3.0.14-stable review
Subsystems (47)
cover 3.0.14-stable review
This is the start of the stable review cycle for the 3.0.14 release. There are 45 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 December 19, 2011, 18:00: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/v3.0/stable-review/patch-3.0.14-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
Makefile | 4 +- arch/arm/mach-at91/at91sam9260.c | 6 +- arch/arm/mach-davinci/board-da850-evm.c | 2 +- arch/arm/mach-davinci/board-dm646x-evm.c | 6 +- arch/arm/mach-mxs/include/mach/mxs.h | 1 + arch/x86/kernel/hpet.c | 21 +++++--- arch/x86/mm/gup.c | 2 + arch/x86/xen/setup.c | 18 ++++++- drivers/firmware/iscsi_ibft.c | 42 +++++++++++++++- drivers/firmware/iscsi_ibft_find.c | 26 +--------- drivers/hwmon/coretemp.c | 2 + drivers/hwmon/jz4740-hwmon.c | 2 +- drivers/md/raid5.c | 2 +- drivers/mmc/host/mxcmmc.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 36 +++++++++----- drivers/net/wireless/iwlwifi/iwl-agn.c | 18 +------ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 + drivers/pci/intel-iommu.c | 40 +++++++++------ drivers/ptp/ptp_clock.c | 4 +- drivers/staging/rtl8712/usb_intf.c | 1 + drivers/target/target_core_transport.c | 9 +++- drivers/usb/class/cdc-acm.c | 10 ++++ drivers/usb/serial/option.c | 7 ++- fs/dcache.c | 71 ++++++++++++++++---------- fs/ext4/inode.c | 9 ++- fs/ext4/page-io.c | 12 +++++ fs/ext4/super.c | 17 +++--- fs/fuse/dev.c | 3 +- fs/hfs/btree.c | 20 ++++++-- fs/jbd/journal.c | 8 +++ fs/jbd2/journal.c | 8 +++ fs/namespace.c | 20 ++++--- fs/proc/meminfo.c | 7 ++- fs/seq_file.c | 6 +- fs/xfs/linux-2.6/xfs_export.c | 8 ++-- fs/xfs/xfs_attr.c | 14 +---- fs/xfs/xfs_bmap.c | 10 +--- fs/xfs/xfs_inode.c | 8 --- include/drm/drm_pciids.h | 10 ++++ include/linux/dcache.h | 3 +- include/linux/fs.h | 1 + include/linux/log2.h | 1 - kernel/taskstats.c | 1 + kernel/time/alarmtimer.c | 2 +- mm/hugetlb.c | 1 + mm/page_alloc.c | 10 +++- mm/percpu-vm.c | 12 ++-- mm/percpu.c | 34 ++++++++----- mm/vmalloc.c | 2 + net/mac80211/agg-tx.c | 17 ++++++- security/apparmor/path.c | 65 ++++++++++++++---------- security/tomoyo/realpath.c | 9 ++- sound/pci/hda/patch_realtek.c | 2 + sound/pci/sis7019.c | 64 ++++++++++++++++++++---- sound/soc/soc-utils.c | 31 +++++++++++- 55 files changed, 492 insertions(+), 256 deletions(-)
PATCH 1/45 ALSA: sis7019 - give slow codecs more time to reset
3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Dillow <[email protected]>
commit fc084e0b930d546872ab23667052499f7daf0fed upstream.
There are some AC97 codec and board combinations that have been observed to take a very long time to respond after the cold reset has completed. In one case, more than 350 ms was required. To allow users to have sound on those platforms, we'll wait up to 500ms for the codec to become ready.
As a board may have multiple codecs, with some faster than others to reset, we add a module parameter to inform the driver which codecs should be present.
--- sound/pci/sis7019.c | 64 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 11 deletions(-)
sound/pci/sis7019.c +53 -11
@@ -41,6 +41,7 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Astatic int index =SNDRV_DEFAULT_IDX1 ;/* Index 0-MAX */ static char *id =SNDRV_DEFAULT_STR1 ;/* ID for this card */ static int enable =1 ; +static int codecs =1 ;module_param (index, int,0444 );MODULE_PARM_DESC (index,"Index value for SiS7019 Audio Accelerator." );
@@ -48,6 +49,8 @@ module_param(id, charp, 0444);MODULE_PARM_DESC (id,"ID string for SiS7019 Audio Accelerator." );module_param (enable, bool,0444 );MODULE_PARM_DESC (enable,"Enable SiS7019 Audio Accelerator." ); +module_param (codecs, int,0444 ); +MODULE_PARM_DESC (codecs,"Set bit to indicate that codec number is expected to be present (default 1)" );static DEFINE_PCI_DEVICE_TABLE (snd_sis7019_ids) = { {PCI_DEVICE (PCI_VENDOR_ID_SI ,0x7019 ) },
@@ -140,6 +143,9 @@ struct sis7019 {dma_addr_t silence_dma_addr; }; +/* These values are also used by the module param 'codecs' to indicate +* which codecs should be present. +*/ #define SIS_PRIMARY_CODEC_PRESENT 0x0001#define SIS_SECONDARY_CODEC_PRESENT 0x0002#define SIS_TERTIARY_CODEC_PRESENT 0x0004
@@ -1078,6 +1084,7 @@ static int sis_chip_init(struct sis7019 {unsigned long io = sis->ioport;void __iomem *ioaddr = sis->ioaddr; +unsigned long timeout;u16 status;int count;int i;
@@ -1104,21 +1111,45 @@ static int sis_chip_init(struct sis7019while ((inw (io +SIS_AC97_STATUS ) &SIS_AC97_STATUS_BUSY ) && --count)udelay (1 ); -/* Now that we've finished the reset, find out what's attached. +/* Command complete, we can let go of the semaphore now. */ - status =inl (io +SIS_AC97_STATUS ); -if (status &SIS_AC97_STATUS_CODEC_READY ) - sis->codecs_present |=SIS_PRIMARY_CODEC_PRESENT ; -if (status &SIS_AC97_STATUS_CODEC2_READY ) - sis->codecs_present |=SIS_SECONDARY_CODEC_PRESENT ; -if (status &SIS_AC97_STATUS_CODEC3_READY ) - sis->codecs_present |=SIS_TERTIARY_CODEC_PRESENT ; +outl (SIS_AC97_SEMA_RELEASE , io +SIS_AC97_SEMA ); +if (!count) +return -EIO ; + +/* Now that we've finished the reset, find out what's attached. +* There are some codec/board combinations that take an extremely +* long time to come up. 350+ ms has been observed in the field, +* so we'll give them up to 500ms. +*/ + sis->codecs_present =0 ; + timeout =msecs_to_jiffies (500 ) + jiffies; +while (time_before_eq (jiffies, timeout)) { + status =inl (io +SIS_AC97_STATUS ); +if (status &SIS_AC97_STATUS_CODEC_READY ) + sis->codecs_present |=SIS_PRIMARY_CODEC_PRESENT ; +if (status &SIS_AC97_STATUS_CODEC2_READY ) + sis->codecs_present |=SIS_SECONDARY_CODEC_PRESENT ; +if (status &SIS_AC97_STATUS_CODEC3_READY ) + sis->codecs_present |=SIS_TERTIARY_CODEC_PRESENT ; + +if (sis->codecs_present == codecs) +break ; -/* All done, let go of the semaphore, and check for errors +msleep (1 ); + } + +/* All done, check for errors. */ -outl (SIS_AC97_SEMA_RELEASE , io +SIS_AC97_SEMA ); -if (!sis->codecs_present || !count) +if (!sis->codecs_present) { +printk (KERN_ERR "sis7019: could not find any codecs\n" );return -EIO ; + } + +if (sis->codecs_present != codecs) { +printk (KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n" , + sis->codecs_present, codecs); + }/* Let the hardware know that the audio driver is alive, * and enable PCM slots on the AC-link for L/R playback (3 & 4) and
@@ -1390,6 +1421,17 @@ static int __devinit snd_sis7019_probe(sif (!enable) goto error_out; +/* The user can specify which codecs should be present so that we +* can wait for them to show up if they are slow to recover from +* the AC97 cold reset. We default to a single codec, the primary. +* +* We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2. +*/ + codecs &=SIS_PRIMARY_CODEC_PRESENT |SIS_SECONDARY_CODEC_PRESENT | +SIS_TERTIARY_CODEC_PRESENT ; +if (!codecs) + codecs =SIS_PRIMARY_CODEC_PRESENT ; + rc =snd_card_create (index, id,THIS_MODULE ,sizeof (*sis), &card);if (rc <0 ) goto error_out;
PATCH 2/45 ALSA: hda/realtek - Fix Oops in alc_mux_select()
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit cce4aa378a049f4275416ee6302dd24f37b289df upstream.
When no imux is available (e.g. a single capture source), alc_auto_init_input_src() may trigger an Oops due to the access to -1. Add a proper zero-check to avoid it.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -509,6 +509,8 @@ static int alc_mux_enum_put(struct snd_k imux = &spec->input_mux[mux_idx];if (!imux->num_items && mux_idx >0 ) imux = &spec->input_mux[0 ]; +if (!imux->num_items) +return 0 ; type =get_wcaps_type (get_wcaps (codec, nid));if (type ==AC_WID_AUD_MIX ) {
PATCH 3/45 alarmtimers: Fix time comparison
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
commit c9c024b3f3e07d087974db4c0dc46217fff3a6c0 upstream.
The expiry function compares the timer against current time and does not expire the timer when the expiry time is >= now. That's wrong. If the timer is set for now, then it must expire.
Make the condition expiry > now for breaking out the loop.
--- kernel/time/alarmtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/time/alarmtimer.c +1 -1
@@ -181,7 +181,7 @@ static enum hrtimer_restart alarmtimer_fstruct alarm *alarm;ktime_t expired = next->expires; -if (expired.tv64 >= now.tv64) +if (expired.tv64 > now.tv64)break ; alarm = container_of(next, struct alarm, node);
PATCH 4/45 ARM: davinci: da850 evm: change audio edma event queue to EVENTQ_0
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Manjunathappa, Prakash" <[email protected]>
commit f1b21c525693b0159aed83b5871f2d0f077f208e upstream.
On OMAP-L138 platform, EDMA event queue 0 should be used for audio transfers so that they are not starved by video data moving on event queue 1.
Commit 48519f0ae03bc7e86b3dc93e56f1334d53803770 (ASoC: davinci: let platform data define edma queue numbers) had a side-effect of changing this behavior by making the driver actually honor the platform data passed.
Fix this now by passing event queue 0 as the queue to be used for audio transfers.
--- arch/arm/mach-davinci/board-da850-evm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-davinci/board-da850-evm.c +1 -1
@@ -748,7 +748,7 @@ static struct snd_platform_data da850_ev .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), .tdm_slots = 2, .serial_dir = da850_iis_serializer_direction, - .asp_chan_q = EVENTQ_1, + .asp_chan_q = EVENTQ_0, .version = MCASP_VERSION_2, .txnumevt = 1, .rxnumevt = 1,
PATCH 5/45 arm: mx23: recognise stmp378x as mx23
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang <[email protected]>
commit 11357be9246c7d1acf9b37ad54a18b29bbb734be upstream.
Adding the machine_is_* line was forgotten when converting mach-stmp378x to mach-mxs.
--- arch/arm/mach-mxs/include/mach/mxs.h | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-mxs/include/mach/mxs.h +1 -0
@@ -30,6 +30,7 @@*/ #define cpu_is_mx23 () ( \ machine_is_mx23evk() || \ + machine_is_stmp378x() || \ 0)#define cpu_is_mx28 () ( \ machine_is_mx28evk() || \
PATCH 6/45 ARM: at91: fix clock conid for atmel_tcb.1 on 9260/9g20
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean-Christophe PLAGNIOL-VILLARD <[email protected]>
commit 1808958d27b1250295f01dff4997d8a8814adaab upstream.
The conid is supposed to be t0/t1/t2_clk.
--- arch/arm/mach-at91/at91sam9260.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/mach-at91/at91sam9260.c +3 -3
@@ -237,9 +237,9 @@ static struct clk_lookup periph_clocks_lCLKDEV_CON_DEV_ID ("t0_clk" ,"atmel_tcb.0" , &tc0_clk),CLKDEV_CON_DEV_ID ("t1_clk" ,"atmel_tcb.0" , &tc1_clk),CLKDEV_CON_DEV_ID ("t2_clk" ,"atmel_tcb.0" , &tc2_clk), -CLKDEV_CON_DEV_ID ("t3_clk" ,"atmel_tcb.1" , &tc3_clk), -CLKDEV_CON_DEV_ID ("t4_clk" ,"atmel_tcb.1" , &tc4_clk), -CLKDEV_CON_DEV_ID ("t5_clk" ,"atmel_tcb.1" , &tc5_clk), +CLKDEV_CON_DEV_ID ("t0_clk" ,"atmel_tcb.1" , &tc3_clk), +CLKDEV_CON_DEV_ID ("t1_clk" ,"atmel_tcb.1" , &tc4_clk), +CLKDEV_CON_DEV_ID ("t2_clk" ,"atmel_tcb.1" , &tc5_clk), CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), };
PATCH 7/45 ARM: davinci: dm646x evm: wrong register used in setup_vpif_input_channel_mode
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
commit 83713fc9373be2e943f82e9d36213708c6b0050e upstream.
The function setup_vpif_input_channel_mode() used the VSCLKDIS register instead of VIDCLKCTL. This meant that when in HD mode videoport channel 0 used a different clock from channel 1.
Clearly a copy-and-paste error.
--- arch/arm/mach-davinci/board-dm646x-evm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/mach-davinci/board-dm646x-evm.c +3 -3
@@ -563,7 +563,7 @@ static int setup_vpif_input_channel_modeint val;u32 value; -if (!vpif_vsclkdis_reg || !cpld_client) +if (!vpif_vidclkctl_reg || !cpld_client)return -ENXIO ; val =i2c_smbus_read_byte (cpld_client);
@@ -571,7 +571,7 @@ static int setup_vpif_input_channel_modereturn val;spin_lock_irqsave (&vpif_reg_lock, flags); - value =__raw_readl (vpif_vsclkdis_reg); + value =__raw_readl (vpif_vidclkctl_reg);if (mux_mode) { val &=VPIF_INPUT_TWO_CHANNEL ; value |=VIDCH1CLK ;
@@ -579,7 +579,7 @@ static int setup_vpif_input_channel_mode val |=VPIF_INPUT_ONE_CHANNEL ; value &= ~VIDCH1CLK ; } -__raw_writel (value, vpif_vsclkdis_reg); +__raw_writel (value, vpif_vidclkctl_reg);spin_unlock_irqrestore (&vpif_reg_lock, flags); err =i2c_smbus_write_byte (cpld_client, val);
PATCH 8/45 ASoC: Provide a more complete DMA driver stub
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Brown <[email protected]>
commit cefcc03ffc9527dde56807339edb1719c8dbae5f upstream.
Allow userspace applications to do more parameter setting by providing a more complete stub DMA driver specifying a wildcard set of formats and channels and essentially random values for the DMA parameters. This is required for useful runtime operation of the dummy DMA driver until we are able to figure out how to power up links and do hw_params() from DAPM.
Sending to stable as without this the dummy driver is not terribly useful.
--- sound/soc/soc-utils.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
sound/soc/soc-utils.c +30 -1
@@ -57,7 +57,36 @@ int snd_soc_params_to_bclk(struct snd_pc }EXPORT_SYMBOL_GPL (snd_soc_params_to_bclk); -static struct snd_soc_platform_driver dummy_platform; +static const struct snd_pcm_hardware dummy_dma_hardware = { + .formats =0xffffffff , + .channels_min =1 , + .channels_max =UINT_MAX , + +/* Random values to keep userspace happy when checking constraints */ + .info =SNDRV_PCM_INFO_INTERLEAVED | +SNDRV_PCM_INFO_BLOCK_TRANSFER , + .buffer_bytes_max =128 *1024 , + .period_bytes_min =PAGE_SIZE , + .period_bytes_max =PAGE_SIZE *2 , + .periods_min =2 , + .periods_max =128 , +}; + +static int dummy_dma_open (struct snd_pcm_substream *substream) +{ +snd_soc_set_runtime_hwparams (substream, &dummy_dma_hardware); + +return 0 ; +} + +static struct snd_pcm_ops dummy_dma_ops = { + .open = dummy_dma_open, + .ioctl = snd_pcm_lib_ioctl, +}; + +static struct snd_soc_platform_driver dummy_platform = { + .ops = &dummy_dma_ops, +};static __devinit int snd_soc_dummy_probe (struct platform_device *pdev) {
PATCH 9/45 fs/proc/meminfo.c: fix compilation error
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudio Scordino <[email protected]>
commit b53fc7c2974a50913f49e1d800fe904a28c338e3 upstream.
Fix the error message "directives may not be used inside a macro argument" which appears when the kernel is compiled for the cris architecture.
--- fs/proc/meminfo.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/proc/meminfo.c +4 -3
@@ -131,12 +131,13 @@ static int meminfo_proc_show(struct seq_K (i.freeswap),K (global_page_state (NR_FILE_DIRTY )),K (global_page_state (NR_WRITEBACK )), -K (global_page_state (NR_ANON_PAGES ) #ifdef CONFIG_TRANSPARENT_HUGEPAGE +K (global_page_state (NR_ANON_PAGES ) +global_page_state (NR_ANON_TRANSPARENT_HUGEPAGES ) * -HPAGE_PMD_NR +HPAGE_PMD_NR ), +#else +K (global_page_state (NR_ANON_PAGES )), #endif - ),K (global_page_state (NR_FILE_MAPPED )),K (global_page_state (NR_SHMEM )), K(global_page_state(NR_SLAB_RECLAIMABLE) +
PATCH 10/45 thp: add compound tail page _mapcount when mapped
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youquan Song <[email protected]>
commit b6999b19120931ede364fa3b685e698a61fed31d upstream.
With the 3.2-rc kernel, IOMMU 2M pages in KVM works. But when I tried to use IOMMU 1GB pages in KVM, I encountered an oops and the 1GB page failed to be used.
The root cause is that 1GB page allocation calls gup_huge_pud() while 2M page calls gup_huge_pmd. If compound pages are used and the page is a tail page, gup_huge_pmd() increases _mapcount to record tail page are mapped while gup_huge_pud does not do that.
So when the mapped page is relesed, it will result in kernel oops because the page is not marked mapped.
This patch add tail process for compound page in 1GB huge page which keeps the same process as 2M page.
Reproduce like:
1. Add grub boot option: hugepagesz=1G hugepages=8
2. mount -t hugetlbfs -o pagesize=1G hugetlbfs /dev/hugepages
3. qemu-kvm -m 2048 -hda os-kvm.img -cpu kvm64 -smp 4 -mem-path /dev/hugepages
-net none -device pci-assign,host=07:00.1
kernel BUG at mm/swap.c:114!
invalid opcode: 0000 [#1] SMP
Call Trace:
put_page+0x15/0x37
kvm_release_pfn_clean+0x31/0x36
kvm_iommu_put_pages+0x94/0xb1
kvm_iommu_unmap_memslots+0x80/0xb6
kvm_assign_device+0xba/0x117
kvm_vm_ioctl_assigned_device+0x301/0xa47
kvm_vm_ioctl+0x36c/0x3a2
do_vfs_ioctl+0x49e/0x4e4
sys_ioctl+0x5a/0x7c
system_call_fastpath+0x16/0x1b
RIP put_compound_page+0xd4/0x168--- arch/x86/mm/gup.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/mm/gup.c +2 -0
@@ -201,6 +201,8 @@ static noinline int gup_huge_pud(pud_t p do { VM_BUG_ON(compound_head(page) != head); pages[*nr] = page; + if (PageTail(page)) + get_huge_page_tail(page); (*nr)++; page++; refs++;
PATCH 11/45 thp: set compound tail page _count to zero
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youquan Song <[email protected]>
commit 58a84aa92723d1ac3e1cc4e3b0ff49291663f7e1 upstream.
Commit 70b50f94f1644 ("mm: thp: tail page refcounting fix") keeps all page_tail->_count zero at all times. But the current kernel does not set page_tail->_count to zero if a 1GB page is utilized. So when an IOMMU 1GB page is used by KVM, it wil result in a kernel oops because a tail page's _count does not equal zero.
kernel BUG at include/linux/mm.h:386!
invalid opcode: 0000 [#1] SMP
Call Trace:
gup_pud_range+0xb8/0x19d
get_user_pages_fast+0xcb/0x192
? trace_hardirqs_off+0xd/0xf
hva_to_pfn+0x119/0x2f2
gfn_to_pfn_memslot+0x2c/0x2e
kvm_iommu_map_pages+0xfd/0x1c1
kvm_iommu_map_memslots+0x7c/0xbd
kvm_iommu_map_guest+0xaa/0xbf
kvm_vm_ioctl_assigned_device+0x2ef/0xa47
kvm_vm_ioctl+0x36c/0x3a2
do_vfs_ioctl+0x49e/0x4e4
sys_ioctl+0x5a/0x7c
system_call_fastpath+0x16/0x1b
RIP gup_huge_pud+0xf2/0x159--- mm/hugetlb.c | 1 + mm/page_alloc.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
mm/hugetlb.c +1 -0
@@ -575,6 +575,7 @@ static void prep_compound_gigantic_page(__SetPageHead (page);for (i =1 ; i < nr_pages; i++, p =mem_map_next (p, page, i)) {__SetPageTail (p); +set_page_count (p,0 ); p->first_page = page; } }
mm/page_alloc.c +1 -1
@@ -355,8 +355,8 @@ void prep_compound_page(struct page *pag__SetPageHead (page);for (i =1 ; i < nr_pages; i++) {struct page *p = page + i; -__SetPageTail (p); +set_page_count (p,0 ); p->first_page = page; } }
PATCH 12/45 ptp: Fix clock_getres() implementation
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
commit d68fb11c3dae75c8331538dcf083a65e697cc034 upstream.
The clock_getres() function must return the resolution in the timespec argument and return 0 for success.
--- drivers/ptp/ptp_clock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/ptp/ptp_clock.c +3 -1
@@ -101,7 +101,9 @@ static s32 scaled_ppm_to_ppb(long ppm)static int ptp_clock_getres (struct posix_clock *pc,struct timespec *tp) { -return 1 ;/* always round timer functions to one nanosecond */ + tp->tv_sec =0 ; + tp->tv_nsec =1 ; +return 0 ; }static int ptp_clock_settime (struct posix_clock *pc,const struct timespec *tp)
PATCH 13/45 mm: Ensure that pfn_valid() is called once per pageblock when reserving pageblocks
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Hocko <[email protected]>
commit d021563888312018ca65681096f62e36c20e63cc upstream.
setup_zone_migrate_reserve() expects that zone->start_pfn starts at pageblock_nr_pages aligned pfn otherwise we could access beyond an existing memblock resulting in the following panic if CONFIG_HOLES_IN_ZONE is not configured and we do not check pfn_valid:
IP: [<c02d331d>] setup_zone_migrate_reserve+0xcd/0x180 *pdpt = 0000000000000000 *pde = f000ff53f000ff53
Oops: 0000 [#1] SMP Pid: 1, comm: swapper Not tainted 3.0.7-0.7-pae #1 VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform EIP: 0060:[<c02d331d>] EFLAGS: 00010006 CPU: 0 EIP is at setup_zone_migrate_reserve+0xcd/0x180 EAX: 000c0000 EBX: f5801fc0 ECX: 000c0000 EDX: 00000000 ESI: 000c01fe EDI: 000c01fe EBP: 00140000 ESP: f2475f58 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 Process swapper (pid: 1, ti=f2474000 task=f2472cd0 task.ti=f2474000) Call Trace: [<c02d389c>] __setup_per_zone_wmarks+0xec/0x160 [<c02d3a1f>] setup_per_zone_wmarks+0xf/0x20 [<c08a771c>] init_per_zone_wmark_min+0x27/0x86 [<c020111b>] do_one_initcall+0x2b/0x160 [<c086639d>] kernel_init+0xbe/0x157 [<c05cae26>] kernel_thread_helper+0x6/0xd Code: a5 39 f5 89 f7 0f 46 fd 39 cf 76 40 8b 03 f6 c4 08 74 32 eb 91 90 89 c8 c1 e8 0e 0f be 80 80 2f 86 c0 8b 14 85 60 2f 86 c0 89 c8 <2b> 82 b4 12 00 00 c1 e0 05 03 82 ac 12 00 00 8b 00 f6 c4 08 0f EIP: [<c02d331d>] setup_zone_migrate_reserve+0xcd/0x180 SS:ESP 0068:f2475f58 CR2: 00000000000012b4
We crashed in pageblock_is_reserved() when accessing pfn 0xc0000 because highstart_pfn = 0x36ffe.
The issue was introduced in 3.0-rc1 by 6d3163ce ("mm: check if any page in a pageblock is reserved before marking it MIGRATE_RESERVE").
Make sure that start_pfn is always aligned to pageblock_nr_pages to ensure that pfn_valid s always called at the start of each pageblock. Architectures with holes in pageblocks will be correctly handled by pfn_valid_within in pageblock_is_reserved.
--- mm/page_alloc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
mm/page_alloc.c +7 -1
@@ -3388,9 +3388,15 @@ static void setup_zone_migrate_reserve(sunsigned long block_migratetype;int reserve; -/* Get the start pfn, end pfn and the number of blocks to reserve */ +/* +* Get the start pfn, end pfn and the number of blocks to reserve +* We have to be careful to be aligned to pageblock_nr_pages to +* make sure that we always check pfn_valid for the first page in +* the block. +*/ start_pfn = zone->zone_start_pfn; end_pfn = start_pfn + zone->spanned_pages; + start_pfn =roundup (start_pfn, pageblock_nr_pages); reserve =roundup (min_wmark_pages (zone), pageblock_nr_pages) >> pageblock_order;
PATCH 14/45 mm: vmalloc: check for page allocation failure before vmlist insertion
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mel Gorman <[email protected]>
commit 1368edf0647ac112d8cfa6ce47257dc950c50f5c upstream.
Commit f5252e00 ("mm: avoid null pointer access in vm_struct via /proc/vmallocinfo") adds newly allocated vm_structs to the vmlist after it is fully initialised. Unfortunately, it did not check that __vmalloc_area_node() successfully populated the area. In the event of allocation failure, the vmalloc area is freed but the pointer to freed memory is inserted into the vmlist leading to a a crash later in get_vmalloc_info().
This patch adds a check for ____vmalloc_area_node() failure within __vmalloc_node_range. It does not use "goto fail" as in the previous error path as a warning was already displayed by __vmalloc_area_node() before it called vfree in its failure path.
Credit goes to Luciano Chavez for doing all the real work of identifying exactly where the problem was.
--- mm/vmalloc.c | 2 ++ 1 file changed, 2 insertions(+)
mm/vmalloc.c +2 -0
@@ -1648,6 +1648,8 @@ void *__vmalloc_node_range(unsigned longreturn NULL ; addr =__vmalloc_area_node (area, gfp_mask, prot, node, caller); +if (!addr) +return NULL ;/* * In this function, newly allocated vm_struct is not added
PATCH 15/45 fix apparmor dereferencing potentially freed dentry, sanitize __d_path() API
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 02125a826459a6ad142f8d91c5b6357562f96615 upstream.
__d_path() API is asking for trouble and in case of apparmor d_namespace_path() getting just that. The root cause is that when __d_path() misses the root it had been told to look for, it stores the location of the most remote ancestor in *root. Without grabbing references. Sure, at the moment of call it had been pinned down by what we have in *path. And if we raced with umount -l, we could have very well stopped at vfsmount/dentry that got freed as soon as prepend_path() dropped vfsmount_lock.
It is safe to compare these pointers with pre-existing (and known to be still alive) vfsmount and dentry, as long as all we are asking is "is it the same address?". Dereferencing is not safe and apparmor ended up stepping into that. d_namespace_path() really wants to examine the place where we stopped, even if it's not connected to our namespace. As the result, it looked at ->d_sb->s_magic of a dentry that might've been already freed by that point. All other callers had been careful enough to avoid that, but it's really a bad interface - it invites that kind of trouble.
The fix is fairly straightforward, even though it's bigger than I'd like:
* prepend_path() root argument becomes const.
* __d_path() is never called with NULL/NULL root. It was a kludge
to start with. Instead, we have an explicit function - d_absolute_root(). Same as __d_path(), except that it doesn't get root passed and stops where it stops. apparmor and tomoyo are using it.
* __d_path() returns NULL on path outside of root. The main
caller is show_mountinfo() and that's precisely what we pass root for - to skip those outside chroot jail. Those who don't want that can (and do) use d_path().
* __d_path() root argument becomes const. Everyone agrees, I hope.
* apparmor does *NOT* try to use __d_path() or any of its variants
when it sees that path->mnt is an internal vfsmount. In that case it's definitely not mounted anywhere and dentry_path() is exactly what we want there. Handling of sysctl()-triggered weirdness is moved to that place.
* if apparmor is asked to do pathname relative to chroot jail
and __d_path() tells it we it's not in that jail, the sucker just calls d_absolute_path() instead. That's the other remaining caller of __d_path(), BTW.
* seq_path_root() does _NOT_ return -ENAMETOOLONG (it's stupid anyway -
the normal seq_file logics will take care of growing the buffer and redoing the call of ->show() just fine). However, if it gets path not reachable from root, it returns SEQ_SKIP. The only caller adjusted (i.e. stopped ignoring the return value as it used to do).
--- fs/dcache.c | 71 +++++++++++++++++++++++++++------------------ fs/namespace.c | 20 ++++++------ fs/seq_file.c | 6 +-- include/linux/dcache.h | 3 + include/linux/fs.h | 1 security/apparmor/path.c | 65 ++++++++++++++++++++++++----------------- security/tomoyo/realpath.c | 9 +++-- 7 files changed, 105 insertions(+), 70 deletions(-)
fs/dcache.c +44 -27
@@ -2487,16 +2487,14 @@ static int prepend_name(char **buffer, i/** * prepend_path - Prepend path string to a buffer * @path: the dentry/vfsmount to report -* @root: root vfsmnt/dentry (may be modified by this function) +* @root: root vfsmnt/dentry * @buffer: pointer to the end of the buffer * @buflen: pointer to buffer length * * Caller holds the rename_lock. -* -* If path is not reachable from the supplied root, then the value of -* root is changed (without modifying refcounts). */ -static int prepend_path (const struct path *path,struct path *root, +static int prepend_path (const struct path *path, +const struct path *root,char **buffer,int *buflen) {struct dentry *dentry = path->dentry;
@@ -2531,10 +2529,10 @@ static int prepend_path(const struct pat dentry = parent; } -out:if (!error && !slash) error =prepend (buffer, buflen,"/" ,1 ); +out:br_read_unlock (vfsmount_lock);return error;
@@ -2548,15 +2546,17 @@ global_root:WARN (1 ,"Root dentry has weird name <%.*s>\n" , (int ) dentry->d_name.len, dentry->d_name.name); } - root->mnt = vfsmnt; - root->dentry = dentry; +if (!slash) + error =prepend (buffer, buflen,"/" ,1 ); +if (!error) + error = vfsmnt->mnt_ns ?1 :2 ; goto out; }/** * __d_path - return the path of a dentry * @path: the dentry/vfsmount to report -* @root: root vfsmnt/dentry (may be modified by this function) +* @root: root vfsmnt/dentry * @buf: buffer to return value in * @buflen: buffer length *
@@ -2567,10 +2567,10 @@ global_root:* * "buflen" should be positive. * -* If path is not reachable from the supplied root, then the value of -* root is changed (without modifying refcounts). +* If the path is not reachable from the supplied root, return %NULL. */ -char *__d_path (const struct path *path,struct path *root, +char *__d_path (const struct path *path, +const struct path *root,char *buf,int buflen) {char *res = buf + buflen;
@@ -2581,7 +2581,28 @@ char *__d_path(const struct path *path, error =prepend_path (path, root, &res, &buflen);write_sequnlock (&rename_lock); -if (error) +if (error <0 ) +return ERR_PTR (error); +if (error >0 ) +return NULL ; +return res; +} + +char *d_absolute_path (const struct path *path, +char *buf,int buflen) +{ +struct path root = {}; +char *res = buf + buflen; +int error; + +prepend (&res, &buflen,"\0" ,1 ); +write_seqlock (&rename_lock); + error =prepend_path (path, &root, &res, &buflen); +write_sequnlock (&rename_lock); + +if (error >1 ) + error = -EINVAL ; +if (error <0 )return ERR_PTR (error);return res; }
@@ -2589,8 +2610,9 @@ char *__d_path(const struct path *path,/* * same as __d_path but appends "(deleted)" for unlinked files. */ -static int path_with_deleted (const struct path *path,struct path *root, -char **buf,int *buflen) +static int path_with_deleted (const struct path *path, +const struct path *root, +char **buf,int *buflen) {prepend (buf, buflen,"\0" ,1 );if (d_unlinked (path->dentry)) {
@@ -2627,7 +2649,6 @@ char *d_path(const struct path *path, ch {char *res = buf + buflen;struct path root; -struct path tmp;int error;/*
@@ -2642,9 +2663,8 @@ char *d_path(const struct path *path, chget_fs_root (current->fs, &root);write_seqlock (&rename_lock); - tmp = root; - error =path_with_deleted (path, &tmp, &res, &buflen); -if (error) + error =path_with_deleted (path, &root, &res, &buflen); +if (error <0 ) res =ERR_PTR (error);write_sequnlock (&rename_lock);path_put (&root);
@@ -2665,7 +2685,6 @@ char *d_path_with_unreachable(const stru {char *res = buf + buflen;struct path root; -struct path tmp;int error;if (path->dentry->d_op && path->dentry->d_op->d_dname)
@@ -2673,9 +2692,8 @@ char *d_path_with_unreachable(const struget_fs_root (current->fs, &root);write_seqlock (&rename_lock); - tmp = root; - error =path_with_deleted (path, &tmp, &res, &buflen); -if (!error && !path_equal (&tmp, &root)) + error =path_with_deleted (path, &root, &res, &buflen); +if (error >0 ) error =prepend_unreachable (&res, &buflen);write_sequnlock (&rename_lock);path_put (&root);
@@ -2806,19 +2824,18 @@ SYSCALL_DEFINE2(getcwd, char __user *, bwrite_seqlock (&rename_lock);if (!d_unlinked (pwd.dentry)) {unsigned long len; -struct path tmp = root;char *cwd = page +PAGE_SIZE ;int buflen =PAGE_SIZE ;prepend (&cwd, &buflen,"\0" ,1 ); - error =prepend_path (&pwd, &tmp, &cwd, &buflen); + error =prepend_path (&pwd, &root, &cwd, &buflen);write_sequnlock (&rename_lock); -if (error) +if (error <0 ) goto out;/* Unreachable from current root */ -if (!path_equal (&tmp, &root)) { +if (error >0 ) { error =prepend_unreachable (&cwd, &buflen);if (error) goto out;
fs/namespace.c +11 -9
@@ -1048,15 +1048,12 @@ static int show_mountinfo(struct seq_filif (err) goto out;seq_putc (m,' ' ); -seq_path_root (m, &mnt_path, &root," \t\n\\" ); -if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { -/* -* Mountpoint is outside root, discard that one. Ugly, -* but less so than trying to do that in iterator in a -* race-free way (due to renames). -*/ -return SEQ_SKIP ; - } + +/* mountpoints outside of chroot jail will give SEQ_SKIP on this */ + err =seq_path_root (m, &mnt_path, &root," \t\n\\" ); +if (err) + goto out; +seq_puts (m, mnt->mnt_flags &MNT_READONLY ?" ro" :" rw" );show_mnt_opts (m, mnt);
@@ -2725,3 +2722,8 @@ struct vfsmount *kern_mount_data(structreturn vfs_kern_mount (type,MS_KERNMOUNT , type->name, data); }EXPORT_SYMBOL_GPL (kern_mount_data); + +bool our_mnt (struct vfsmount *mnt) +{ +return check_mnt (mnt); +}
fs/seq_file.c +3 -3
@@ -449,8 +449,6 @@ EXPORT_SYMBOL(seq_path);/* * Same as seq_path, but relative to supplied root. -* -* root may be changed, see __d_path(). */ int seq_path_root (struct seq_file *m,struct path *path,struct path *root,char *esc)
@@ -463,6 +461,8 @@ int seq_path_root(struct seq_file *m, stchar *p; p =__d_path (path, root, buf, size); +if (!p) +return SEQ_SKIP ; res =PTR_ERR (p);if (!IS_ERR (p)) {char *end =mangle_path (buf, p, esc);
@@ -474,7 +474,7 @@ int seq_path_root(struct seq_file *m, st }seq_commit (m, res); -return res <0 ? res :0 ; +return res <0 && res != -ENAMETOOLONG ? res :0 ; }/*
include/linux/dcache.h +2 -1
@@ -340,7 +340,8 @@ extern int d_validate(struct dentry *, s*/ extern char *dynamic_dname (struct dentry *,char *,int ,const char *, ...); -extern char *__d_path (const struct path *path,struct path *root,char *,int ); +extern char *__d_path (const struct path *,const struct path *,char *,int ); +extern char *d_absolute_path (const struct path *,char *,int );extern char *d_path (const struct path *,char *,int );extern char *d_path_with_unreachable (const struct path *,char *,int );extern char *dentry_path_raw (struct dentry *,char *,int );
include/linux/fs.h +1 -0
@@ -1882,6 +1882,7 @@ extern int fd_statfs(int, struct kstatfsextern int statfs_by_dentry (struct dentry *,struct kstatfs *);extern int freeze_super (struct super_block *super);extern int thaw_super (struct super_block *super); +extern bool our_mnt (struct vfsmount *mnt);extern int current_umask (void );
security/apparmor/path.c +38 -27
103 lines not on this page · raw message
security/tomoyo/realpath.c +6 -3
@@ -95,7 +95,6 @@ char *tomoyo_realpath_from_path(struct preturn NULL ; is_dir = dentry->d_inode &&S_ISDIR (dentry->d_inode->i_mode);while (1 ) { -struct path ns_root = { .mnt =NULL , .dentry =NULL };char *pos; buf_len <<=1 ;kfree (buf);
@@ -128,8 +127,12 @@ char *tomoyo_realpath_from_path(struct p/* If we don't have a vfsmount, we can't calculate. */ if (!path->mnt)break ; -/* go to whatever namespace root we are under */ - pos =__d_path (path, &ns_root, buf, buf_len); + pos =d_absolute_path (path, buf, buf_len -1 ); +/* If path is disconnected, use "[unknown]" instead. */ +if (pos ==ERR_PTR (-EINVAL )) { + name =tomoyo_encode ("[unknown]" ); +break ; + }/* Prepend "/proc" prefix if using internal proc vfs mount. */ if (!IS_ERR (pos) && (path->mnt->mnt_flags &MNT_INTERNAL ) && (path->mnt->mnt_sb->s_magic ==PROC_SUPER_MAGIC )) {
PATCH 16/45 target: Handle 0 correctly in transport_get_sectors_6()
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roland Dreier <[email protected]>
commit 9b5cd7f37e1e018432111333e2a67f78ba41edfe upstream.
SBC-3 says:
A TRANSFER LENGTH field set to zero specifies that 256 logical blocks shall be written. Any other value specifies the number of logical blocks that shall be written.
The old code was always just returning the value in the TRANSFER LENGTH byte. Fix this to return 256 if the byte is 0.
--- drivers/target/target_core_transport.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/target/target_core_transport.c +7 -2
@@ -2777,10 +2777,15 @@ static inline u32 transport_get_sectors_/* * Everything else assume TYPE_DISK Sector CDB location. -* Use 8-bit sector value. +* Use 8-bit sector value. SBC-3 says: +* +* A TRANSFER LENGTH field set to zero specifies that 256 +* logical blocks shall be written. Any other value +* specifies the number of logical blocks that shall be +* written. */ type_disk: -return (u32 )cdb[4 ]; +return cdb[4 ] ? :256 ; } static inline u32 transport_get_sectors_10(
PATCH 17/45 intel-iommu: fix return value of iommu_unmap() API
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allen Kay <[email protected]>
commit 292827cb164ad00cc7689a21283b1261c0b6daed upstream.
iommu_unmap() API expects IOMMU drivers to return the actual page order of the address being unmapped. Previous code was just returning page order passed in from the caller. This patch fixes this problem.
--- drivers/pci/intel-iommu.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/pci/intel-iommu.c +8 -3
@@ -817,13 +817,14 @@ static struct dma_pte *dma_pfn_level_pte }/* clear last level pte, a tlb flush should be followed */ -static void dma_pte_clear_range (struct dmar_domain *domain, +static int dma_pte_clear_range (struct dmar_domain *domain,unsigned long start_pfn,unsigned long last_pfn) {int addr_width =agaw_to_width (domain->agaw) -VTD_PAGE_SHIFT ;unsigned int large_page =1 ;struct dma_pte *first_pte, *pte; +int order;BUG_ON (addr_width <BITS_PER_LONG && start_pfn >> addr_width);BUG_ON (addr_width <BITS_PER_LONG && last_pfn >> addr_width);
@@ -847,6 +848,9 @@ static void dma_pte_clear_range(struct d (void *)pte - (void *)first_pte); }while (start_pfn && start_pfn <= last_pfn); + + order = (large_page -1 ) *9 ; +return order; }/* free page table pages. last level pte should already be cleared */
@@ -3865,14 +3869,15 @@ static int intel_iommu_unmap(struct iomm {struct dmar_domain *dmar_domain = domain->priv;size_t size =PAGE_SIZE << gfp_order; +int order; -dma_pte_clear_range (dmar_domain, iova >>VTD_PAGE_SHIFT , + order =dma_pte_clear_range (dmar_domain, iova >>VTD_PAGE_SHIFT , (iova + size -1 ) >>VTD_PAGE_SHIFT );if (dmar_domain->max_addr == iova + size) dmar_domain->max_addr = iova; -return gfp_order; +return order; } static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
PATCH 18/45 intel-iommu: set iommu_superpage on VM domains to lowest common denominator
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allen Kay <[email protected]>
commit 8140a95d228efbcd64d84150e794761a32463947 upstream.
set dmar->iommu_superpage field to the smallest common denominator of super page sizes supported by all active VT-d engines. Initialize this field in intel_iommu_domain_init() API so intel_iommu_map() API will be able to use iommu_superpage field to determine the appropriate super page size to use.
--- drivers/pci/intel-iommu.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/pci/intel-iommu.c +7 -5
@@ -578,17 +578,18 @@ static void domain_update_iommu_snoopingstatic void domain_update_iommu_superpage (struct dmar_domain *domain) { -int i, mask =0xf ; +struct dmar_drhd_unit *drhd; +struct intel_iommu *iommu =NULL ; +int mask =0xf ;if (!intel_iommu_superpage) { domain->iommu_superpage =0 ;return ; } - domain->iommu_superpage =4 ;/* 1TiB */ - -for_each_set_bit (i, &domain->iommu_bmp, g_num_of_iommus) { - mask |=cap_super_page_val (g_iommus[i]->cap); +/* set iommu_superpage to the smallest common denominator */ +for_each_active_iommu (iommu, drhd) { + mask &=cap_super_page_val (iommu->cap);if (!mask) {break ; }
@@ -3744,6 +3745,7 @@ static int intel_iommu_domain_init(strucvm_domain_exit (dmar_domain);return -ENOMEM ; } +domain_update_iommu_cap (dmar_domain); domain->priv = dmar_domain;return 0 ;
PATCH 19/45 intel-iommu: fix superpage support in pfn_to_dma_pte()
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allen Kay <[email protected]>
commit 4399c8bf2b9093696fa8160d79712e7346989c46 upstream.
If target_level == 0, current code breaks out of the while-loop if SUPERPAGE bit is set. We should also break out if PTE is not present. If we don't do this, KVM calls to iommu_iova_to_phys() will cause pfn_to_dma_pte() to create mapping for 4KiB pages.
--- drivers/pci/intel-iommu.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/pci/intel-iommu.c +8 -9
@@ -307,6 +307,11 @@ static inline bool dma_pte_present(strucreturn (pte->val &3 ) !=0 ; } +static inline bool dma_pte_superpage (struct dma_pte *pte) +{ +return (pte->val & (1 <<7 )); +} +static inline int first_pte_in_page (struct dma_pte *pte) {return !((unsigned long )pte & ~VTD_PAGE_MASK );
@@ -732,29 +737,23 @@ out: }static struct dma_pte *pfn_to_dma_pte (struct dmar_domain *domain, -unsigned long pfn,int large_level) +unsigned long pfn,int target_level) {int addr_width =agaw_to_width (domain->agaw) -VTD_PAGE_SHIFT ;struct dma_pte *parent, *pte =NULL ;int level =agaw_to_level (domain->agaw); -int offset, target_level; +int offset;BUG_ON (!domain->pgd);BUG_ON (addr_width <BITS_PER_LONG && pfn >> addr_width); parent = domain->pgd; -/* Search pte */ -if (!large_level) - target_level =1 ; -else - target_level = large_level; -while (level >0 ) {void *tmp_page; offset =pfn_level_offset (pfn, level); pte = &parent[offset]; -if (!large_level && (pte->val &DMA_PTE_LARGE_PAGE )) +if (!target_level && (dma_pte_superpage (pte) || !dma_pte_present (pte)))break ;if (level == target_level)break ;
PATCH 20/45 percpu: fix chunk range calculation
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
commit a855b84c3d8c73220d4d3cd392a7bee7c83de70e upstream.
Percpu allocator recorded the cpus which map to the first and last units in pcpu_first/last_unit_cpu respectively and used them to determine the address range of a chunk - e.g. it assumed that the first unit has the lowest address in a chunk while the last unit has the highest address.
This simply isn't true. Groups in a chunk can have arbitrary positive or negative offsets from the previous one and there is no guarantee that the first unit occupies the lowest offset while the last one the highest.
Fix it by actually comparing unit offsets to determine cpus occupying the lowest and highest offsets. Also, rename pcu_first/last_unit_cpu to pcpu_low/high_unit_cpu to avoid confusion.
The chunk address range is used to flush cache on vmalloc area map/unmap and decide whether a given address is in the first chunk by per_cpu_ptr_to_phys() and the bug was discovered by invalid per_cpu_ptr_to_phys() translation for crash_note.
Kudos to Dave Young for tracking down the problem.
LKML-Reference: <[email protected]>
--- mm/percpu-vm.c | 12 ++++++------ mm/percpu.c | 34 ++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 20 deletions(-)
mm/percpu-vm.c +6 -6
@@ -143,8 +143,8 @@ static void pcpu_pre_unmap_flush(struct int page_start, int page_end) {flush_cache_vunmap ( -pcpu_chunk_addr (chunk ,pcpu_first_unit_cpu ,page_start ), -pcpu_chunk_addr (chunk ,pcpu_last_unit_cpu ,page_end )); +pcpu_chunk_addr (chunk ,pcpu_low_unit_cpu ,page_start ), +pcpu_chunk_addr (chunk ,pcpu_high_unit_cpu ,page_end )); }static void __pcpu_unmap_pages (unsigned long addr,int nr_pages)
@@ -206,8 +206,8 @@ static void pcpu_post_unmap_tlb_flush(st int page_start, int page_end) {flush_tlb_kernel_range ( -pcpu_chunk_addr (chunk ,pcpu_first_unit_cpu ,page_start ), -pcpu_chunk_addr (chunk ,pcpu_last_unit_cpu ,page_end )); +pcpu_chunk_addr (chunk ,pcpu_low_unit_cpu ,page_start ), +pcpu_chunk_addr (chunk ,pcpu_high_unit_cpu ,page_end )); } static int __pcpu_map_pages(unsigned long addr, struct page **pages,
@@ -284,8 +284,8 @@ static void pcpu_post_map_flush(struct p int page_start, int page_end) {flush_cache_vmap ( -pcpu_chunk_addr (chunk ,pcpu_first_unit_cpu ,page_start ), -pcpu_chunk_addr (chunk ,pcpu_last_unit_cpu ,page_end )); +pcpu_chunk_addr (chunk ,pcpu_low_unit_cpu ,page_start ), +pcpu_chunk_addr (chunk ,pcpu_high_unit_cpu ,page_end )); }/**
mm/percpu.c +20 -14
@@ -116,9 +116,9 @@ static int pcpu_atom_size __read_mostly;static int pcpu_nr_slots__read_mostly ;static size_t pcpu_chunk_struct_size__read_mostly ; -/* cpus with the lowest and highest unit numbers */ -static unsigned int pcpu_first_unit_cpu__read_mostly ; -static unsigned int pcpu_last_unit_cpu__read_mostly ; +/* cpus with the lowest and highest unit addresses */ +static unsigned int pcpu_low_unit_cpu__read_mostly ; +static unsigned int pcpu_high_unit_cpu__read_mostly ;/* the address of the first chunk which starts with the kernel static area */ void *pcpu_base_addr__read_mostly ;
@@ -984,19 +984,19 @@ phys_addr_t per_cpu_ptr_to_phys(void *ad {void __percpu *base =__addr_to_pcpu_ptr (pcpu_base_addr);bool in_first_chunk = false; -unsigned long first_start, first_end; +unsigned long first_low, first_high;unsigned int cpu;/* -* The following test on first_start/end isn't strictly +* The following test on unit_low/high isn't strictly * necessary but will speed up lookups of addresses which * aren't in the first chunk. */ - first_start =pcpu_chunk_addr (pcpu_first_chunk, pcpu_first_unit_cpu,0 ); - first_end =pcpu_chunk_addr (pcpu_first_chunk, pcpu_last_unit_cpu, - pcpu_unit_pages); -if ((unsigned long )addr >= first_start && - (unsigned long )addr < first_end) { + first_low =pcpu_chunk_addr (pcpu_first_chunk, pcpu_low_unit_cpu,0 ); + first_high =pcpu_chunk_addr (pcpu_first_chunk, pcpu_high_unit_cpu, + pcpu_unit_pages); +if ((unsigned long )addr >= first_low && + (unsigned long )addr < first_high) {for_each_possible_cpu (cpu) {void *start =per_cpu_ptr (base, cpu);
@@ -1233,7 +1233,9 @@ int __init pcpu_setup_first_chunk(constfor (cpu =0 ; cpu < nr_cpu_ids; cpu++) unit_map[cpu] =UINT_MAX ; - pcpu_first_unit_cpu =NR_CPUS ; + + pcpu_low_unit_cpu =NR_CPUS ; + pcpu_high_unit_cpu =NR_CPUS ;for (group =0 , unit =0 ; group < ai->nr_groups; group++, unit += i) {const struct pcpu_group_info *gi = &ai->groups[group];
@@ -1253,9 +1255,13 @@ int __init pcpu_setup_first_chunk(const unit_map[cpu] = unit + i; unit_off[cpu] = gi->base_offset + i * ai->unit_size; -if (pcpu_first_unit_cpu ==NR_CPUS ) - pcpu_first_unit_cpu = cpu; - pcpu_last_unit_cpu = cpu; +/* determine low/high unit_cpu */ +if (pcpu_low_unit_cpu ==NR_CPUS || + unit_off[cpu] < unit_off[pcpu_low_unit_cpu]) + pcpu_low_unit_cpu = cpu; +if (pcpu_high_unit_cpu ==NR_CPUS || + unit_off[cpu] > unit_off[pcpu_high_unit_cpu]) + pcpu_high_unit_cpu = cpu; } } pcpu_nr_units = unit;
PATCH 21/45 iwlwifi: do not re-configure HT40 after associated
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wey-Yi Guy <[email protected]>
commit 34a5b4b6af104cf18eb50748509528b9bdbc4036 upstream.
The ht40 setting should not change after association unless channel switch
This fix a problem we are seeing which cause uCode assert because driver sending invalid information and make uCode confuse
Here is the firmware assert message:
kernel: iwlagn 0000:03:00.0: Microcode SW error detected. Restarting 0x82000000.
kernel: iwlagn 0000:03:00.0: Loaded firmware version: 17.168.5.3 build 42301
kernel: iwlagn 0000:03:00.0: Start IWL Error Log Dump:
kernel: iwlagn 0000:03:00.0: Status: 0x000512E4, count: 6
kernel: iwlagn 0000:03:00.0: 0x00002078 | ADVANCED_SYSASSERT
kernel: iwlagn 0000:03:00.0: 0x00009514 | uPc
kernel: iwlagn 0000:03:00.0: 0x00009496 | branchlink1
kernel: iwlagn 0000:03:00.0: 0x00009496 | branchlink2
kernel: iwlagn 0000:03:00.0: 0x0000D1F2 | interruptlink1
kernel: iwlagn 0000:03:00.0: 0x00000000 | interruptlink2
kernel: iwlagn 0000:03:00.0: 0x01008035 | data1
kernel: iwlagn 0000:03:00.0: 0x0000C90F | data2
kernel: iwlagn 0000:03:00.0: 0x000005A7 | line
kernel: iwlagn 0000:03:00.0: 0x5080B520 | beacon time
kernel: iwlagn 0000:03:00.0: 0xCC515AE0 | tsf low
kernel: iwlagn 0000:03:00.0: 0x00000003 | tsf hi
kernel: iwlagn 0000:03:00.0: 0x00000000 | time gp1
kernel: iwlagn 0000:03:00.0: 0x29703BF0 | time gp2
kernel: iwlagn 0000:03:00.0: 0x00000000 | time gp3
kernel: iwlagn 0000:03:00.0: 0x000111A8 | uCode version
kernel: iwlagn 0000:03:00.0: 0x000000B0 | hw version
kernel: iwlagn 0000:03:00.0: 0x00480303 | board version
kernel: iwlagn 0000:03:00.0: 0x09E8004E | hcmd
kernel: iwlagn 0000:03:00.0: CSR values:
kernel: iwlagn 0000:03:00.0: (2nd byte of CSR_INT_COALESCING is CSR_INT_PERIODIC_REG)
kernel: iwlagn 0000:03:00.0: CSR_HW_IF_CONFIG_REG: 0X00480303
kernel: iwlagn 0000:03:00.0: CSR_INT_COALESCING: 0X0000ff40
kernel: iwlagn 0000:03:00.0: CSR_INT: 0X00000000
kernel: iwlagn 0000:03:00.0: CSR_INT_MASK: 0X00000000
kernel: iwlagn 0000:03:00.0: CSR_FH_INT_STATUS: 0X00000000
kernel: iwlagn 0000:03:00.0: CSR_GPIO_IN: 0X00000030
kernel: iwlagn 0000:03:00.0: CSR_RESET: 0X00000000
kernel: iwlagn 0000:03:00.0: CSR_GP_CNTRL: 0X080403c5
kernel: iwlagn 0000:03:00.0: CSR_HW_REV: 0X000000b0
kernel: iwlagn 0000:03:00.0: CSR_EEPROM_REG: 0X07d60ffd
kernel: iwlagn 0000:03:00.0: CSR_EEPROM_GP: 0X90000001
kernel: iwlagn 0000:03:00.0: CSR_OTP_GP_REG: 0X00030001
kernel: iwlagn 0000:03:00.0: CSR_GIO_REG: 0X00080044
kernel: iwlagn 0000:03:00.0: CSR_GP_UCODE_REG: 0X000093bb
kernel: iwlagn 0000:03:00.0: CSR_GP_DRIVER_REG: 0X00000000
kernel: iwlagn 0000:03:00.0: CSR_UCODE_DRV_GP1: 0X00000000
kernel: iwlagn 0000:03:00.0: CSR_UCODE_DRV_GP2: 0X00000000
kernel: iwlagn 0000:03:00.0: CSR_LED_REG: 0X00000078
kernel: iwlagn 0000:03:00.0: CSR_DRAM_INT_TBL_REG: 0X88214dd2
kernel: iwlagn 0000:03:00.0: CSR_GIO_CHICKEN_BITS: 0X27800200
kernel: iwlagn 0000:03:00.0: CSR_ANA_PLL_CFG: 0X00000000
kernel: iwlagn 0000:03:00.0: CSR_HW_REV_WA_REG: 0X0001001a
kernel: iwlagn 0000:03:00.0: CSR_DBG_HPET_MEM_REG: 0Xffff0010
kernel: iwlagn 0000:03:00.0: FH register values:
kernel: iwlagn 0000:03:00.0: FH_RSCSR_CHNL0_STTS_WPTR_REG: 0X21316d00
kernel: iwlagn 0000:03:00.0: FH_RSCSR_CHNL0_RBDCB_BASE_REG: 0X021479c0
kernel: iwlagn 0000:03:00.0: FH_RSCSR_CHNL0_WPTR: 0X00000060
kernel: iwlagn 0000:03:00.0: FH_MEM_RCSR_CHNL0_CONFIG_REG: 0X80819104
kernel: iwlagn 0000:03:00.0: FH_MEM_RSSR_SHARED_CTRL_REG: 0X000000fc
kernel: iwlagn 0000:03:00.0: FH_MEM_RSSR_RX_STATUS_REG: 0X07030000
kernel: iwlagn 0000:03:00.0: FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV: 0X00000000
kernel: iwlagn 0000:03:00.0: FH_TSSR_TX_STATUS_REG: 0X07ff0001
kernel: iwlagn 0000:03:00.0: FH_TSSR_TX_ERROR_REG: 0X00000000
kernel: iwlagn 0000:03:00.0: Start IWL Event Log Dump: display last 20 entries
kernel: ------------[ cut here ]------------
WARNING: at net/mac80211/util.c:1208 ieee80211_reconfig+0x1f1/0x407() kernel: Hardware name: 4290W4H kernel: Pid: 1896, comm: kworker/0:0 Not tainted 3.1.0 #2 kernel: Call Trace: kernel: [<ffffffff81036558>] ? warn_slowpath_common+0x73/0x87 kernel: [<ffffffff813b8966>] ? ieee80211_reconfig+0x1f1/0x407 kernel: [<ffffffff8139e8dc>] ? ieee80211_recalc_smps_work+0x32/0x32 kernel: [<ffffffff8139e95a>] ? ieee80211_restart_work+0x7e/0x87 kernel: [<ffffffff810472fa>] ? process_one_work+0x1c8/0x2e3 kernel: [<ffffffff810480c9>] ? worker_thread+0x17a/0x23a kernel: [<ffffffff81047f4f>] ? manage_workers.clone.18+0x15b/0x15b kernel: [<ffffffff81047f4f>] ? manage_workers.clone.18+0x15b/0x15b kernel: [<ffffffff8104ba97>] ? kthread+0x7a/0x82 kernel: [<ffffffff813d21b4>] ? kernel_thread_helper+0x4/0x10 kernel: [<ffffffff8104ba1d>] ? kthread_flush_work_fn+0x11/0x11 kernel: [<ffffffff813d21b0>] ? gs_change+0xb/0xb
--- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 36 +++++++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-agn.c | 18 ++------------ drivers/net/wireless/iwlwifi/iwl-agn.h | 2 + 3 files changed, 28 insertions(+), 28 deletions(-)
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +23 -13
@@ -411,6 +411,24 @@ int iwlagn_commit_rxon(struct iwl_priv *return 0 ; } +void iwlagn_config_ht40 (struct ieee80211_conf *conf, +struct iwl_rxon_context *ctx) +{ +if (conf_is_ht40_minus (conf)) { + ctx->ht.extension_chan_offset = +IEEE80211_HT_PARAM_CHA_SEC_BELOW ; + ctx->ht.is_40mhz = true; + }else if (conf_is_ht40_plus (conf)) { + ctx->ht.extension_chan_offset = +IEEE80211_HT_PARAM_CHA_SEC_ABOVE ; + ctx->ht.is_40mhz = true; + }else { + ctx->ht.extension_chan_offset = +IEEE80211_HT_PARAM_CHA_SEC_NONE ; + ctx->ht.is_40mhz = false; + } +} +int iwlagn_mac_config (struct ieee80211_hw *hw,u32 changed) {struct iwl_priv *priv = hw->priv;
@@ -470,19 +488,11 @@ int iwlagn_mac_config(struct ieee80211_h ctx->ht.enabled =conf_is_ht (conf);if (ctx->ht.enabled) { -if (conf_is_ht40_minus (conf)) { - ctx->ht.extension_chan_offset = -IEEE80211_HT_PARAM_CHA_SEC_BELOW ; - ctx->ht.is_40mhz = true; - }else if (conf_is_ht40_plus (conf)) { - ctx->ht.extension_chan_offset = -IEEE80211_HT_PARAM_CHA_SEC_ABOVE ; - ctx->ht.is_40mhz = true; - }else { - ctx->ht.extension_chan_offset = -IEEE80211_HT_PARAM_CHA_SEC_NONE ; - ctx->ht.is_40mhz = false; - } +/* if HT40 is used, it should not change +* after associated except channel switch */ +if (iwl_is_associated_ctx (ctx) && + !ctx->ht.is_40mhz) +iwlagn_config_ht40 (conf, ctx); }else ctx->ht.is_40mhz = false;
drivers/net/wireless/iwlwifi/iwl-agn.c +3 -15
@@ -2872,21 +2872,9 @@ static void iwlagn_mac_channel_switch(st/* Configure HT40 channels */ ctx->ht.enabled =conf_is_ht (conf); -if (ctx->ht.enabled) { -if (conf_is_ht40_minus (conf)) { - ctx->ht.extension_chan_offset = -IEEE80211_HT_PARAM_CHA_SEC_BELOW ; - ctx->ht.is_40mhz = true; - }else if (conf_is_ht40_plus (conf)) { - ctx->ht.extension_chan_offset = -IEEE80211_HT_PARAM_CHA_SEC_ABOVE ; - ctx->ht.is_40mhz = true; - }else { - ctx->ht.extension_chan_offset = -IEEE80211_HT_PARAM_CHA_SEC_NONE ; - ctx->ht.is_40mhz = false; - } - }else +if (ctx->ht.enabled) +iwlagn_config_ht40 (conf, ctx); +else ctx->ht.is_40mhz = false;if ((le16_to_cpu (ctx->staging.channel) != ch))
drivers/net/wireless/iwlwifi/iwl-agn.h +2 -0
@@ -152,6 +152,8 @@ void iwlagn_bss_info_changed(struct ieeestruct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); +void iwlagn_config_ht40 (struct ieee80211_conf *conf, +struct iwl_rxon_context *ctx);/* uCode */ void iwlagn_rx_calib_result(struct iwl_priv *priv,
PATCH 22/45 mac80211: fix race condition caused by late addBA response
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Martynov <[email protected]>
Upstream commit d305a6557b2c4dca0110f05ffe745b1ef94adb80.
If addBA responses comes in just after addba_resp_timer has expired mac80211 will still accept it and try to open the aggregation session. This causes drivers to be confused and in some cases even crash.
This patch fixes the race condition and makes sure that if addba_resp_timer has expired addBA response is not longer accepted and we do not try to open half-closed session.
--- net/mac80211/agg-tx.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
net/mac80211/agg-tx.c +16 -1
@@ -792,12 +792,27 @@ void ieee80211_process_addba_resp(struct goto out; } -del_timer (&tid_tx->addba_resp_timer); +del_timer_sync (&tid_tx->addba_resp_timer);#ifdef CONFIG_MAC80211_HT_DEBUG printk (KERN_DEBUG "switched off addBA timer for tid %d\n" , tid);#endif +/* +* addba_resp_timer may have fired before we got here, and +* caused WANT_STOP to be set. If the stop then was already +* processed further, STOPPING might be set. +*/ +if (test_bit (HT_AGG_STATE_WANT_STOP , &tid_tx->state) || +test_bit (HT_AGG_STATE_STOPPING , &tid_tx->state)) { +#ifdef CONFIG_MAC80211_HT_DEBUG +printk (KERN_DEBUG +"got addBA resp for tid %d but we already gave up\n" , + tid); +#endif + goto out; + } +if (le16_to_cpu (mgmt->u.action.u.addba_resp.status) ==WLAN_STATUS_SUCCESS ) {/*
PATCH 23/45 linux/log2.h: Fix rounddown_pow_of_two(1)
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit 13c07b0286d340275f2d97adf085cecda37ede37 upstream.
Exactly like roundup_pow_of_two(1), the rounddown version was buggy for the case of a compile-time constant '1' argument. Probably because it originated from the same code, sharing history with the roundup version from before the bugfix (for that one, see commit 1a06a52ee1b0: "Fix roundup_pow_of_two(1)").
However, unlike the roundup version, the fix for rounddown is to just remove the broken special case entirely. It's simply not needed - the generic code
1UL << ilog2(n)
does the right thing for the constant '1' argment too. The only reason roundup needed that special case was because rounding up does so by subtracting one from the argument (and then adding one to the result) causing the obvious problems with "ilog2(0)".
But rounddown doesn't do any of that, since ilog2() naturally truncates (ie "rounds down") to the right rounded down value. And without the ilog2(0) case, there's no reason for the special case that had the wrong value.
tl;dr: rounddown_pow_of_two(1) should be 1, not 0.
--- include/linux/log2.h | 1 - 1 file changed, 1 deletion(-)
include/linux/log2.h +0 -1
@@ -185,7 +185,6 @@ unsigned long __rounddown_pow_of_two(uns#define rounddown_pow_of_two (n) \ ( \ __builtin_constant_p(n) ? ( \ - (n == 1) ? 0 : \ (1UL << ilog2(n))) : \ __rounddown_pow_of_two(n) \ )
PATCH 24/45 hwmon: (jz4740) fix signedness bug
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Axel Lin <[email protected]>
commit 0b57d7602b68f7b2786b2f0e22da39cbd4139a95 upstream.
wait_for_completion_interruptible_timeout() may return negative value. In this case, checking if (t > 0) will return true if t is unsigned.
--- drivers/hwmon/jz4740-hwmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/jz4740-hwmon.c +1 -1
@@ -59,7 +59,7 @@ static ssize_t jz4740_hwmon_read_adcin(s {struct jz4740_hwmon *hwmon =dev_get_drvdata (dev);struct completion *completion = &hwmon->read_completion; -unsigned long t; +long t;unsigned long val;int ret;
PATCH 25/45 mmc: mxcmmc: fix falling back to PIO
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sascha Hauer <[email protected]>
commit e58f516ff4730c4047c3f104b061f7a03e9a263c upstream.
When we can't configure the dma channel we want to fall back to PIO. We do this by setting host->do_dma to zero. This does not work as do_dma is used to see whether dma can be used for the current transfer. Instead, we have to set host->dma to NULL.
--- drivers/mmc/host/mxcmmc.c | 1 + 1 file changed, 1 insertion(+)
drivers/mmc/host/mxcmmc.c +1 -0
@@ -731,6 +731,7 @@ static void mxcmci_set_ios(struct mmc_ho "failed to config DMA channel. Falling back to PIO\n");dma_release_channel (host->dma); host->do_dma =0 ; + host->dma =NULL ; } }
PATCH 26/45 x86, hpet: Immediately disable HPET timer 1 if rtc irq is masked
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Langsdorf <[email protected]>
commit 2ded6e6a94c98ea453a156748cb7fabaf39a76b9 upstream.
When HPET is operating in RTC mode, the TN_ENABLE bit on timer1 controls whether the HPET or the RTC delivers interrupts to irq8. When the system goes into suspend, the RTC driver sends a signal to the HPET driver so that the HPET releases control of irq8, allowing the RTC to wake the system from suspend. The switchover is accomplished by a write to the HPET configuration registers which currently only occurs while servicing the HPET interrupt.
On some systems, I have seen the system suspend before an HPET interrupt occurs, preventing the write to the HPET configuration register and leaving the HPET in control of the irq8. As the HPET is not active during suspend, it does not generate a wake signal and RTC alarms do not work.
This patch forces the HPET driver to immediately transfer control of the irq8 channel to the RTC instead of waiting until the next interrupt event.
--- arch/x86/kernel/hpet.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
arch/x86/kernel/hpet.c +14 -7
@@ -1054,6 +1054,14 @@ int hpet_rtc_timer_init(void) }EXPORT_SYMBOL_GPL (hpet_rtc_timer_init); +static void hpet_disable_rtc_channel (void ) +{ +unsigned long cfg; + cfg =hpet_readl (HPET_T1_CFG ); + cfg &= ~HPET_TN_ENABLE ; +hpet_writel (cfg,HPET_T1_CFG ); +} +/* * The functions below are called from rtc driver. * Return 0 if HPET is not being used.
@@ -1065,6 +1073,9 @@ int hpet_mask_rtc_irq_bit(unsigned longreturn 0 ; hpet_rtc_flags &= ~bit_mask; +if (unlikely (!hpet_rtc_flags)) +hpet_disable_rtc_channel (); +return 1 ; }EXPORT_SYMBOL_GPL (hpet_mask_rtc_irq_bit);
@@ -1130,15 +1141,11 @@ EXPORT_SYMBOL_GPL(hpet_rtc_dropped_irq);static void hpet_rtc_timer_reinit (void ) { -unsigned int cfg, delta; +unsigned int delta;int lost_ints =-1 ; -if (unlikely (!hpet_rtc_flags)) { - cfg =hpet_readl (HPET_T1_CFG ); - cfg &= ~HPET_TN_ENABLE ; -hpet_writel (cfg,HPET_T1_CFG ); -return ; - } +if (unlikely (!hpet_rtc_flags)) +hpet_disable_rtc_channel ();if (!(hpet_rtc_flags &RTC_PIE ) || hpet_pie_limit) delta = hpet_default_delta;
PATCH 27/45 jbd/jbd2: validate sb->s_first in journal_get_superblock()
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eryu Guan <[email protected]>
commit 8762202dd0d6e46854f786bdb6fb3780a1625efe upstream.
I hit a J_ASSERT(blocknr != 0) failure in cleanup_journal_tail() when mounting a fsfuzzed ext3 image. It turns out that the corrupted ext3 image has s_first = 0 in journal superblock, and the 0 is passed to journal->j_head in journal_reset(), then to blocknr in cleanup_journal_tail(), in the end the J_ASSERT failed.
So validate s_first after reading journal superblock from disk in journal_get_superblock() to ensure s_first is valid.
The following script could reproduce it:
fstype=ext3
blocksize=1024
img=$fstype.img
offset=0
found=0
magic="c0 3b 39 98"
dd if=/dev/zero of=$img bs=1M count=8
mkfs -t $fstype -b $blocksize -F $img
filesize=stat -c %s $img
while [ $offset -lt $filesize ]
do
if od -j $offset -N 4 -t x1 $img | grep -i "$magic";then
echo "Found journal: $offset"
found=1
break
fi
offset=echo "$offset+$blocksize" | bc
done
if [ $found -ne 1 ];then
echo "Magic \"$magic\" not found"
exit 1
fi
dd if=/dev/zero of=$img seek=$(($offset+23)) conv=notrunc bs=1 count=1
mkdir -p ./mnt
mount -o loop $img ./mnt
--- fs/jbd/journal.c | 8 ++++++++ fs/jbd2/journal.c | 8 ++++++++ 2 files changed, 16 insertions(+)
fs/jbd/journal.c +8 -0
@@ -1131,6 +1131,14 @@ static int journal_get_superblock(journa goto out; } +if (be32_to_cpu (sb->s_first) ==0 || +be32_to_cpu (sb->s_first) >= journal->j_maxlen) { +printk (KERN_WARNING +"JBD: Invalid start block of journal: %u\n" , +be32_to_cpu (sb->s_first)); + goto out; + } +return 0 ; out:
fs/jbd2/journal.c +8 -0
@@ -1251,6 +1251,14 @@ static int journal_get_superblock(journa goto out; } +if (be32_to_cpu (sb->s_first) ==0 || +be32_to_cpu (sb->s_first) >= journal->j_maxlen) { +printk (KERN_WARNING +"JBD2: Invalid start block of journal: %u\n" , +be32_to_cpu (sb->s_first)); + goto out; + } +return 0 ; out:
PATCH 28/45 Make TASKSTATS require root access
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit 1a51410abe7d0ee4b1d112780f46df87d3621043 upstream.
Ok, this isn't optimal, since it means that 'iotop' needs admin capabilities, and we may have to work on this some more. But at the same time it is very much not acceptable to let anybody just read anybody elses IO statistics quite at this level.
Use of the GENL_ADMIN_PERM suggested by Johannes Berg as an alternative to checking the capabilities by hand.
--- kernel/taskstats.c | 1 + 1 file changed, 1 insertion(+)
kernel/taskstats.c +1 -0
@@ -657,6 +657,7 @@ static struct genl_ops taskstats_ops = { .cmd = TASKSTATS_CMD_GET, .doit = taskstats_user_cmd, .policy = taskstats_cmd_get_policy, + .flags = GENL_ADMIN_PERM, };static struct genl_ops cgroupstats_ops = {
PATCH 29/45 hfs: fix hfs_find_init() sb->ext_tree NULL ptr oops
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phillip Lougher <[email protected]>
commit 434a964daa14b9db083ce20404a4a2add54d037a upstream.
Clement Lecigne reports a filesystem which causes a kernel oops in hfs_find_init() trying to dereference sb->ext_tree which is NULL.
This proves to be because the filesystem has a corrupted MDB extent record, where the extents file does not fit into the first three extents in the file record (the first blocks).
In hfs_get_block() when looking up the blocks for the extent file (HFS_EXT_CNID), it fails the first blocks special case, and falls through to the extent code (which ultimately calls hfs_find_init()) which is in the process of being initialised.
Hfs avoids this scenario by always having the extents b-tree fitting into the first blocks (the extents B-tree can't have overflow extents).
The fix is to check at mount time that the B-tree fits into first blocks, i.e. fail if HFS_I(inode)->alloc_blocks >= HFS_I(inode)->first_blocks
Note, the existing commit 47f365eb57573 ("hfs: fix oops on mount with corrupted btree extent records") becomes subsumed into this as a special case, but only for the extents B-tree (HFS_EXT_CNID), it is perfectly acceptable for the catalog B-Tree file to grow beyond three extents, with the remaining extent descriptors in the extents overfow.
This fixes CVE-2011-2203
--- fs/hfs/btree.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
fs/hfs/btree.c +15 -5
@@ -46,11 +46,26 @@ struct hfs_btree *hfs_btree_open(structcase HFS_EXT_CNID :hfs_inode_read_fork (tree->inode, mdb->drXTExtRec, mdb->drXTFlSize, mdb->drXTFlSize,be32_to_cpu (mdb->drXTClpSiz)); +if (HFS_I (tree->inode)->alloc_blocks > +HFS_I (tree->inode)->first_blocks) { +printk (KERN_ERR "hfs: invalid btree extent records\n" ); +unlock_new_inode (tree->inode); + goto free_inode; + } + tree->inode->i_mapping->a_ops = &hfs_btree_aops;break ;case HFS_CAT_CNID :hfs_inode_read_fork (tree->inode, mdb->drCTExtRec, mdb->drCTFlSize, mdb->drCTFlSize,be32_to_cpu (mdb->drCTClpSiz)); + +if (!HFS_I (tree->inode)->first_blocks) { +printk (KERN_ERR "hfs: invalid btree extent records " +"(0 size).\n" ); +unlock_new_inode (tree->inode); + goto free_inode; + } + tree->inode->i_mapping->a_ops = &hfs_btree_aops;break ;default :
@@ -59,11 +74,6 @@ struct hfs_btree *hfs_btree_open(struct }unlock_new_inode (tree->inode); -if (!HFS_I (tree->inode)->first_blocks) { -printk (KERN_ERR "hfs: invalid btree extent records (0 size).\n" ); - goto free_inode; - } - mapping = tree->inode->i_mapping; page =read_mapping_page (mapping,0 ,NULL );if (IS_ERR (page))
PATCH 30/45 hwmon: (coretemp) Fix oops on CPU offlining
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
This is for stable kernel branch 3.0 only. Previous and later versions have different code paths and are not affected by this bug.
This is the same fix as "hwmon: (coretemp) Fix oops on driver load" but for the CPU offlining case. Sorry for missing it at first.
--- drivers/hwmon/coretemp.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/hwmon/coretemp.c +2 -0
@@ -747,6 +747,8 @@ static void __cpuinit put_core_offline(ureturn ; pdata =platform_get_drvdata (pdev); +if (!pdata) +return ; indx =TO_ATTR_NO (cpu);
RE: [30/45] hwmon: (coretemp) Fix oops on CPU offlining
Quoted 20 lines
-----Original Message-----
From: Greg KH [mailto:[email protected]]
Sent: Friday, December 16, 2011 11:41 AM
To: [email protected]; [email protected]; [email protected]
Cc: [email protected]; [email protected]; [email protected]; Guenter Roeck; Greg KH; Jean Delvare; R, Durgadoss; Yu, Fenghua
Subject: [30/45] hwmon: (coretemp) Fix oops on CPU offlining3.0-stable review patch. If anyone has any objections, please let me know.
------------------
This is for stable kernel branch 3.0 only. Previous and later versions have different code paths and are not affected by this bug.
Quoted 8 lines
This is the same fix as "hwmon: (coretemp) Fix oops on driver load" but for the CPU offlining case. Sorry for missing it at first.
Signed-off-by Jean Delvare <[email protected]>Cc Durgadoss R <[email protected]>Acked-by Guenter Roeck <[email protected]>Cc Fenghua Yu <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
PATCH 31/45 xfs: fix nfs export of 64-bit inodes numbers on 32-bit kernels
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
commit c29f7d457ac63311feb11928a866efd2fe153d74 upstream.
The i_ino field in the VFS inode is of type unsigned long and thus can't hold the full 64-bit inode number on 32-bit kernels. We have the full inode number in the XFS inode, so use that one for nfs exports. Note that I've also switched the 32-bit file handles types to it, just to make the code more consistent and copy & paste errors less likely to happen.
--- fs/xfs/linux-2.6/xfs_export.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/xfs/linux-2.6/xfs_export.c +4 -4
@@ -98,22 +98,22 @@ xfs_fs_encode_fh(switch (fileid_type) {case FILEID_INO32_GEN_PARENT :spin_lock (&dentry->d_lock); - fid->i32.parent_ino = dentry->d_parent->d_inode->i_ino; + fid->i32.parent_ino =XFS_I (dentry->d_parent->d_inode)->i_ino; fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation;spin_unlock (&dentry->d_lock);/*FALLTHRU*/ case FILEID_INO32_GEN : - fid->i32.ino = inode->i_ino; + fid->i32.ino =XFS_I (inode)->i_ino; fid->i32.gen = inode->i_generation;break ;case FILEID_INO32_GEN_PARENT |XFS_FILEID_TYPE_64FLAG :spin_lock (&dentry->d_lock); - fid64->parent_ino = dentry->d_parent->d_inode->i_ino; + fid64->parent_ino =XFS_I (dentry->d_parent->d_inode)->i_ino; fid64->parent_gen = dentry->d_parent->d_inode->i_generation;spin_unlock (&dentry->d_lock);/*FALLTHRU*/ case FILEID_INO32_GEN |XFS_FILEID_TYPE_64FLAG : - fid64->ino = inode->i_ino; + fid64->ino =XFS_I (inode)->i_ino; fid64->gen = inode->i_generation;break ; }
PATCH 32/45 xfs: avoid synchronous transactions when deleting attr blocks
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
commit 859f57ca00805e6c482eef1a7ab073097d02c8ca upstream.
[slightly different from the upstream version because of a previous cleanup]
Currently xfs_attr_inactive causes a synchronous transactions if we are removing a file that has any extents allocated to the attribute fork, and thus makes XFS extremely slow at removing files with out of line extended attributes. The code looks a like a relict from the days before the busy extent list, but with the busy extent list we avoid reusing data and attr extents that have been freed but not commited yet, so this code is just as superflous as the synchronous transactions for data blocks.
--- fs/xfs/xfs_attr.c | 14 +++----------- fs/xfs/xfs_bmap.c | 10 +--------- fs/xfs/xfs_inode.c | 8 -------- 3 files changed, 4 insertions(+), 28 deletions(-)
fs/xfs/xfs_attr.c +3 -11
@@ -822,17 +822,9 @@ xfs_attr_inactive(xfs_inode_t *dp) error =xfs_attr_root_inactive (&trans, dp);if (error) goto out; -/* -* signal synchronous inactive transactions unless this -* is a synchronous mount filesystem in which case we -* know that we're here because we've been called out of -* xfs_inactive which means that the last reference is gone -* and the unlink transaction has already hit the disk so -* async inactive transactions are safe. -*/ -if ((error =xfs_itruncate_finish (&trans, dp,0LL ,XFS_ATTR_FORK , - (!(mp->m_flags &XFS_MOUNT_WSYNC ) - ?1 :0 )))) + + error =xfs_itruncate_finish (&trans, dp,0LL ,XFS_ATTR_FORK ,0 ); +if (error) goto out;/*
fs/xfs/xfs_bmap.c +1 -9
@@ -3785,19 +3785,11 @@ xfs_bmap_compute_maxlevels(* Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi * caller. Frees all the extents that need freeing, which must be done * last due to locking considerations. We never free any extents in -* the first transaction. This is to allow the caller to make the first -* transaction a synchronous one so that the pointers to the data being -* broken in this transaction will be permanent before the data is actually -* freed. This is necessary to prevent blocks from being reallocated -* and written to before the free and reallocation are actually permanent. -* We do not just make the first transaction synchronous here, because -* there are more efficient ways to gain the same protection in some cases -* (see the file truncation code). +* the first transaction. * * Return 1 if the given transaction was committed and a new one * started, and 0 otherwise in the committed parameter. */ -/*ARGSUSED*/ int /* error */ xfs_bmap_finish( xfs_trans_t **tp, /* transaction pointer addr */
fs/xfs/xfs_inode.c +0 -8
@@ -1528,15 +1528,7 @@ xfs_itruncate_finish(xfs_trans_log_inode (ntp, ip,XFS_ILOG_CORE ); } } - }else if (sync) { -ASSERT (!(mp->m_flags &XFS_MOUNT_WSYNC )); -if (ip->i_d.di_anextents >0 ) -xfs_trans_set_sync (ntp); } -ASSERT (fork ==XFS_DATA_FORK || - (fork ==XFS_ATTR_FORK && - ((sync && !(mp->m_flags &XFS_MOUNT_WSYNC )) || - (sync ==0 && (mp->m_flags &XFS_MOUNT_WSYNC )))));/* * Since it is possible for space to become allocated beyond
PATCH 33/45 md/raid5: fix bug that could result in reads from a failed device.
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 355840e7a7e56bb2834fd3b0da64da5465f8aeaa upstream.
commit a847627709b3402163d99f7c6fda4a77bcd6b51b in linux-3.0.9 attempted to backport this to 3.0 but only made one change were two were necessary. This add the second change.
This bug was introduced in 415e72d034c50520ddb7ff79e7d1792c1306f0c9 which was in 2.6.36.
There is a small window of time between when a device fails and when it is removed from the array. During this time we might still read from it, but we won't write to it - so it is possible that we could read stale data.
We didn't need the test of 'Faulty' before because the test on In_sync is sufficient. Since we started allowing reads from the early part of non-In_sync devices we need a test on Faulty too.
This is suitable for any kernel from 2.6.36 onwards, though the patch might need a bit of tweaking in 3.0 and earlier.
--- drivers/md/raid5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/raid5.c +1 -1
@@ -3078,7 +3078,7 @@ static void handle_stripe5(struct stripe/* Not in-sync */ ; else if (test_bit(In_sync, &rdev->flags)) set_bit(R5_Insync, &dev->flags); - else { + else if (!test_bit(Faulty, &rdev->flags)) {/* could be in-sync depending on recovery/reshape status */ if (sh->sector +STRIPE_SECTORS <= rdev->recovery_offset)set_bit (R5_Insync, &dev->flags);
PATCH 34/45 xen: only limit memory map to maximum reservation for domain 0.
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Campbell <[email protected]>
commit d3db728125c4470a2d061ac10fa7395e18237263 upstream.
d312ae878b6a "xen: use maximum reservation to limit amount of usable RAM" clamped the total amount of RAM to the current maximum reservation. This is correct for dom0 but is not correct for guest domains. In order to boot a guest "pre-ballooned" (e.g. with memory=1G but maxmem=2G) in order to allow for future memory expansion the guest must derive max_pfn from the e820 provided by the toolstack and not the current maximum reservation (which can reflect only the current maximum, not the guest lifetime max). The existing algorithm already behaves this correctly if we do not artificially limit the maximum number of pages for the guest case.
For a guest booted with maxmem=512, memory=128 this results in:
[ 0.000000] BIOS-provided physical RAM map: [ 0.000000] Xen: 0000000000000000 - 00000000000a0000 (usable) [ 0.000000] Xen: 00000000000a0000 - 0000000000100000 (reserved) -[ 0.000000] Xen: 0000000000100000 - 0000000008100000 (usable) -[ 0.000000] Xen: 0000000008100000 - 0000000020800000 (unusable) +[ 0.000000] Xen: 0000000000100000 - 0000000020800000 (usable) ... [ 0.000000] NX (Execute Disable) protection: active [ 0.000000] DMI not present or invalid. [ 0.000000] e820 update range: 0000000000000000 - 0000000000010000 (usable) ==> (reserved) [ 0.000000] e820 remove range: 00000000000a0000 - 0000000000100000 (usable) -[ 0.000000] last_pfn = 0x8100 max_arch_pfn = 0x1000000 +[ 0.000000] last_pfn = 0x20800 max_arch_pfn = 0x1000000 [ 0.000000] initial memory mapped : 0 - 027ff000 [ 0.000000] Base memory trampoline at [c009f000] 9f000 size 4096 -[ 0.000000] init_memory_mapping: 0000000000000000-0000000008100000 -[ 0.000000] 0000000000 - 0008100000 page 4k -[ 0.000000] kernel direct mapping tables up to 8100000 @ 27bb000-27ff000 +[ 0.000000] init_memory_mapping: 0000000000000000-0000000020800000 +[ 0.000000] 0000000000 - 0020800000 page 4k +[ 0.000000] kernel direct mapping tables up to 20800000 @ 26f8000-27ff000 [ 0.000000] xen: setting RW the range 27e8000 - 27ff000 [ 0.000000] 0MB HIGHMEM available. -[ 0.000000] 129MB LOWMEM available. -[ 0.000000] mapped low ram: 0 - 08100000 -[ 0.000000] low ram: 0 - 08100000 +[ 0.000000] 520MB LOWMEM available. +[ 0.000000] mapped low ram: 0 - 20800000 +[ 0.000000] low ram: 0 - 20800000
With this change "xl mem-set <domain> 512M" will successfully increase the guest RAM (by reducing the balloon).
There is no change for dom0.
--- arch/x86/xen/setup.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
arch/x86/xen/setup.c +15 -3
@@ -192,9 +192,21 @@ static unsigned long __init xen_get_max_domid_t domid =DOMID_SELF ;int ret; - ret =HYPERVISOR_memory_op (XENMEM_maximum_reservation, &domid); -if (ret >0 ) - max_pages = ret; +/* +* For the initial domain we use the maximum reservation as +* the maximum page. +* +* For guest domains the current maximum reservation reflects +* the current maximum rather than the static maximum. In this +* case the e820 map provided to us will cover the static +* maximum region. +*/ +if (xen_initial_domain ()) { + ret =HYPERVISOR_memory_op (XENMEM_maximum_reservation, &domid); +if (ret >0 ) + max_pages = ret; + } +return min (max_pages,MAX_DOMAIN_PAGES ); }
PATCH 35/45 ext4: display the correct mount option in /proc/mounts for [no]init_itable
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit fc6cb1cda5db7b2d24bf32890826214b857c728e upstream.
/proc/mounts was showing the mount option [no]init_inode_table when the correct mount option that will be accepted by parse_options() is [no]init_itable.
--- fs/ext4/super.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
fs/ext4/super.c +8 -9
@@ -1113,9 +1113,9 @@ static int ext4_show_options(struct seq_seq_puts (seq,",block_validity" );if (!test_opt (sb,INIT_INODE_TABLE )) -seq_puts (seq,",noinit_inode_table" ); +seq_puts (seq,",noinit_itable" );else if (sbi->s_li_wait_mult !=EXT4_DEF_LI_WAIT_MULT ) -seq_printf (seq,",init_inode_table=%u" , +seq_printf (seq,",init_itable=%u" , (unsigned ) sbi->s_li_wait_mult);ext4_show_quota_options (seq, sb);
@@ -1291,8 +1291,7 @@ enum { Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, Opt_inode_readahead_blks, Opt_journal_ioprio, Opt_dioread_nolock, Opt_dioread_lock, - Opt_discard, Opt_nodiscard, - Opt_init_inode_table, Opt_noinit_inode_table, + Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable, }; static const match_table_t tokens = {
@@ -1365,9 +1364,9 @@ static const match_table_t tokens = { {Opt_dioread_lock, "dioread_lock"}, {Opt_discard, "discard"}, {Opt_nodiscard, "nodiscard"}, - {Opt_init_inode_table, "init_itable=%u"}, - {Opt_init_inode_table, "init_itable"}, - {Opt_noinit_inode_table, "noinit_itable"}, + {Opt_init_itable, "init_itable=%u"}, + {Opt_init_itable, "init_itable"}, + {Opt_noinit_itable, "noinit_itable"}, {Opt_err, NULL}, };
@@ -1844,7 +1843,7 @@ set_qf_format:case Opt_dioread_lock:clear_opt (sb,DIOREAD_NOLOCK );break ; -case Opt_init_inode_table: +case Opt_init_itable:set_opt (sb,INIT_INODE_TABLE );if (args[0 ].from) {if (match_int (&args[0 ], &option))
@@ -1855,7 +1854,7 @@ set_qf_format:return 0 ; sbi->s_li_wait_mult = option;break ; -case Opt_noinit_inode_table: +case Opt_noinit_itable:clear_opt (sb,INIT_INODE_TABLE );break ;default :
PATCH 36/45 ext4: avoid hangs in ext4_da_should_update_i_disksize()
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea Arcangeli <[email protected]>
commit ea51d132dbf9b00063169c1159bee253d9649224 upstream.
If the pte mapping in generic_perform_write() is unmapped between iov_iter_fault_in_readable() and iov_iter_copy_from_user_atomic(), the "copied" parameter to ->end_write can be zero. ext4 couldn't cope with it with delayed allocations enabled. This skips the i_disksize enlargement logic if copied is zero and no new data was appeneded to the inode.
gdb> bt
#0 0xffffffff811afe80 in ext4_da_should_update_i_disksize (file=0xffff88003f606a80, mapping=0xffff88001d3824e0, pos=0x1\
08000, len=0x1000, copied=0x0, page=0xffffea0000d792e8, fsdata=0x0) at fs/ext4/inode.c:2467
#1 ext4_da_write_end (file=0xffff88003f606a80, mapping=0xffff88001d3824e0, pos=0x108000, len=0x1000, copied=0x0, page=0\
xffffea0000d792e8, fsdata=0x0) at fs/ext4/inode.c:2512
#2 0xffffffff810d97f1 in generic_perform_write (iocb=<value optimized out>, iov=<value optimized out>, nr_segs=<value o\
ptimized out>, pos=0x108000, ppos=0xffff88001e26be40, count=<value optimized out>, written=0x0) at mm/filemap.c:2440 #3 generic_file_buffered_write (iocb=<value optimized out>, iov=<value optimized out>, nr_segs=<value optimized out>, p\
os=0x108000, ppos=0xffff88001e26be40, count=<value optimized out>, written=0x0) at mm/filemap.c:2482 #4 0xffffffff810db5d1 in __generic_file_aio_write (iocb=0xffff88001e26bde8, iov=0xffff88001e26bec8, nr_segs=0x1, ppos=0\
xffff88001e26be40) at mm/filemap.c:2600
#5 0xffffffff810db853 in generic_file_aio_write (iocb=0xffff88001e26bde8, iov=0xffff88001e26bec8, nr_segs=<value optimi\
zed out>, pos=<value optimized out>) at mm/filemap.c:2632
#6 0xffffffff811a71aa in ext4_file_write (iocb=0xffff88001e26bde8, iov=0xffff88001e26bec8, nr_segs=0x1, pos=0x108000) a\
t fs/ext4/file.c:136
#7 0xffffffff811375aa in do_sync_write (filp=0xffff88003f606a80, buf=<value optimized out>, len=<value optimized out>, \
ppos=0xffff88001e26bf48) at fs/read_write.c:406
#8 0xffffffff81137e56 in vfs_write (file=0xffff88003f606a80, buf=0x1ec2960 <Address 0x1ec2960 out of bounds>, count=0x4\
000, pos=0xffff88001e26bf48) at fs/read_write.c:435
#9 0xffffffff8113816c in sys_write (fd=<value optimized out>, buf=0x1ec2960 <Address 0x1ec2960 out of bounds>, count=0x\
4000) at fs/read_write.c:487
#10 <signal handler called>
#11 0x00007f120077a390 in __brk_reservation_fn_dmi_alloc__ ()
#12 0x0000000000000000 in ?? ()
gdb> print offset
$22 = 0xffffffffffffffff
gdb> print idx
$23 = 0xffffffff
gdb> print inode->i_blkbits
$24 = 0xc
gdb> up
#1 ext4_da_write_end (file=0xffff88003f606a80, mapping=0xffff88001d3824e0, pos=0x108000, len=0x1000, copied=0x0, page=0\
xffffea0000d792e8, fsdata=0x0) at fs/ext4/inode.c:2512
2512 if (ext4_da_should_update_i_disksize(page, end)) {
gdb> print start
$25 = 0x0
gdb> print end
$26 = 0xffffffffffffffff
gdb> print pos
$27 = 0x108000
gdb> print new_i_size
$28 = 0x108000
gdb> print ((struct ext4_inode_info *)((char *)inode-((int)(&((struct ext4_inode_info *)0)->vfs_inode))))->i_disksize
$29 = 0xd9000
gdb> down
2467 for (i = 0; i < idx; i++)
gdb> print i
$30 = 0xd44acbeeThis is 100% reproducible with some autonuma development code tuned in a very aggressive manner (not normal way even for knumad) which does "exotic" changes to the ptes. It wouldn't normally trigger but I don't see why it can't happen normally if the page is added to swap cache in between the two faults leading to "copied" being zero (which then hangs in ext4). So it should be fixed. Especially possible with lumpy reclaim (albeit disabled if compaction is enabled) as that would ignore the young bits in the ptes.
--- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/inode.c +1 -1
@@ -3231,7 +3231,7 @@ static int ext4_da_write_end(struct file*/ new_i_size = pos + copied; -if (new_i_size >EXT4_I (inode)->i_disksize) { +if (copied && new_i_size >EXT4_I (inode)->i_disksize) {if (ext4_da_should_update_i_disksize (page, end)) {down_write (&EXT4_I (inode)->i_data_sem);if (new_i_size >EXT4_I (inode)->i_disksize) {
PATCH 37/45 ext4: avoid potential hang in mpage_submit_io() when blocksize < pagesize
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongqiang Yang <[email protected]>
commit 13a79a4741d37fda2fbafb953f0f301dc007928f upstream.
If there is an unwritten but clean buffer in a page and there is a dirty buffer after the buffer, then mpage_submit_io does not write the dirty buffer out. As a result, da_writepages loops forever.
This patch fixes the problem by checking dirty flag.
--- fs/ext4/inode.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/ext4/inode.c +5 -2
@@ -2126,8 +2126,11 @@ static int mpage_da_submit_io(struct mpaclear_buffer_unwritten (bh); } -/* skip page if block allocation undone */ -if (buffer_delay (bh) ||buffer_unwritten (bh)) +/* +* skip page if block allocation undone and +* block is dirty +*/ +if (ext4_bh_delay_or_unwritten (NULL , bh)) skip_page =1 ; bh = bh->b_this_page; block_start += bh->b_size;
PATCH 38/45 ext4: handle EOF correctly in ext4_bio_write_page()
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongqiang Yang <[email protected]>
commit 5a0dc7365c240795bf190766eba7a27600be3b3e upstream.
We need to zero out part of a page which beyond EOF before setting uptodate, otherwise, mapread or write will see non-zero data beyond EOF.
--- fs/ext4/page-io.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
fs/ext4/page-io.c +12 -0
@@ -405,6 +405,18 @@ int ext4_bio_write_page(struct ext4_io_s block_end = block_start + blocksize;if (block_start >= len) { +/* +* Comments copied from block_write_full_page_endio: +* +* The page straddles i_size. It must be zeroed out on +* each and every writepage invocation because it may +* be mmapped. "A file is mapped in multiples of the +* page size. For a file that is not a multiple of +* the page size, the remaining memory is zeroed when +* mapped, and writes to that region are not written +* out to the file." +*/ +zero_user_segment (page, block_start, block_end);clear_buffer_dirty (bh);set_buffer_uptodate (bh);continue ;
PATCH 39/45 fuse: fix fuse_retrieve
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <[email protected]>
commit 48706d0a91583d08c56e7ef2a7602d99c8d4133f upstream.
Fix two bugs in fuse_retrieve():
- retrieving more than one page would yield repeated instances of the first page
- if more than FUSE_MAX_PAGES_PER_REQ pages were requested than the request page array would overflow
fuse_retrieve() was added in 2.6.36 and these bugs had been there since the beginning.
--- fs/fuse/dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/fuse/dev.c +2 -1
@@ -1512,7 +1512,7 @@ static int fuse_retrieve(struct fuse_conelse if (outarg->offset + num > file_size) num = file_size - outarg->offset; -while (num) { +while (num && req->num_pages <FUSE_MAX_PAGES_PER_REQ ) {struct page *page;unsigned int this_num;
@@ -1526,6 +1526,7 @@ static int fuse_retrieve(struct fuse_con num -= this_num; total_len += this_num; + index++; } req->misc.retrieve_in.offset = outarg->offset; req->misc.retrieve_in.size = total_len;
PATCH 40/45 staging: r8712u: Add new USB ID
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larry Finger <[email protected]>
commit c7caf4d4c56aee40b995f5858ccf1c814f3d2da2 upstream.
Add USB ID for Sitecom WLA-2000 v1.001 WLAN.
--- drivers/staging/rtl8712/usb_intf.c | 1 + 1 file changed, 1 insertion(+)
drivers/staging/rtl8712/usb_intf.c +1 -0
@@ -86,6 +86,7 @@ static struct usb_device_id rtl871x_usb_ {USB_DEVICE(0x0DF6, 0x0045)}, {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ {USB_DEVICE(0x0DF6, 0x004B)}, + {USB_DEVICE(0x0DF6, 0x005D)}, {USB_DEVICE(0x0DF6, 0x0063)},/* Sweex */ {USB_DEVICE(0x177F, 0x0154)},
PATCH 41/45 drm/radeon/kms: add some new pci ids
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit cd5cfce856684e13b9b57d46b78bb827e9c4da3c upstream.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=43739
--- include/drm/drm_pciids.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
include/drm/drm_pciids.h +10 -0
@@ -182,8 +182,11 @@ {0x1002, 0x6748, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6758, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6759, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x675B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x675D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x675F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6761, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
@@ -195,8 +198,10 @@ {0x1002, 0x6767, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6768, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x677B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x6842, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
@@ -246,6 +251,7 @@ {0x1002, 0x68f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68f8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68f9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68fa, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x68fe, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ {0x1002, 0x7100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ {0x1002, 0x7101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
@@ -488,6 +494,8 @@ {0x1002, 0x9647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ {0x1002, 0x9648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ {0x1002, 0x964a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x964b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x964c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x964e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ {0x1002, 0x964f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ {0x1002, 0x9710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \
@@ -502,6 +510,8 @@ {0x1002, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9806, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9807, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0, 0, 0} #define r128_PCI_IDS \
PATCH 42/45 ibft: Fix finding IBFT ACPI table on UEFI
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yinghai Lu <[email protected]>
commit 935a9fee51c945b8942be2d7b4bae069167b4886 upstream.
Found one system with UEFI/iBFT, kernel does not detect the iBFT during iscsi_ibft module loading.
Root cause: on x86 (UEFI), we are calling of find_ibft_region() much earlier
- specifically in setup_arch() before ACPI is enabled.
Try to split acpi checking code out and call that later
At that time ACPI iBFT already get permanent mapped with ioremap. So isa_virt_to_bus() will get wrong phys from right virt address. We could just skip that phys address printing.
For legacy one, print the found address early.
-v2: update comments and description according to Konrad.
-v3: fix problem about module use case that is found by Konrad.
-v4: use acpi_get_table() instead of acpi_table_parse() to handle module use case that is found by Konrad again..
--- drivers/firmware/iscsi_ibft.c | 42 +++++++++++++++++++++++++++++++++++-- drivers/firmware/iscsi_ibft_find.c | 26 +--------------------- 2 files changed, 42 insertions(+), 26 deletions(-)
drivers/firmware/iscsi_ibft.c +40 -2
@@ -738,6 +738,37 @@ static void __exit ibft_exit(void)ibft_cleanup (); } +#ifdef CONFIG_ACPI +static const struct { +char *sign; +} ibft_signs[] = { +/* +* One spec says "IBFT", the other says "iBFT". We have to check +* for both. +*/ + {ACPI_SIG_IBFT }, + {"iBFT" }, +}; + +static void __init acpi_find_ibft_region (void ) +{ +int i; +struct acpi_table_header *table =NULL ; + +if (acpi_disabled) +return ; + +for (i =0 ; i <ARRAY_SIZE (ibft_signs) && !ibft_addr; i++) { +acpi_get_table (ibft_signs[i].sign,0 , &table); + ibft_addr = (struct acpi_table_ibft *)table; + } +} +#else +static void __init acpi_find_ibft_region (void ) +{ +} +#endif +/* * ibft_init() - creates sysfs tree entries for the iBFT data. */
@@ -745,9 +776,16 @@ static int __init ibft_init(void) {int rc =0 ; +/* +As on UEFI systems the setup_arch()/find_ibft_region() +is called before ACPI tables are parsed and it only does +legacy finding. +*/ +if (!ibft_addr) +acpi_find_ibft_region (); +if (ibft_addr) { -printk (KERN_INFO "iBFT detected at 0x%llx.\n" , - (u64 )isa_virt_to_bus (ibft_addr)); +pr_info ("iBFT detected.\n" ); rc =ibft_check_device ();if (rc)
drivers/firmware/iscsi_ibft_find.c +2 -24
@@ -45,13 +45,6 @@ EXPORT_SYMBOL_GPL(ibft_addr);static const struct {char *sign; } ibft_signs[] = { -#ifdef CONFIG_ACPI -/* -* One spec says "IBFT", the other says "iBFT". We have to check -* for both. -*/ - {ACPI_SIG_IBFT }, -#endif {"iBFT" }, {"BIFT" },/* Broadcom iSCSI Offload */ };
@@ -62,14 +55,6 @@ static const struct {#define VGA_MEM 0xA0000/* VGA buffer */ #define VGA_SIZE 0x20000/* 128kB */ -#ifdef CONFIG_ACPI -static int __init acpi_find_ibft (struct acpi_table_header *header) -{ - ibft_addr = (struct acpi_table_ibft *)header; -return 0 ; -} -#endif /* CONFIG_ACPI */ -static int __init find_ibft_in_mem (void ) {unsigned long pos;
@@ -94,6 +79,7 @@ static int __init find_ibft_in_mem(void)* the table cannot be valid. */ if (pos + len <= (IBFT_END -1 )) { ibft_addr = (struct acpi_table_ibft *)virt; +pr_info ("iBFT found at 0x%lx.\n" , pos); goto done; } }
@@ -108,20 +94,12 @@ done:*/ unsigned long __init find_ibft_region (unsigned long *sizep) { -#ifdef CONFIG_ACPI -int i; -#endif ibft_addr =NULL ; -#ifdef CONFIG_ACPI -for (i =0 ; i <ARRAY_SIZE (ibft_signs) && !ibft_addr; i++) -acpi_table_parse (ibft_signs[i].sign, acpi_find_ibft); -#endif /* CONFIG_ACPI */ -/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will * only use ACPI for this */ -if (!ibft_addr && !efi_enabled) +if (!efi_enabled)find_ibft_in_mem ();if (ibft_addr) {
PATCH 43/45 USB: cdc-acm: add IDs for Motorola H24 HSPA USB module.
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Hałasa <[email protected]>
commit 6abff5dc4d5a2c90e597137ce8987e7fd439259b upstream.
Add USB IDs for Motorola H24 HSPA USB module.
--- drivers/usb/class/cdc-acm.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/usb/class/cdc-acm.c +10 -0
@@ -1458,6 +1458,16 @@ static const struct usb_device_id acm_id }, {USB_DEVICE (0x22b8 ,0x6425 ),/* Motorola MOTOMAGX phones */ }, + /* Motorola H24 HSPA module: */ + { USB_DEVICE(0x22b8, 0x2d91) }, /* modem */ + { USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */ + { USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */ + { USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */ + { USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */ + { USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */ + { USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */ + { USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */ + { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced ondata interface instead of
PATCH 44/45 usb: option: Add Huawei E398 controlling interfaces
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hermann <[email protected]>
commit 414b591fd16655871e9f5592a55368b10a3ccc30 upstream.
This patch adds the controlling interfaces for the Huawei E398.
Thanks to Bjørn Mork <[email protected]> for extracting the interface numbers from the windows driver.
--- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/serial/option.c +3 -0
@@ -660,6 +660,9 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x08) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */ + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */ + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
PATCH 45/45 USB: option: Removing one bogus and adding some new Huawei combinations
In reply to Greg KH3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjørn Mork <[email protected]>
commit 02a551c9755b799579e0a093bcc99b80b4dc1453 upstream.
Huawei use the product code HUAWEI_PRODUCT_E353 (0x1506) for a number of different devices, which each can appear with a number of different descriptor sets. Different types of interfaces can be identified by looking at the subclass and protocol fields
Subclass 1 protocol 8 is actually the data interface of a CDC ECM set, with subclass 1 protocol 9 as the control interface. Neither support serial data communcation, and cannot therefore be supported by this driver.
At the same time, add a few other sets which appear if the device is configured in "Windows mode" using this modeswitch message:
55534243000000000000000000000011060000000100000000000000000000
--- drivers/usb/serial/option.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/serial/option.c +3 -1
@@ -659,7 +659,9 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x08) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */