3.4.83-stable review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 3.4.83-stable review
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.4.83-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 3.4.83-rc1
Emil Goode <[email protected]>
net: asix: add missing flag to struct driver_info
Lucas Stach <[email protected]>
net: asix: handle packets crossing URB boundaries
Mark Cave-Ayland <[email protected]>
rtlwifi: Fix endian error in extracting packet type
Emmanuel Grumbach <[email protected]>
iwlwifi: pcie: add SKUs for 6000, 6005 and 6235 series
Stanislaw Gruszka <[email protected]>
iwlwifi: dvm: fix calling ieee80211_chswitch_done() with NULL
Johannes Berg <[email protected]>
iwlwifi: dvm: don't send BT_CONFIG on devices w/o Bluetooth
Johannes Berg <[email protected]>
iwlwifi: always copy first 16 bytes of commands
Johannes Berg <[email protected]>
iwlwifi: handle DMA mapping failures
Emmanuel Grumbach <[email protected]>
iwlwifi: don't handle masked interrupt
Johannes Berg <[email protected]>
iwlwifi: protect SRAM debugfs
Johannes Berg <[email protected]>
iwlwifi: fix flow handler debug code
Takashi Iwai <[email protected]>
ALSA: asihpi: Fix unlocked snd_pcm_stop() call
Takashi Iwai <[email protected]>
staging: line6: Fix unlocked snd_pcm_stop() call
Takashi Iwai <[email protected]>
ASoC: s6000: Fix unlocked snd_pcm_stop() call
Takashi Iwai <[email protected]>
ALSA: pxa2xx: Fix unlocked snd_pcm_stop() call
Takashi Iwai <[email protected]>
ALSA: usx2y: Fix unlocked snd_pcm_stop() call
Takashi Iwai <[email protected]>
ALSA: ua101: Fix unlocked snd_pcm_stop() call
Takashi Iwai <[email protected]>
ALSA: 6fire: Fix unlocked snd_pcm_stop() call
Takashi Iwai <[email protected]>
ALSA: atiixp: Fix unlocked snd_pcm_stop() call
Fabio Estevam <[email protected]>
ASoC: sglt5000: Fix the default value of CHIP_SSS_CTRL
Sascha Hauer <[email protected]>
ASoC: imx-ssi: Fix occasional AC97 reset failure
Trond Myklebust <[email protected]>
SUNRPC: Prevent an rpc_task wakeup race
Jeff Layton <[email protected]>
sunrpc: clarify comments on rpc_make_runnable
David Vrabel <[email protected]>
xen/events: mask events when changing their VCPU binding
Konrad Rzeszutek Wilk <[email protected]>
xen/blkback: Check for insane amounts of request on the ring (v6).
Jan Beulich <[email protected]>
xen/io/ring.h: new macro to detect whether there are too many requests on the ring
Wei Liu <[email protected]>
xen-netback: don't disconnect frontend when seeing oversize packet
Wei Liu <[email protected]>
xen-netback: coalesce slots in TX path and fix regressions
stephen hemminger <[email protected]>
xen-netback: fix sparse warning
Konrad Rzeszutek Wilk <[email protected]>
xen/smp/spinlock: Fix leakage of the spinlock interrupt line for every CPU online/offline
Konrad Rzeszutek Wilk <[email protected]>
xen/smp: Fix leakage of timer interrupt line for every CPU online/offline.
Konrad Rzeszutek Wilk <[email protected]>
xen/boot: Disable BIOS SMP MP table search.
Takashi Iwai <[email protected]>
saa7134: Fix unlocked snd_pcm_stop() call
Theodore Ts'o <[email protected]>
ext4: return ENOMEM if sb_getblk() fails
Roland Dreier <[email protected]>
block: Don't access request after it might be freed
Paul Clements <[email protected]>
nbd: correct disconnect behavior
Jeff Layton <[email protected]>
cifs: adjust sequence number downward after signing NT_CANCEL request
Jan Kara <[email protected]>
ext4: fix possible use-after-free with AIO
Adam Thomas <[email protected]>
UBIFS: fix double free of ubifs_orphan objects
Theodore Ts'o <[email protected]>
ext4/jbd2: don't wait (forever) for stale tid caused by wraparound
Dave Chiluk <[email protected]>
ncpfs: fix rmdir returns Device or resource busy
Jeff Layton <[email protected]>
cifs: don't instantiate new dentries in readdir for inodes that need to be revalidated immediately
majianpeng <[email protected]>
libceph: unregister request in __map_request failed and nofail == false
Maxim Patlasov <[email protected]>
fuse: hotfix truncate_pagecache() issue
Miklos Szeredi <[email protected]>
fuse: readdir: check for slash in names
Vyacheslav Dubeyko <[email protected]>
nilfs2: fix issue with race condition of competition between segments for dirty blocks
Jiri Olsa <[email protected]>
perf tools: Fix cache event name generation
Arnaldo Carvalho de Melo <[email protected]>
perf tools: Remove extraneous newline when parsing hardware cache events
Jiang Liu <[email protected]>
mm/hotplug: correctly add new zone to all other nodes' zone lists
Tejun Heo <[email protected]>
cgroup: fix RCU accesses to task->cgroups
Kees Cook <[email protected]>
proc connector: reject unprivileged listener bumps
Greg Edwards <[email protected]>
KVM: IOMMU: hva align mapping page size
Alexander Graf <[email protected]>
KVM: PPC: Emulate dcbf
Christian Borntraeger <[email protected]>
s390/kvm: dont announce RRBM support
Dominik Dingel <[email protected]>
KVM: s390: move kvm_guest_enter,exit closer to sie
Tejun Heo <[email protected]>
cgroup: cgroup_subsys->fork() should be called after the task is added to css_set
Johannes Weiner <[email protected]>
mm: vmscan: fix endless loop in kswapd balancing
Hannes Reinecke <[email protected]>
dm mpath: fix stalls when handling invalid ioctls
Linus Walleij <[email protected]>
dma: ste_dma40: don't dereference free:d descriptor
Jan Kara <[email protected]>
quota: Fix race between dqput() and dquot_scan_active()
Eric Paris <[email protected]>
SELinux: bigendian problems with filename trans rules
Peter Zijlstra <[email protected]>
perf: Fix hotplug splat
Lai Jiangshan <[email protected]>
workqueue: ensure @task is valid across kthread_stop()
Guenter Roeck <[email protected]>
hwmon: (max1668) Fix writing the minimum temperature
Joerg Dorchain <[email protected]>
USB: ftdi_sio: add Cressi Leonardo PID
Aleksander Morgado <[email protected]>
USB: serial: option: blacklist interface 4 for Cinterion PHS8 and PXS8
Lan Tianyu <[email protected]>
ACPI / processor: Rework processor throttling with work_on_cpu()
Hans de Goede <[email protected]>
ACPI / video: Filter the _BCL table for duplicate brightness values
Jean Delvare <[email protected]>
i7core_edac: Fix PCI device reference count
Bjorn Helgaas <[email protected]>
PCI: Enable INTx if BIOS left them disabled
Tejun Heo <[email protected]>
sata_sil: apply MOD15WRITE quirk to TOSHIBA MK2561GSYN
Denis V. Lunev <[email protected]>
ata: enable quirk from jmicron JMB350 for JMB394
Peter Zijlstra <[email protected]>
perf/x86: Fix event scheduling
Laurent Dufour <[email protected]>
powerpc/crashdump : Fix page frame number check in copy_oldmem_page
Tony Breeds <[email protected]>
powerpc/le: Ensure that the 'stop-self' RTAS token is handled correctly
Trond Myklebust <[email protected]>
SUNRPC: Fix races in xs_nospace()
Lars-Peter Clausen <[email protected]>
ASoC: wm8958-dsp: Fix firmware block loading
Takashi Iwai <[email protected]>
ASoC: sta32x: Fix array access overflow
Takashi Iwai <[email protected]>
ASoC: sta32x: Fix wrong enum for limiter2 release rate
Takashi Iwai <[email protected]>
ASoC: wm8770: Fix wrong number of enum items
Clemens Ladisch <[email protected]>
ALSA: usb-audio: work around KEF X300A firmware bug
Florian Westphal <[email protected]>
net: ip, ipv6: handle gso skbs in forwarding path
Florian Westphal <[email protected]>
net: add and use skb_gso_transport_seglen()
Daniel Borkmann <[email protected]>
net: sctp: fix sctp_connectx abi for ia32 emulation/compat mode
Emil Goode <[email protected]>
usbnet: remove generic hard_header_len check
Jiri Bohac <[email protected]>
bonding: 802.3ad: make aggregator_identifier bond-private
Nithin Sujir <[email protected]>
tg3: Fix deadlock in tg3_change_mtu()
Maciej Żenczykowski <[email protected]>
net: fix 'ip rule' iif/oif device rename
Olivier Langlois <[email protected]>
rtlwifi: rtl8192ce: Fix too long disable of IRQs
Olivier Langlois <[email protected]>
rtlwifi: Fix incorrect return from rtl_ps_enable_nic()
Stanislaw Gruszka <[email protected]>
rtl8187: fix regression on MIPS without coherent DMA
Jeff Layton <[email protected]>
cifs: ensure that uncached writes handle unmapped areas correctly
Chen Gang <[email protected]>
avr32: Makefile: add '-D__linux__' flag for gcc-4.4.7 use
Paul Gortmaker <[email protected]>
avr32: fix missing module.h causing build failure in mimc200/fram.c
Vinayak Kale <[email protected]>
ARM: 7957/1: add DSB after icache flush in __flush_icache_all()
Will Deacon <[email protected]>
ARM: 7953/1: mm: ensure TLB invalidation is complete before enabling MMU
Theodore Ts'o <[email protected]>
ext4: don't leave i_crtime.tv_sec uninitialized
Theodore Ts'o <[email protected]>
ext4: fix online resize with a non-standard blocks per group setting
Theodore Ts'o <[email protected]>
ext4: don't try to modify s_flags if the the file system is read-only
-------------
Diffstat:
Makefile | 4 +- arch/arm/include/asm/cacheflush.h | 1 + arch/arm/mm/proc-v6.S | 3 +- arch/arm/mm/proc-v7.S | 2 +- arch/avr32/Makefile | 2 +- arch/avr32/boards/mimc200/fram.c | 1 + arch/powerpc/kernel/crash_dump.c | 8 +- arch/powerpc/kvm/emulate.c | 2 + arch/powerpc/platforms/pseries/hotplug-cpu.c | 22 +- arch/s390/kvm/kvm-s390.c | 14 +- arch/x86/kernel/cpu/perf_event.c | 3 + arch/x86/xen/enlighten.c | 4 + arch/x86/xen/smp.c | 2 + block/blk-exec.c | 12 +- drivers/acpi/processor_throttling.c | 69 +++--- drivers/acpi/video.c | 8 +- drivers/ata/libata-pmp.c | 7 +- drivers/ata/sata_sil.c | 1 + drivers/block/nbd.c | 8 +- drivers/block/xen-blkback/blkback.c | 13 +- drivers/block/xen-blkback/common.h | 2 + drivers/block/xen-blkback/xenbus.c | 2 + drivers/connector/cn_proc.c | 8 + drivers/dma/ste_dma40.c | 4 +- drivers/edac/i7core_edac.c | 9 +- drivers/hwmon/max1668.c | 2 +- drivers/md/dm-mpath.c | 7 +- drivers/media/video/saa7134/saa7134-alsa.c | 2 + drivers/net/bonding/bond_3ad.c | 6 +- drivers/net/bonding/bond_3ad.h | 1 + drivers/net/ethernet/broadcom/tg3.c | 4 +- drivers/net/usb/asix.c | 128 +++++++--- drivers/net/usb/gl620a.c | 4 + drivers/net/usb/mcs7830.c | 5 +- drivers/net/usb/net1080.c | 4 + drivers/net/usb/qmi_wwan.c | 8 +- drivers/net/usb/rndis_host.c | 4 + drivers/net/usb/smsc75xx.c | 4 + drivers/net/usb/smsc95xx.c | 4 + drivers/net/usb/usbnet.c | 25 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 6 + drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-cfg.h | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 5 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 + drivers/net/wireless/iwlwifi/iwl-pci.c | 10 + drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 11 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 37 ++- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 65 ++++- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 27 +- drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | 10 +- drivers/net/wireless/rtlwifi/base.c | 89 +++---- drivers/net/wireless/rtlwifi/ps.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 18 +- drivers/net/wireless/rtlwifi/wifi.h | 6 +- drivers/net/xen-netback/netback.c | 289 ++++++++++++++++++---- drivers/pci/pci.c | 10 + drivers/staging/line6/pcm.c | 5 +- drivers/usb/serial/ftdi_sio.c | 2 + drivers/usb/serial/ftdi_sio_ids.h | 6 + drivers/usb/serial/option.c | 3 +- drivers/xen/events.c | 11 + fs/cifs/file.c | 37 ++- fs/cifs/readdir.c | 8 + fs/cifs/transport.c | 7 + fs/ext4/ext4.h | 2 + fs/ext4/extents.c | 25 +- fs/ext4/fsync.c | 3 +- fs/ext4/indirect.c | 9 +- fs/ext4/inode.c | 14 +- fs/ext4/mmp.c | 2 + fs/ext4/page-io.c | 9 +- fs/ext4/resize.c | 10 +- fs/ext4/super.c | 20 +- fs/ext4/xattr.c | 3 +- fs/fuse/dir.c | 9 +- fs/fuse/file.c | 8 +- fs/fuse/fuse_i.h | 9 + fs/fuse/inode.c | 4 +- fs/jbd2/journal.c | 31 +++ fs/ncpfs/dir.c | 9 - fs/nilfs2/page.c | 2 + fs/nilfs2/segment.c | 11 +- fs/quota/dquot.c | 14 +- fs/ubifs/orphan.c | 5 +- fs/ubifs/ubifs.h | 2 + include/linux/cgroup.h | 53 +++- include/linux/jbd2.h | 1 + include/linux/nbd.h | 1 + include/linux/skbuff.h | 19 ++ include/xen/interface/io/netif.h | 18 ++ include/xen/interface/io/ring.h | 5 + kernel/cgroup.c | 50 ++-- kernel/cgroup_freezer.c | 13 +- kernel/events/core.c | 12 +- kernel/fork.c | 9 +- kernel/workqueue.c | 7 + mm/memory_hotplug.c | 15 +- mm/vmscan.c | 27 +- net/ceph/osd_client.c | 2 + net/core/fib_rules.c | 7 + net/core/skbuff.c | 25 ++ net/ipv4/ip_forward.c | 68 ++++- net/ipv6/ip6_output.c | 13 +- net/sctp/socket.c | 41 ++- net/sunrpc/sched.c | 13 +- net/sunrpc/xprtsock.c | 6 +- security/selinux/ss/policydb.c | 8 +- sound/arm/pxa2xx-pcm-lib.c | 2 + sound/pci/asihpi/asihpi.c | 3 + sound/pci/atiixp.c | 2 + sound/pci/atiixp_modem.c | 2 + sound/soc/codecs/sgtl5000.c | 2 +- sound/soc/codecs/sta32x.c | 74 +++--- sound/soc/codecs/wm8770.c | 4 +- sound/soc/codecs/wm8958-dsp2.c | 2 +- sound/soc/imx/imx-ssi.c | 5 + sound/soc/s6000/s6000-pcm.c | 2 + sound/usb/6fire/pcm.c | 12 +- sound/usb/misc/ua101.c | 14 +- sound/usb/mixer_maps.c | 9 + sound/usb/usx2y/usbusx2yaudio.c | 4 + tools/perf/util/parse-events.c | 2 +- virt/kvm/iommu.c | 4 + 124 files changed, 1363 insertions(+), 483 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/99 ext4: dont try to modify s_flags if the the file system is read-only
3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 23301410972330c0ae9a8afc379ba2005e249cc6 upstream.
If an ext4 file system is created by some tool other than mke2fs (perhaps by someone who has a pathalogical fear of the GPL) that doesn't set one or the other of the EXT2_FLAGS_{UN}SIGNED_HASH flags, and that file system is then mounted read-only, don't try to modify the s_flags field. Otherwise, if dm_verity is in use, the superblock will change, causing an dm_verity failure.
--- fs/ext4/super.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
fs/ext4/super.c +13 -7
@@ -3370,16 +3370,22 @@ static int ext4_fill_super(struct super_for (i =0 ; i <4 ; i++) sbi->s_hash_seed[i] =le32_to_cpu (es->s_hash_seed[i]); sbi->s_def_hash_version = es->s_def_hash_version; - i =le32_to_cpu (es->s_flags); -if (i &EXT2_FLAGS_UNSIGNED_HASH ) - sbi->s_hash_unsigned =3 ; -else if ((i &EXT2_FLAGS_SIGNED_HASH ) ==0 ) { +if (EXT4_HAS_COMPAT_FEATURE (sb,EXT4_FEATURE_COMPAT_DIR_INDEX )) { + i =le32_to_cpu (es->s_flags); +if (i &EXT2_FLAGS_UNSIGNED_HASH ) + sbi->s_hash_unsigned =3 ; +else if ((i &EXT2_FLAGS_SIGNED_HASH ) ==0 ) {#ifdef __CHAR_UNSIGNED__ - es->s_flags |=cpu_to_le32 (EXT2_FLAGS_UNSIGNED_HASH ); - sbi->s_hash_unsigned =3 ; +if (!(sb->s_flags &MS_RDONLY )) + es->s_flags |= +cpu_to_le32 (EXT2_FLAGS_UNSIGNED_HASH ); + sbi->s_hash_unsigned =3 ;#else - es->s_flags |=cpu_to_le32 (EXT2_FLAGS_SIGNED_HASH ); +if (!(sb->s_flags &MS_RDONLY )) + es->s_flags |= +cpu_to_le32 (EXT2_FLAGS_SIGNED_HASH );#endif + } }/* Handle clustersize */
Greg Kroah-Hartman
maintainerPATCH 2/99 ext4: fix online resize with a non-standard blocks per group setting
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 3d2660d0c9c2f296837078c189b68a47f6b2e3b5 upstream.
The set_flexbg_block_bitmap() function assumed that the number of blocks in a blockgroup was sb->blocksize * 8, which is normally true, but not always! Use EXT4_BLOCKS_PER_GROUP(sb) instead, to fix block bitmap corruption after:
mke2fs -t ext4 -g 3072 -i 4096 /dev/vdd 1G
mount -t ext4 /dev/vdd /vdd
resize2fs /dev/vdd 8G
--- fs/ext4/resize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ext4/resize.c +1 -1
@@ -377,7 +377,7 @@ static int set_flexbg_block_bitmap(struc start =ext4_group_first_block_no (sb, group); group -= flex_gd->groups[0 ].group; - count2 = sb->s_blocksize *8 - (block - start); + count2 =EXT4_BLOCKS_PER_GROUP (sb) - (block - start);if (count2 > count) count2 = count;
Greg Kroah-Hartman
maintainerPATCH 3/99 ext4: dont leave i_crtime.tv_sec uninitialized
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 19ea80603715d473600cd993b9987bc97d042e02 upstream.
If the i_crtime field is not present in the inode, don't leave the field uninitialized.
--- fs/ext4/ext4.h | 2 ++ 1 file changed, 2 insertions(+)
fs/ext4/ext4.h +2 -0
@@ -751,6 +751,8 @@ do { \if (EXT4_FITS_IN_INODE (raw_inode, einode, xtime)) \ (einode)->xtime.tv_sec = \ (signed )le32_to_cpu ((raw_inode)->xtime); \ +else \ + (einode)->xtime.tv_sec =0 ; \ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \ext4_decode_extra_time (&(einode)->xtime, \ raw_inode->xtime ## _extra); \
Greg Kroah-Hartman
maintainerPATCH 4/99 ARM: 7953/1: mm: ensure TLB invalidation is complete before enabling MMU
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
commit bae0ca2bc550d1ec6a118fb8f2696f18c4da3d8e upstream.
During __v{6,7}_setup, we invalidate the TLBs since we are about to enable the MMU on return to head.S. Unfortunately, without a subsequent dsb instruction, the invalidation is not guaranteed to have completed by the time we write to the sctlr, potentially exposing us to junk/stale translations cached in the TLB.
This patch reworks the init functions so that the dsb used to ensure completion of cache/predictor maintenance is also used to ensure completion of the TLB invalidation.
--- arch/arm/mm/proc-v6.S | 3 ++- arch/arm/mm/proc-v7.S | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/mm/proc-v6.S +2 -1
@@ -202,7 +202,6 @@ __v6_setup: mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer #ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs mcr p15, 0, r0, c2, c0, 2 @ TTB control register
@@ -212,6 +211,8 @@ __v6_setup: ALT_UP(orr r8, r8, #TTB_FLAGS_UP) mcr p15, 0, r8, c2, c0, 1 @ load TTB1 #endif /* CONFIG_MMU */ + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer and + @ complete invalidations adr r5, v6_crval ldmia r5, {r5, r6} #ifdef CONFIG_CPU_ENDIAN_BE8
arch/arm/mm/proc-v7.S +1 -1
@@ -246,7 +246,6 @@ __v7_setup: 3: mov r10, #0 mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate - dsb #ifdef CONFIG_MMU mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs v7_ttb_setup r10, r4, r8, r5 @ TTBCR, TTBRx setup
@@ -255,6 +254,7 @@ __v7_setup: mcr p15, 0, r5, c10, c2, 0 @ write PRRR mcr p15, 0, r6, c10, c2, 1 @ write NMRR #endif + dsb @ Complete invalidations #ifndef CONFIG_ARM_THUMBEE mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE and r0, r0, #(0xf << 12) @ ThumbEE enabled field
Greg Kroah-Hartman
maintainerPATCH 5/99 ARM: 7957/1: add DSB after icache flush in __flush_icache_all()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vinayak Kale <[email protected]>
commit 39544ac9df20f73e49fc6b9ac19ff533388c82c0 upstream.
Add DSB after icache flush to complete the cache maintenance operation.
--- arch/arm/include/asm/cacheflush.h | 1 + 1 file changed, 1 insertion(+)
arch/arm/include/asm/cacheflush.h +1 -0
@@ -202,6 +202,7 @@ extern void copy_to_user_page(struct vm_static inline void __flush_icache_all (void ) {__flush_icache_preferred (); +dsb (); }#define flush_cache_all () __cpuc_flush_kern_all()
Greg Kroah-Hartman
maintainerPATCH 6/99 avr32: fix missing module.h causing build failure in mimc200/fram.c
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Gortmaker <[email protected]>
commit 5745d6a41a4f4aec29e2ccd591c6fb09ed73a955 upstream.
Causing this:
In file included from arch/avr32/boards/mimc200/fram.c:13:include/linux/miscdevice.h:51: error: field 'list' has incomplete type include/linux/miscdevice.h:55: error: expected specifier-qualifier-list before 'mode_t' arch/avr32/boards/mimc200/fram.c:42: error: 'THIS_MODULE' undeclared here (not in a function)
--- arch/avr32/boards/mimc200/fram.c | 1 + 1 file changed, 1 insertion(+)
arch/avr32/boards/mimc200/fram.c +1 -0
@@ -11,6 +11,7 @@#define FRAM_VERSION "1.0"#include <linux/miscdevice.h> +#include <linux/module.h> #include <linux/proc_fs.h> #include <linux/mm.h> #include <linux/io.h>
Greg Kroah-Hartman
maintainerPATCH 7/99 avr32: Makefile: add -D__linux__ flag for gcc-4.4.7 use
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Gang <[email protected]>
commit 8d80390cfc9434d5aa4fb9e5f9768a66b30cb8a6 upstream.
For avr32 cross compiler, do not define '__linux__' internally, so it will cause issue with allmodconfig.
The related error:
CC [M] fs/coda/psdev.o
In file included from include/linux/coda.h:64,
from fs/coda/psdev.c:45:
include/uapi/linux/coda.h:221: error: expected specifier-qualifier-list before 'u_quad_t'
The related toolchain version (which only download, not re-compile):
[root@gchen linux-next]# /upstream/toolchain/download/avr32-gnu-toolchain-linux_x86/bin/avr32-gcc -v
Using built-in specs.
Target: avr32
Configured with: /data2/home/toolsbuild/jenkins-knuth/workspace/avr32-gnu-toolchain/src/gcc/configure --target=avr32 --host=i686-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/home/toolsbuild/jenkins-knuth/workspace/avr32-gnu-toolchain/avr32-gnu-toolchain-linux_x86 --enable-languages=c,c++ --disable-nls --disable-libssp --disable-libstdcxx-pch --with-dwarf2 --enable-version-specific-runtime-libs --disable-shared --enable-doc --with-mpfr-lib=/home/toolsbuild/jenkins-knuth/workspace/avr32-gnu-toolchain/avr32-gnu-toolchain-linux_x86/lib
--with-mpfr-include=/home/toolsbuild/jenkins-knuth/workspace/avr32-gnu-toolchain/avr32-gnu-toolchain-linux_x86/include --with-gmp=/home/toolsbuild/jenkins-knuth/workspace/avr32-gnu-toolchain/avr32-gnu-toolchain-linux_x86 --with-mpc=/home/toolsbuild/jenkins-knuth/workspace/avr32-gnu-toolchain/avr32-gnu-toolchain-linux_x86 --enable-__cxa_atexit --disable-shared --with-newlib --with-pkgversion=AVR_32_bit_GNU_Toolchain_3.4.2_435 --with-bugurl=http://www .atmel.com/avr
Thread model: single
gcc version 4.4.7 (AVR_32_bit_GNU_Toolchain_3.4.2_435)
--- arch/avr32/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/avr32/Makefile +1 -1
@@ -11,7 +11,7 @@ all: uImage vmlinux.elf KBUILD_DEFCONFIG := atstk1002_defconfig -KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic +KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic -D__linux__ KBUILD_AFLAGS += -mrelax -mno-pic KBUILD_CFLAGS_MODULE += -mno-relax LDFLAGS_vmlinux += --relax
Greg Kroah-Hartman
maintainerPATCH 8/99 cifs: ensure that uncached writes handle unmapped areas correctly
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
commit 5d81de8e8667da7135d3a32a964087c0faf5483f upstream.
It's possible for userland to pass down an iovec via writev() that has a bogus user pointer in it. If that happens and we're doing an uncached write, then we can end up getting less bytes than we expect from the call to iov_iter_copy_from_user. This is CVE-2014-0069
cifs_iovec_write isn't set up to handle that situation however. It'll blindly keep chugging through the page array and not filling those pages with anything useful. Worse yet, we'll later end up with a negative number in wdata->tailsz, which will confuse the sending routines and cause an oops at the very least.
Fix this by having the copy phase of cifs_iovec_write stop copying data in this situation and send the last write as a short one. At the same time, we want to avoid sending a zero-length write to the server, so break out of the loop and set rc to -EFAULT if that happens. This also allows us to handle the case where no address in the iovec is valid.
[Note: Marking this for stable on v3.4+ kernels, but kernels as old as
v2.6.38 may have a similar problem and may need similar fix]
--- fs/cifs/file.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-)
fs/cifs/file.c +34 -3
@@ -2185,7 +2185,7 @@ cifs_iovec_write(struct file *file, cons unsigned long nr_segs, loff_t *poffset) { unsigned long nr_pages, i; -size_t copied, len, cur_len; +size_t bytes, copied, len, cur_len;ssize_t total_written =0 ;loff_t offset;struct iov_iter it;
@@ -2236,14 +2236,45 @@ cifs_iovec_write(struct file *file, cons save_len = cur_len;for (i =0 ; i < nr_pages; i++) { - copied = min_t(const size_t, cur_len, PAGE_SIZE); + bytes = min_t(const size_t, cur_len, PAGE_SIZE); copied =iov_iter_copy_from_user (wdata->pages[i], &it, -0 , copied); +0 , bytes); cur_len -= copied;iov_iter_advance (&it, copied); +/* +* If we didn't copy as much as we expected, then that +* may mean we trod into an unmapped area. Stop copying +* at that point. On the next pass through the big +* loop, we'll likely end up getting a zero-length +* write and bailing out of it. +*/ +if (copied < bytes) +break ; } cur_len = save_len - cur_len; +/* +* If we have no data to send, then that probably means that +* the copy above failed altogether. That's most likely because +* the address in the iovec was bogus. Set the rc to -EFAULT, +* free anything we allocated and bail out. +*/ +if (!cur_len) { +for (i =0 ; i < nr_pages; i++) +put_page (wdata->pages[i]); +kfree (wdata); + rc = -EFAULT ; +break ; + } + +/* +* i + 1 now represents the number of pages we actually used in +* the copy phase above. Bring nr_pages down to that, and free +* any pages that we didn't use. +*/ +for ( ; nr_pages > i +1 ; nr_pages--) +put_page (wdata->pages[nr_pages -1 ]); + wdata->sync_mode =WB_SYNC_ALL ; wdata->nr_pages = nr_pages; wdata->offset = (__u64 )offset;
Greg Kroah-Hartman
maintainerPATCH 9/99 rtl8187: fix regression on MIPS without coherent DMA
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanislaw Gruszka <[email protected]>
commit b6213e413a4e0c66548153516b074df14f9d08e0 upstream.
This patch fixes regression caused by commit a16dad77634 "MIPS: Fix potencial corruption". That commit fixes one corruption scenario in cost of adding another one, which actually start to cause crashes on Yeeloong laptop when rtl8187 driver is used.
For correct DMA read operation on machines without DMA coherence, kernel have to invalidate cache, such it will refill later with new data that device wrote to memory, when that data is needed to process. We can only invalidate full cache line. Hence when cache line includes both dma buffer and some other data (written in cache, but not yet in main memory), the other data can not hit memory due to invalidation. That happen on rtl8187 where struct rtl8187_priv fields are located just before and after small buffers that are passed to USB layer and DMA is performed on them.
To fix the problem we align buffers and reserve space after them to make them match cache line.
This patch does not resolve all possible MIPS problems entirely, for that we have to assure that we always map cache aligned buffers for DMA, what can be complex or even not possible. But patch fixes visible and reproducible regression and seems other possible corruptions do not happen in practice, since Yeeloong laptop works stable without rtl8187 driver.
Bug report:
https://bugzilla.kernel.org/show_bug.cgi?id=54391
--- drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +8 -2
@@ -15,6 +15,8 @@#ifndef RTL8187_H #define RTL8187_H +#include <linux/cache.h> +#include "rtl818x.h" #include "leds.h"
@@ -139,7 +141,10 @@ struct rtl8187_priv {u8 aifsn[4 ];u8 rfkill_mask;struct { -__le64 buf; +union { +__le64 buf; +u8 dummy1[L1_CACHE_BYTES ]; + }____cacheline_aligned ;struct sk_buff_head queue; } b_tx_status;/* This queue is used by both -b and non-b devices */ struct mutex io_mutex;
@@ -147,7 +152,8 @@ struct rtl8187_priv {u8 bits8;__le16 bits16;__le32 bits32; - } *io_dmabuf; +u8 dummy2[L1_CACHE_BYTES ]; + } *io_dmabuf____cacheline_aligned ;bool rfkill_off;u16 seqno; };
Greg Kroah-Hartman
maintainerPATCH 10/99 rtlwifi: Fix incorrect return from rtl_ps_enable_nic()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olivier Langlois <[email protected]>
commit 2e8c5e56b307271c2dab6f8bfd1d8a3822ca2390 upstream.
rtl_ps_enable_nic() is called from loops that will loop until this function returns true or a maximum number of retries is performed.
hw_init() returns non-zero on error. In that situation return false to restore the original design intent to retry hw init when it fails.
--- drivers/net/wireless/rtlwifi/ps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/rtlwifi/ps.c +1 -1
@@ -48,7 +48,7 @@ bool rtl_ps_enable_nic(struct ieee80211_/*<2> Enable Adapter */ if (rtlpriv->cfg->ops->hw_init (hw)) -return 1 ; +return false;RT_CLEAR_PS_LEVEL (ppsc,RT_RF_OFF_LEVL_HALT_NIC );/*<3> Enable Interrupt */
Greg Kroah-Hartman
maintainerPATCH 11/99 rtlwifi: rtl8192ce: Fix too long disable of IRQs
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olivier Langlois <[email protected]>
commit f78bccd79ba3cd9d9664981b501d57bdb81ab8a4 upstream.
rtl8192ce is disabling for too long the local interrupts during hw initiatialisation when performing scans
The observable symptoms in dmesg can be:
- underruns from ALSA playback
- clock freezes (tstamps do not change for several dmesg entries until irqs are finaly reenabled):
[ 250.817669] rtlwifi:rtl_op_config():<0-0-0> 0x100 [ 250.817685] rtl8192ce:_rtl92ce_phy_set_rf_power_state():<0-1-0> IPS Set eRf nic enable [ 250.817732] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.817796] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.817910] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.818024] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.818139] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.818253] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.818367] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:18051d59:11 [ 250.818472] rtl8192ce:_rtl92ce_init_mac():<0-1-0> reg0xec:98053f15:10 [ 250.818472] rtl8192ce:rtl92ce_sw_led_on():<0-1-0> LedAddr:4E ledpin=1 [ 250.818472] rtl8192c_common:rtl92c_download_fw():<0-1-0> Firmware Version(49), Signature(0x88c1),Size(32) [ 250.818472] rtl8192ce:rtl92ce_enable_hw_security_config():<0-1-0> PairwiseEncAlgorithm = 0 GroupEncAlgorithm = 0 [ 250.818472] rtl8192ce:rtl92ce_enable_hw_security_config():<0-1-0> The SECR-value cc [ 250.818472] rtl8192c_common:rtl92c_dm_check_txpower_tracking_thermal_meter():<0-1-0> Schedule TxPowerTracking direct call!! [ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> rtl92c_dm_txpower_tracking_callback_thermalmeter [ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Readback Thermal Meter = 0xe pre thermal meter 0xf eeprom_thermalmeter 0xf [ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Initial pathA ele_d reg0xc80 = 0x40000000, ofdm_index=0xc [ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Initial reg0xa24 = 0x90e1317, cck_index=0xc, ch14 0 [ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> Readback Thermal Meter = 0xe pre thermal meter 0xf eeprom_thermalmeter 0xf delta 0x1 delta_lck 0x0 delta_iqk 0x0 [ 250.818472] rtl8192c_common:rtl92c_dm_txpower_tracking_callback_thermalmeter():<0-1-0> <=== [ 250.818472] rtl8192c_common:rtl92c_dm_initialize_txpower_tracking_thermalmeter():<0-1-0> pMgntInfo->txpower_tracking = 1 [ 250.818472] rtl8192ce:rtl92ce_led_control():<0-1-0> ledaction 3 [ 250.818472] rtl8192ce:rtl92ce_sw_led_on():<0-1-0> LedAddr:4E ledpin=1 [ 250.818472] rtlwifi:rtl_ips_nic_on():<0-1-0> before spin_unlock_irqrestore [ 251.154656] PCM: Lost interrupts? [Q]-0 (stream=0, delta=15903, new_hw_ptr=293408, old_hw_ptr=277505)
The exact code flow that causes that is:
1. wpa_supplicant send a start_scan request to the nl80211 driver
2. mac80211 module call rtl_op_config with IEEE80211_CONF_CHANGE_IDLE
3. rtl_ips_nic_on is called which disable local irqs
4. rtl92c_phy_set_rf_power_state() is called
5. rtl_ps_enable_nic() is called and hw_init()is executed and then the interrupts on the device are enabled
A good solution could be to refactor the code to avoid calling rtl92ce_hw_init() with the irqs disabled but a quick and dirty solution that has proven to work is
to reenable the irqs during the function rtl92ce_hw_init().
I think that it is safe doing so since the device interrupt will only be enabled after the init function succeed.
--- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +16 -2
@@ -902,14 +902,26 @@ int rtl92ce_hw_init(struct ieee80211_hwbool is92c;int err;u8 tmp_u1b; +unsigned long flags; rtlpci->being_init_adapter = true; + +/* Since this function can take a very long time (up to 350 ms) +* and can be called with irqs disabled, reenable the irqs +* to let the other devices continue being serviced. +* +* It is safe doing so since our own interrupts will only be enabled +* in a subsequent step. +*/ +local_save_flags (flags); +local_irq_enable (); + rtlpriv->intf_ops->disable_aspm (hw); rtstatus =_rtl92ce_init_mac (hw);if (!rtstatus) {RT_TRACE (rtlpriv,COMP_ERR ,DBG_EMERG ,"Init MAC failed\n" ); err =1 ; -return err; + goto exit; } err =rtl92c_download_fw (hw);
@@ -917,7 +929,7 @@ int rtl92ce_hw_init(struct ieee80211_hwRT_TRACE (rtlpriv,COMP_ERR ,DBG_WARNING ,"Failed to download FW. Init HW without FW now..\n" ); err =1 ; -return err; + goto exit; } rtlhal->last_hmeboxnum =0 ;
@@ -978,6 +990,8 @@ int rtl92ce_hw_init(struct ieee80211_hwRT_TRACE (rtlpriv,COMP_INIT ,DBG_TRACE ,"under 1.5V\n" ); }rtl92c_dm_init (hw); +exit: +local_irq_restore (flags); rtlpci->being_init_adapter = false;return err; }
Greg Kroah-Hartman
maintainerPATCH 13/99 tg3: Fix deadlock in tg3_change_mtu()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nithin Sujir <[email protected]>
[ Upstream commit c6993dfd7db9b0c6b7ca7503a56fda9236a4710f ]
Quoting David Vrabel -
"5780 cards cannot have jumbo frames and TSO enabled together. When jumbo frames are enabled by setting the MTU, the TSO feature must be cleared. This is done indirectly by calling netdev_update_features() which will call tg3_fix_features() to actually clear the flags.
netdev_update_features() will also trigger a new netlink message for the feature change event which will result in a call to tg3_get_stats64() which deadlocks on the tg3 lock."
tg3_set_mtu() does not need to be under the tg3 lock since converting the flags to use set_bit(). Move it out to after tg3_netif_stop().
--- drivers/net/ethernet/broadcom/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +2 -2
@@ -12343,12 +12343,12 @@ static int tg3_change_mtu(struct net_devtg3_netif_stop (tp); +tg3_set_mtu (dev, tp, new_mtu); +tg3_full_lock (tp,1 );tg3_halt (tp,RESET_KIND_SHUTDOWN ,1 ); -tg3_set_mtu (dev, tp, new_mtu); -/* Reset PHY, otherwise the read DMA engine will be in a mode that * breaks all requests to 256 bytes. */
Greg Kroah-Hartman
maintainerPATCH 14/99 bonding: 802.3ad: make aggregator_identifier bond-private
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Bohac <[email protected]>
[ Upstream commit 163c8ff30dbe473abfbb24a7eac5536c87f3baa9 ]
aggregator_identifier is used to assign unique aggregator identifiers to aggregators of a bond during device enslaving.
aggregator_identifier is currently a global variable that is zeroed in bond_3ad_initialize().
This sequence will lead to duplicate aggregator identifiers for eth1 and eth3:
create bond0
change bond0 mode to 802.3ad
enslave eth0 to bond0 //eth0 gets agg id 1
enslave eth1 to bond0 //eth1 gets agg id 2
create bond1
change bond1 mode to 802.3ad
enslave eth2 to bond1 //aggregator_identifier is reset to 0
//eth2 gets agg id 1
enslave eth3 to bond0 //eth3 gets agg id 2
Fix this by making aggregator_identifier private to the bond.
--- drivers/net/bonding/bond_3ad.c | 6 ++---- drivers/net/bonding/bond_3ad.h | 1 + 2 files changed, 3 insertions(+), 4 deletions(-)
drivers/net/bonding/bond_3ad.c +2 -4
@@ -1854,8 +1854,6 @@ void bond_3ad_initiate_agg_selection(strBOND_AD_INFO (bond).agg_select_timer = timeout; } -static u16 aggregator_identifier; -/** * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures * @bond: bonding struct to work on
@@ -1869,7 +1867,7 @@ void bond_3ad_initialize(struct bondingif (MAC_ADDRESS_COMPARE (&(BOND_AD_INFO (bond).system.sys_mac_addr), bond->dev->dev_addr)) { - aggregator_identifier =0 ; +BOND_AD_INFO (bond).aggregator_identifier =0 ;BOND_AD_INFO (bond).system.sys_priority =0xFFFF ;BOND_AD_INFO (bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr);
@@ -1941,7 +1939,7 @@ int bond_3ad_bind_slave(struct slave *slad_initialize_agg (aggregator); aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr); - aggregator->aggregator_identifier = (++aggregator_identifier); + aggregator->aggregator_identifier = ++BOND_AD_INFO (bond).aggregator_identifier; aggregator->slave = slave; aggregator->is_active =0 ; aggregator->num_of_ports =0 ;
drivers/net/bonding/bond_3ad.h +1 -0
@@ -253,6 +253,7 @@ struct ad_system {struct ad_bond_info {struct ad_system system;/* 802.3ad system structure */ u32 agg_select_timer;// Timer to select aggregator after all adapter's hand shakes +u16 aggregator_identifier; };struct ad_slave_info {
Greg Kroah-Hartman
maintainerPATCH 15/99 usbnet: remove generic hard_header_len check
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emil Goode <[email protected]>
[ Upstream commit eb85569fe2d06c2fbf4de7b66c263ca095b397aa ]
This patch removes a generic hard_header_len check from the usbnet module that is causing dropped packages under certain circumstances for devices that send rx packets that cross urb boundaries.
One example is the AX88772B which occasionally send rx packets that cross urb boundaries where the remaining partial packet is sent with no hardware header. When the buffer with a partial packet is of less number of octets than the value of hard_header_len the buffer is discarded by the usbnet module.
With AX88772B this can be reproduced by using ping with a packet size between 1965-1976.
The bug has been reported here:
https://bugzilla.kernel.org/show_bug.cgi?id=29082
This patch introduces the following changes:
- Removes the generic hard_header_len check in the rx_complete function in the usbnet module.
- Introduces a ETH_HLEN check for skbs that are not cloned from within a rx_fixup callback.
- For safety a hard_header_len check is added to each rx_fixup callback function that could be affected by this change. These extra checks could possibly be removed by someone who has the hardware to test.
- Removes a call to dev_kfree_skb_any() and instead utilizes the dev->done list to queue skbs for cleanup.
The changes place full responsibility on the rx_fixup callback functions that clone skbs to only pass valid skbs to the usbnet_skb_return function.
--- drivers/net/usb/gl620a.c | 4 ++++ drivers/net/usb/mcs7830.c | 5 +++-- drivers/net/usb/net1080.c | 4 ++++ drivers/net/usb/qmi_wwan.c | 8 ++++---- drivers/net/usb/rndis_host.c | 4 ++++ drivers/net/usb/smsc75xx.c | 4 ++++ drivers/net/usb/smsc95xx.c | 4 ++++ drivers/net/usb/usbnet.c | 25 ++++++++++--------------- 8 files changed, 37 insertions(+), 21 deletions(-)
drivers/net/usb/gl620a.c +4 -0
@@ -86,6 +86,10 @@ static int genelink_rx_fixup(struct usbnu32 size;u32 count; +/* This check is no longer done by usbnet */ +if (skb->len < dev->net->hard_header_len) +return 0 ; + header = (struct gl_header *) skb->data;// get the packet count of the received skb
drivers/net/usb/mcs7830.c +3 -2
@@ -601,8 +601,9 @@ static int mcs7830_rx_fixup(struct usbne {u8 status; -if (skb->len ==0 ) { -dev_err (&dev->udev->dev,"unexpected empty rx frame\n" ); +/* This check is no longer done by usbnet */ +if (skb->len < dev->net->hard_header_len) { +dev_err (&dev->udev->dev,"unexpected tiny rx frame\n" );return 0 ; }
drivers/net/usb/net1080.c +4 -0
@@ -419,6 +419,10 @@ static int net1080_rx_fixup(struct usbnestruct nc_trailer *trailer;u16 hdr_len, packet_len; +/* This check is no longer done by usbnet */ +if (skb->len < dev->net->hard_header_len) +return 0 ; +if (!(skb->len &0x01 )) {#ifdef DEBUG struct net_device *net = dev->net;
drivers/net/usb/qmi_wwan.c +4 -4
@@ -202,10 +202,10 @@ static int qmi_wwan_rx_fixup(struct usbn {__be16 proto; -/* usbnet rx_complete guarantees that skb->len is at least -* hard_header_len, so we can inspect the dest address without -* checking skb->len -*/ +/* This check is no longer done by usbnet */ +if (skb->len < dev->net->hard_header_len) +return 0 ; +switch (skb->data[0 ] &0xf0 ) {case 0x40 : proto =htons (ETH_P_IP );
drivers/net/usb/rndis_host.c +4 -0
@@ -490,6 +490,10 @@ EXPORT_SYMBOL_GPL(rndis_unbind);*/ int rndis_rx_fixup (struct usbnet *dev,struct sk_buff *skb) { +/* This check is no longer done by usbnet */ +if (skb->len < dev->net->hard_header_len) +return 0 ; +/* peripheral may have batched packets to us... */ while (likely (skb->len)) {struct rndis_data_hdr *hdr = (void *)skb->data;
drivers/net/usb/smsc75xx.c +4 -0
@@ -1093,6 +1093,10 @@ static void smsc75xx_rx_csum_offload(strstatic int smsc75xx_rx_fixup (struct usbnet *dev,struct sk_buff *skb) { +/* This check is no longer done by usbnet */ +if (skb->len < dev->net->hard_header_len) +return 0 ; +while (skb->len >0 ) {u32 rx_cmd_a, rx_cmd_b, align_count, size;struct sk_buff *ax_skb;
drivers/net/usb/smsc95xx.c +4 -0
@@ -1041,6 +1041,10 @@ static void smsc95xx_rx_csum_offload(strstatic int smsc95xx_rx_fixup (struct usbnet *dev,struct sk_buff *skb) { +/* This check is no longer done by usbnet */ +if (skb->len < dev->net->hard_header_len) +return 0 ; +while (skb->len >0 ) {u32 header, align_count;struct sk_buff *ax_skb;
drivers/net/usb/usbnet.c +10 -15
@@ -415,17 +415,19 @@ static inline void rx_process (struct us }// else network stack removes extra byte if we forced a short packet -if (skb->len) { -/* all data was already cloned from skb inside the driver */ -if (dev->driver_info->flags &FLAG_MULTI_PACKET ) -dev_kfree_skb_any (skb); -else -usbnet_skb_return (dev, skb); +/* all data was already cloned from skb inside the driver */ +if (dev->driver_info->flags &FLAG_MULTI_PACKET ) + goto done; + +if (skb->len <ETH_HLEN ) { + dev->net->stats.rx_errors++; + dev->net->stats.rx_length_errors++; +netif_dbg (dev, rx_err, dev->net,"rx length %d\n" , skb->len); + }else { +usbnet_skb_return (dev, skb);return ; } -netif_dbg (dev, rx_err, dev->net,"drop\n" ); - dev->net->stats.rx_errors++; done:skb_queue_tail (&dev->done, skb); }
@@ -447,13 +449,6 @@ static void rx_complete (struct urb *urbswitch (urb_status) {/* success */ case 0 : -if (skb->len < dev->net->hard_header_len) { - state = rx_cleanup; - dev->net->stats.rx_errors++; - dev->net->stats.rx_length_errors++; -netif_dbg (dev, rx_err, dev->net, -"rx length %d\n" , skb->len); - }break ;/* stalls need manual reset. this is rare ... except that
Greg Kroah-Hartman
maintainerPATCH 16/99 net: sctp: fix sctp_connectx abi for ia32 emulation/compat mode
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit ffd5939381c609056b33b7585fb05a77b4c695f3 ]
SCTP's sctp_connectx() abi breaks for 64bit kernels compiled with 32bit emulation (e.g. ia32 emulation or x86_x32). Due to internal usage of 'struct sctp_getaddrs_old' which includes a struct sockaddr pointer, sizeof(param) check will always fail in kernel as the structure in 64bit kernel space is 4bytes larger than for user binaries compiled in 32bit mode. Thus, applications making use of sctp_connectx() won't be able to run under such circumstances.
Introduce a compat interface in the kernel to deal with such situations by using a 'struct compat_sctp_getaddrs_old' structure where user data is copied into it, and then sucessively transformed into a 'struct sctp_getaddrs_old' structure with the help of compat_ptr(). That fixes sctp_connectx() abi without any changes needed in user space, and lets the SCTP test suite pass when compiled in 32bit and run on 64bit kernels.
--- net/sctp/socket.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-)
net/sctp/socket.c +32 -9
@@ -70,6 +70,7 @@#include <linux/init.h> #include <linux/crypto.h> #include <linux/slab.h> +#include <linux/compat.h> #include <net/ip.h> #include <net/icmp.h>
@@ -1376,11 +1377,19 @@ SCTP_STATIC int sctp_setsockopt_connectx/* * New (hopefully final) interface for the API. * We use the sctp_getaddrs_old structure so that use-space library -* can avoid any unnecessary allocations. The only defferent part +* can avoid any unnecessary allocations. The only different part * is that we store the actual length of the address buffer into the -* addrs_num structure member. That way we can re-use the existing +* addrs_num structure member. That way we can re-use the existing * code. */ +#ifdef CONFIG_COMPAT +struct compat_sctp_getaddrs_old { +sctp_assoc_t assoc_id; +s32 addr_num; +compat_uptr_t addrs;/* struct sockaddr * */ +}; +#endif + SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,char __user *optval,int __user *optlen)
@@ -1389,16 +1398,30 @@ SCTP_STATIC int sctp_getsockopt_connectxsctp_assoc_t assoc_id =0 ;int err =0 ; -if (len <sizeof (param)) -return -EINVAL ; +#ifdef CONFIG_COMPAT +if (is_compat_task ()) { +struct compat_sctp_getaddrs_old param32; -if (copy_from_user (¶m, optval,sizeof (param))) -return -EFAULT ; +if (len <sizeof (param32)) +return -EINVAL ; +if (copy_from_user (¶m32, optval,sizeof (param32))) +return -EFAULT ; - err =__sctp_setsockopt_connectx (sk, - (struct sockaddr __user *)param.addrs, - param.addr_num, &assoc_id); + param.assoc_id = param32.assoc_id; + param.addr_num = param32.addr_num; + param.addrs =compat_ptr (param32.addrs); + } else +#endif + { +if (len <sizeof (param)) +return -EINVAL ; +if (copy_from_user (¶m, optval,sizeof (param))) +return -EFAULT ; + } + err =__sctp_setsockopt_connectx (sk, (struct sockaddr __user *) + param.addrs, param.addr_num, + &assoc_id);if (err ==0 || err == -EINPROGRESS ) {if (copy_to_user (optval, &assoc_id,sizeof (assoc_id)))return -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 17/99 net: add and use skb_gso_transport_seglen()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit de960aa9ab4decc3304959f69533eef64d05d8e8 upstream.
[ no skb_gso_seglen helper in 3.4, leave tbf alone ]
This moves part of Eric Dumazets skb_gso_seglen helper from tbf sched to skbuff core so it may be reused by upcoming ip forwarding path patch.
--- include/linux/skbuff.h | 2 ++ net/core/skbuff.c | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+)
include/linux/skbuff.h +2 -0
@@ -2159,6 +2159,8 @@ extern int skb_shift(struct sk_buextern struct sk_buff *skb_segment (struct sk_buff *skb,netdev_features_t features); +unsigned int skb_gso_transport_seglen (const struct sk_buff *skb); +static inline void *skb_header_pointer (const struct sk_buff *skb,int offset,int len,void *buffer) {
net/core/skbuff.c +25 -0
@@ -45,6 +45,8 @@#include <linux/in.h> #include <linux/inet.h> #include <linux/slab.h> +#include <linux/tcp.h> +#include <linux/udp.h> #include <linux/netdevice.h> #ifdef CONFIG_NET_CLS_ACT #include <net/pkt_sched.h>
@@ -3281,3 +3283,26 @@ void __skb_warn_lro_forwarding(const str " while LRO is enabled\n", skb->dev->name); }EXPORT_SYMBOL (__skb_warn_lro_forwarding); + +/** +* skb_gso_transport_seglen - Return length of individual segments of a gso packet +* +* @skb: GSO skb +* +* skb_gso_transport_seglen is used to determine the real size of the +* individual segments, including Layer4 headers (TCP/UDP). +* +* The MAC/L2 or network (IP, IPv6) headers are not accounted for. +*/ +unsigned int skb_gso_transport_seglen (const struct sk_buff *skb) +{ +const struct skb_shared_info *shinfo =skb_shinfo (skb); +unsigned int hdr_len; + +if (likely (shinfo->gso_type & (SKB_GSO_TCPV4 |SKB_GSO_TCPV6 ))) + hdr_len =tcp_hdrlen (skb); +else + hdr_len =sizeof (struct udphdr ); +return hdr_len + shinfo->gso_size; +} +EXPORT_SYMBOL_GPL (skb_gso_transport_seglen);
Greg Kroah-Hartman
maintainerPATCH 18/99 net: ip, ipv6: handle gso skbs in forwarding path
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit fe6cc55f3a9a053482a76f5a6b2257cee51b4663 upstream.
[ use zero netdev_feature mask to avoid backport of
netif_skb_dev_features function ]
Marcelo Ricardo Leitner reported problems when the forwarding link path has a lower mtu than the incoming one if the inbound interface supports GRO.
Given:
Host <mtu1500> R1 <mtu1200> R2
Host sends tcp stream which is routed via R1 and R2. R1 performs GRO.
In this case, the kernel will fail to send ICMP fragmentation needed messages (or pkt too big for ipv6), as GSO packets currently bypass dstmtu checks in forward path. Instead, Linux tries to send out packets exceeding the mtu.
When locking route MTU on Host (i.e., no ipv4 DF bit set), R1 does not fragment the packets when forwarding, and again tries to send out packets exceeding R1-R2 link mtu.
This alters the forwarding dstmtu checks to take the individual gso segment lengths into account.
For ipv6, we send out pkt too big error for gso if the individual segments are too big.
For ipv4, we either send icmp fragmentation needed, or, if the DF bit is not set, perform software segmentation and let the output path create fragments when the packet is leaving the machine.
It is not 100% correct as the error message will contain the headers of the GRO skb instead of the original/segmented one, but it seems to work fine in my (limited) tests.
Eric Dumazet suggested to simply shrink mss via ->gso_size to avoid sofware segmentation.
However it turns out that skb_segment() assumes skb nr_frags is related to mss size so we would BUG there. I don't want to mess with it considering Herbert and Eric disagree on what the correct behavior should be.
Hannes Frederic Sowa notes that when we would shrink gso_size skb_segment would then also need to deal with the case where SKB_MAX_FRAGS would be exceeded.
This uses sofware segmentation in the forward path when we hit ipv4 non-DF packets and the outgoing link mtu is too small. Its not perfect, but given the lack of bug reports wrt. GRO fwd being broken this is a rare case anyway. Also its not like this could not be improved later once the dust settles.
--- include/linux/skbuff.h | 17 ++++++++++++ net/ipv4/ip_forward.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++-- net/ipv6/ip6_output.c | 13 ++++++++- 3 files changed, 95 insertions(+), 3 deletions(-)
include/linux/skbuff.h +17 -0
@@ -2582,5 +2582,22 @@ static inline bool skb_is_recycleable(coreturn true; } + +/** +* skb_gso_network_seglen - Return length of individual segments of a gso packet +* +* @skb: GSO skb +* +* skb_gso_network_seglen is used to determine the real size of the +* individual segments, including Layer3 (IP, IPv6) and L4 headers (TCP/UDP). +* +* The MAC/L2 header is not accounted for. +*/ +static inline unsigned int skb_gso_network_seglen (const struct sk_buff *skb) +{ +unsigned int hdr_len =skb_transport_header (skb) - +skb_network_header (skb); +return hdr_len +skb_gso_transport_seglen (skb); +}#endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */
net/ipv4/ip_forward.c +66 -2
86 lines not on this page · raw message
net/ipv6/ip6_output.c +12 -1
@@ -382,6 +382,17 @@ static inline int ip6_forward_finish(strreturn dst_output (skb); } +static bool ip6_pkt_too_big (const struct sk_buff *skb,unsigned int mtu) +{ +if (skb->len <= mtu || skb->local_df) +return false; + +if (skb_is_gso (skb) &&skb_gso_network_seglen (skb) <= mtu) +return false; + +return true; +} +int ip6_forward (struct sk_buff *skb) {struct dst_entry *dst =skb_dst (skb);
@@ -503,7 +514,7 @@ int ip6_forward(struct sk_buff *skb)if (mtu <IPV6_MIN_MTU ) mtu =IPV6_MIN_MTU ; -if (skb->len > mtu && !skb_is_gso (skb)) { +if (ip6_pkt_too_big (skb, mtu)) {/* Again, force OUTPUT device used as source address */ skb->dev = dst->dev;icmpv6_send (skb,ICMPV6_PKT_TOOBIG ,0 , mtu);
Greg Kroah-Hartman
maintainerPATCH 19/99 ALSA: usb-audio: work around KEF X300A firmware bug
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Clemens Ladisch <[email protected]>
commit 624aef494f86ed0c58056361c06347ad62b26806 upstream.
When the driver tries to access Function Unit 10, the KEF X300A speakers' firmware apparently locks up, making even PCM streaming impossible. Work around this by ignoring this FU.
--- sound/usb/mixer_maps.c | 9 +++++++++ 1 file changed, 9 insertions(+)
sound/usb/mixer_maps.c +9 -0
@@ -304,6 +304,11 @@ static struct usbmix_name_map hercules_u { 0 } /* terminator */ }; +static const struct usbmix_name_map kef_x300a_map[] = { + {10 ,NULL },/* firmware locks up (?) when we try to access this FU */ + {0 } +}; +/* * Control map entries */
@@ -371,6 +376,10 @@ static struct usbmix_ctl_map usbmix_ctl_ .map = scratch_live_map, .ignore_ctl_error = 1, }, + { + .id = USB_ID(0x27ac, 0x1000), + .map = kef_x300a_map, + }, { 0 } /* terminator */ };
Greg Kroah-Hartman
maintainerPATCH 20/99 ASoC: wm8770: Fix wrong number of enum items
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 7a6c0a58dc824523966f212c76322d47c5b0e6fe upstream.
wm8770 codec driver defines ain_enum with a wrong number of items.
Use SOC_ENUM_DOUBLE_DECL() macro and it's automatically fixed.
--- sound/soc/codecs/wm8770.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/wm8770.c +2 -2
@@ -162,8 +162,8 @@ static const char *ain_text[] = {"AIN5" ,"AIN6" ,"AIN7" ,"AIN8" }; -static const struct soc_enum ain_enum = -SOC_ENUM_DOUBLE (WM8770_ADCMUX ,0 ,4 ,8 , ain_text); +static SOC_ENUM_DOUBLE_DECL(ain_enum, + WM8770_ADCMUX, 0, 4, ain_text);static const struct snd_kcontrol_new ain_mux =SOC_DAPM_ENUM ("Capture Mux" , ain_enum);
Greg Kroah-Hartman
maintainerPATCH 22/99 ASoC: sta32x: Fix array access overflow
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 025c3fa9256d4c54506b7a29dc3befac54f5c68d upstream.
Preset EQ enum of sta32x codec driver declares too many number of items and it may lead to the access over the actual array size.
Use SOC_ENUM_SINGLE_DECL() helper and it's automatically fixed.
--- sound/soc/codecs/sta32x.c | 72 +++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 36 deletions(-)
sound/soc/codecs/sta32x.c +36 -36
@@ -147,42 +147,42 @@ static const unsigned int sta32x_limiter 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), }; -static const struct soc_enum sta32x_drc_ac_enum = -SOC_ENUM_SINGLE (STA32X_CONFD ,STA32X_CONFD_DRC_SHIFT , -2 , sta32x_drc_ac); -static const struct soc_enum sta32x_auto_eq_enum = -SOC_ENUM_SINGLE (STA32X_AUTO1 ,STA32X_AUTO1_AMEQ_SHIFT , -3 , sta32x_auto_eq_mode); -static const struct soc_enum sta32x_auto_gc_enum = -SOC_ENUM_SINGLE (STA32X_AUTO1 ,STA32X_AUTO1_AMGC_SHIFT , -4 , sta32x_auto_gc_mode); -static const struct soc_enum sta32x_auto_xo_enum = -SOC_ENUM_SINGLE (STA32X_AUTO2 ,STA32X_AUTO2_XO_SHIFT , -16 , sta32x_auto_xo_mode); -static const struct soc_enum sta32x_preset_eq_enum = -SOC_ENUM_SINGLE (STA32X_AUTO3 ,STA32X_AUTO3_PEQ_SHIFT , -32 , sta32x_preset_eq_mode); -static const struct soc_enum sta32x_limiter_ch1_enum = -SOC_ENUM_SINGLE (STA32X_C1CFG , STA32X_CxCFG_LS_SHIFT, -3 , sta32x_limiter_select); -static const struct soc_enum sta32x_limiter_ch2_enum = -SOC_ENUM_SINGLE (STA32X_C2CFG , STA32X_CxCFG_LS_SHIFT, -3 , sta32x_limiter_select); -static const struct soc_enum sta32x_limiter_ch3_enum = -SOC_ENUM_SINGLE (STA32X_C3CFG , STA32X_CxCFG_LS_SHIFT, -3 , sta32x_limiter_select); -static const struct soc_enum sta32x_limiter1_attack_rate_enum = -SOC_ENUM_SINGLE (STA32X_L1AR , STA32X_LxA_SHIFT, -16 , sta32x_limiter_attack_rate); -static const struct soc_enum sta32x_limiter2_attack_rate_enum = -SOC_ENUM_SINGLE (STA32X_L2AR , STA32X_LxA_SHIFT, -16 , sta32x_limiter_attack_rate); -static const struct soc_enum sta32x_limiter1_release_rate_enum = -SOC_ENUM_SINGLE (STA32X_L1AR , STA32X_LxR_SHIFT, -16 , sta32x_limiter_release_rate); -static const struct soc_enum sta32x_limiter2_release_rate_enum = -SOC_ENUM_SINGLE (STA32X_L2AR , STA32X_LxR_SHIFT, -16 , sta32x_limiter_release_rate); +static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum, + STA32X_CONFD, STA32X_CONFD_DRC_SHIFT, + sta32x_drc_ac); +static SOC_ENUM_SINGLE_DECL(sta32x_auto_eq_enum, + STA32X_AUTO1, STA32X_AUTO1_AMEQ_SHIFT, + sta32x_auto_eq_mode); +static SOC_ENUM_SINGLE_DECL(sta32x_auto_gc_enum, + STA32X_AUTO1, STA32X_AUTO1_AMGC_SHIFT, + sta32x_auto_gc_mode); +static SOC_ENUM_SINGLE_DECL(sta32x_auto_xo_enum, + STA32X_AUTO2, STA32X_AUTO2_XO_SHIFT, + sta32x_auto_xo_mode); +static SOC_ENUM_SINGLE_DECL(sta32x_preset_eq_enum, + STA32X_AUTO3, STA32X_AUTO3_PEQ_SHIFT, + sta32x_preset_eq_mode); +static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch1_enum, + STA32X_C1CFG, STA32X_CxCFG_LS_SHIFT, + sta32x_limiter_select); +static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch2_enum, + STA32X_C2CFG, STA32X_CxCFG_LS_SHIFT, + sta32x_limiter_select); +static SOC_ENUM_SINGLE_DECL(sta32x_limiter_ch3_enum, + STA32X_C3CFG, STA32X_CxCFG_LS_SHIFT, + sta32x_limiter_select); +static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_attack_rate_enum, + STA32X_L1AR, STA32X_LxA_SHIFT, + sta32x_limiter_attack_rate); +static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_attack_rate_enum, + STA32X_L2AR, STA32X_LxA_SHIFT, + sta32x_limiter_attack_rate); +static SOC_ENUM_SINGLE_DECL(sta32x_limiter1_release_rate_enum, + STA32X_L1AR, STA32X_LxR_SHIFT, + sta32x_limiter_release_rate); +static SOC_ENUM_SINGLE_DECL(sta32x_limiter2_release_rate_enum, + STA32X_L2AR, STA32X_LxR_SHIFT, + sta32x_limiter_release_rate);/* byte array controls for setting biquad, mixer, scaling coefficients; * for biquads all five coefficients need to be set in one go,
Greg Kroah-Hartman
maintainerPATCH 23/99 ASoC: wm8958-dsp: Fix firmware block loading
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lars-Peter Clausen <[email protected]>
commit 548da08fc1e245faf9b0d7c41ecd8e07984fc332 upstream.
The codec->control_data contains a pointer to the device's regmap struct. But wm8994_bulk_write() expects a pointer to the parent wm8998 device.
The issue was introduced in commit d9a7666f ("ASoC: Remove ASoC-specific WM8994 I/O code").
--- sound/soc/codecs/wm8958-dsp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/wm8958-dsp2.c +1 -1
@@ -153,7 +153,7 @@ static int wm8958_dsp2_fw(struct snd_soc data32 &=0xffffff ; -wm8994_bulk_write (codec->control_data, +wm8994_bulk_write (wm8994->wm8994, data32 &0xffffff , block_len /2 , (void *)(data +8 ));
Greg Kroah-Hartman
maintainerPATCH 24/99 SUNRPC: Fix races in xs_nospace()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit 06ea0bfe6e6043cb56a78935a19f6f8ebc636226 upstream.
When a send failure occurs due to the socket being out of buffer space, we call xs_nospace() in order to have the RPC task wait until the socket has drained enough to make it worth while trying again. The current patch fixes a race in which the socket is drained before we get round to setting up the machinery in xs_nospace(), and which is reported to cause hangs.
--- net/sunrpc/xprtsock.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/sunrpc/xprtsock.c +5 -1
@@ -501,6 +501,7 @@ static int xs_nospace(struct rpc_task *tstruct rpc_rqst *req = task->tk_rqstp;struct rpc_xprt *xprt = req->rq_xprt; struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); +struct sock *sk = transport->inet;int ret = -EAGAIN ; dprintk("RPC: %5u xmit incomplete (%u left of %u)\n",
@@ -518,7 +519,7 @@ static int xs_nospace(struct rpc_task *t* window size */ set_bit (SOCK_NOSPACE , &transport->sock->flags); - transport->inet->sk_write_pending++; + sk->sk_write_pending++;/* ...and wait for more buffer space */ xprt_wait_for_buffer_space (task, xs_nospace_callback); }
@@ -528,6 +529,9 @@ static int xs_nospace(struct rpc_task *t }spin_unlock_bh (&xprt->transport_lock); + +/* Race breaker in case memory is freed before above code is called */ + sk->sk_write_space (sk);return ret; }
Greg Kroah-Hartman
maintainerPATCH 25/99 powerpc/le: Ensure that the stop-self RTAS token is handled correctly
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tony Breeds <[email protected]>
commit 41dd03a94c7d408d2ef32530545097f7d1befe5c upstream.
Currently we're storing a host endian RTAS token in rtas_stop_self_args.token. We then pass that directly to rtas. This is fine on big endian however on little endian the token is not what we expect.
This will typically result in hitting:
panic("Alas, I survived.\n");To fix this we always use the stop-self token in host order and always convert it to be32 before passing this to rtas.
--- arch/powerpc/platforms/pseries/hotplug-cpu.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
arch/powerpc/platforms/pseries/hotplug-cpu.c +11 -11
@@ -34,12 +34,7 @@#include "offline_states.h" /* This version can't take the spinlock, because it never returns */ -static struct rtas_args rtas_stop_self_args = { - .token =RTAS_UNKNOWN_SERVICE , - .nargs =0 , - .nret =1 , - .rets = &rtas_stop_self_args.args[0 ], -}; +static int rtas_stop_self_token =RTAS_UNKNOWN_SERVICE ; static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) =CPU_STATE_OFFLINE ;
@@ -92,15 +87,20 @@ void set_default_offline_state(int cpu)static void rtas_stop_self (void ) { -struct rtas_args *args = &rtas_stop_self_args; +struct rtas_args args = { + .token =cpu_to_be32 (rtas_stop_self_token), + .nargs =0 , + .nret =1 , + .rets = &args.args[0 ], + };local_irq_disable (); -BUG_ON (args->token ==RTAS_UNKNOWN_SERVICE ); +BUG_ON (rtas_stop_self_token ==RTAS_UNKNOWN_SERVICE );printk ("cpu %u (hwid %u) Ready to die...\n" ,smp_processor_id (),hard_smp_processor_id ()); -enter_rtas (__pa (args)); +enter_rtas (__pa (&args));panic ("Alas, I survived.\n" ); }
@@ -383,10 +383,10 @@ static int __init pseries_cpu_hotplug_in } } - rtas_stop_self_args.token =rtas_token ("stop-self" ); + rtas_stop_self_token =rtas_token ("stop-self" ); qcss_tok =rtas_token ("query-cpu-stopped-state" ); -if (rtas_stop_self_args.token ==RTAS_UNKNOWN_SERVICE || +if (rtas_stop_self_token ==RTAS_UNKNOWN_SERVICE || qcss_tok ==RTAS_UNKNOWN_SERVICE ) {printk (KERN_INFO "CPU Hotplug not supported by firmware " "- disabling.\n" );
Re: [PATCH 3.4 25/99] powerpc/le: Ensure that the stop-self RTAS token is handled correctly
Quoted 2 lines · Greg Kroah-Hartman
3.4-stable review patch. If anyone has any objections, please let me know.
As per Tony request, I've dropped this patch from the 3.5 kernel. Looks like it is applicable to kernels >= 3.10, so I guess you can drop it from 3.4 as well.
Cheers,
--
Lu�s
Quoted 84 lines
------------------
From: Tony Breeds <[email protected]>
commit
41dd03a94c7d408d2ef32530545097f7d1befe5cupstream.Currently we're storing a host endian RTAS token in rtas_stop_self_args.token. We then pass that directly to rtas. This is fine on big endian however on little endian the token is not what we expect.
This will typically result in hitting:
panic("Alas, I survived.\n");To fix this we always use the stop-self token in host order and always convert it to be32 before passing this to rtas.
Signed-off-by Tony Breeds <[email protected]>Signed-off-by Benjamin Herrenschmidt <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- arch/powerpc/platforms/pseries/hotplug-cpu.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)arch/powerpc/platforms/pseries/hotplug-cpu.c +11
-12@@ -34,12 +34,7 @@#include "offline_states.h" /* This version can't take the spinlock, because it never returns */ -static struct rtas_args rtas_stop_self_args = { - .token =RTAS_UNKNOWN_SERVICE , - .nargs =0 , - .nret =1 , - .rets = &rtas_stop_self_args.args[0 ], -}; +static int rtas_stop_self_token =RTAS_UNKNOWN_SERVICE ; static DEFINE_PER_CPU(enum cpu_state_vals, preferred_offline_state) =CPU_STATE_OFFLINE ;@@ -92,15 +87,20 @@ void set_default_offline_state(int cpu)static void rtas_stop_self (void ) { -struct rtas_args *args = &rtas_stop_self_args; +struct rtas_args args = { + .token =cpu_to_be32 (rtas_stop_self_token), + .nargs =0 , + .nret =1 , + .rets = &args.args[0 ], + };local_irq_disable (); -BUG_ON (args->token ==RTAS_UNKNOWN_SERVICE ); +BUG_ON (rtas_stop_self_token ==RTAS_UNKNOWN_SERVICE );printk ("cpu %u (hwid %u) Ready to die...\n" ,smp_processor_id (),hard_smp_processor_id ()); -enter_rtas (__pa (args)); +enter_rtas (__pa (&args));panic ("Alas, I survived.\n" ); }@@ -383,10 +383,10 @@ static int __init pseries_cpu_hotplug_in } } - rtas_stop_self_args.token =rtas_token ("stop-self" ); + rtas_stop_self_token =rtas_token ("stop-self" ); qcss_tok =rtas_token ("query-cpu-stopped-state" ); -if (rtas_stop_self_args.token ==RTAS_UNKNOWN_SERVICE || +if (rtas_stop_self_token ==RTAS_UNKNOWN_SERVICE || qcss_tok ==RTAS_UNKNOWN_SERVICE ) {printk (KERN_INFO "CPU Hotplug not supported by firmware " "- disabling.\n" ); --To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Greg Kroah-Hartman
maintainerRe: [PATCH 3.4 25/99] powerpc/le: Ensure that the stop-self RTAS token is handled correctly
Quoted 7 lines · Luís Henriques
Quoted 2 lines · Greg Kroah-Hartman
3.4-stable review patch. If anyone has any objections, please let me know.
As per Tony request, I've dropped this patch from the 3.5 kernel. Looks like it is applicable to kernels >= 3.10, so I guess you can drop it from 3.4 as well.
Thanks, now dropped.
greg k-h
Greg Kroah-Hartman
maintainerPATCH 26/99 powerpc/crashdump : Fix page frame number check in copy_oldmem_page
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurent Dufour <[email protected]>
commit f5295bd8ea8a65dc5eac608b151386314cb978f1 upstream.
In copy_oldmem_page, the current check using max_pfn and min_low_pfn to decide if the page is backed or not, is not valid when the memory layout is not continuous.
This happens when running as a QEMU/KVM guest, where RTAS is mapped higher in the memory. In that case max_pfn points to the end of RTAS, and a hole between the end of the kdump kernel and RTAS is not backed by PTEs. As a consequence, the kdump kernel is crashing in copy_oldmem_page when accessing in a direct way the pages in that hole.
This fix relies on the memblock's service memblock_is_region_memory to check if the read page is part or not of the directly accessible memory.
--- arch/powerpc/kernel/crash_dump.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
arch/powerpc/kernel/crash_dump.c +5 -3
@@ -108,17 +108,19 @@ ssize_t copy_oldmem_page(unsigned long p size_t csize, unsigned long offset, int userbuf) { void *vaddr; +phys_addr_t paddr;if (!csize)return 0 ; csize =min_t (size_t, csize,PAGE_SIZE ); + paddr = pfn <<PAGE_SHIFT ; -if ((min_low_pfn < pfn) && (pfn < max_pfn)) { - vaddr =__va (pfn <<PAGE_SHIFT ); +if (memblock_is_region_memory (paddr, csize)) { + vaddr =__va (paddr); csize =copy_oldmem_vaddr (vaddr, buf, csize, offset, userbuf); }else { - vaddr =__ioremap (pfn <<PAGE_SHIFT ,PAGE_SIZE ,0 ); + vaddr =__ioremap (paddr,PAGE_SIZE ,0 ); csize =copy_oldmem_vaddr (vaddr, buf, csize, offset, userbuf);iounmap (vaddr); }
Greg Kroah-Hartman
maintainerPATCH 27/99 perf/x86: Fix event scheduling
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
commit 26e61e8939b1fe8729572dabe9a9e97d930dd4f6 upstream.
Vince "Super Tester" Weaver reported a new round of syscall fuzzing (Trinity) failures, with perf WARN_ON()s triggering. He also provided traces of the failures.
This is I think the relevant bit:
> pec_1076_warn-2804 [000] d... 147.926153: x86_pmu_disable: x86_pmu_disable
> pec_1076_warn-2804 [000] d... 147.926153: x86_pmu_state: Events: {
> pec_1076_warn-2804 [000] d... 147.926156: x86_pmu_state: 0: state: .R config: ffffffffffffffff ( (null))
> pec_1076_warn-2804 [000] d... 147.926158: x86_pmu_state: 33: state: AR config: 0 (ffff88011ac99800)
> pec_1076_warn-2804 [000] d... 147.926159: x86_pmu_state: }
> pec_1076_warn-2804 [000] d... 147.926160: x86_pmu_state: n_events: 1, n_added: 0, n_txn: 1
> pec_1076_warn-2804 [000] d... 147.926161: x86_pmu_state: Assignment: {
> pec_1076_warn-2804 [000] d... 147.926162: x86_pmu_state: 0->33 tag: 1 config: 0 (ffff88011ac99800)
> pec_1076_warn-2804 [000] d... 147.926163: x86_pmu_state: }
> pec_1076_warn-2804 [000] d... 147.926166: collect_events: Adding event: 1 (ffff880119ec8800)So we add the insn:p event (fd[23]).
At this point we should have:
n_events = 2, n_added = 1, n_txn = 1
> pec_1076_warn-2804 [000] d... 147.926170: collect_events: Adding event: 0 (ffff8800c9e01800) > pec_1076_warn-2804 [000] d... 147.926172: collect_events: Adding event: 4 (ffff8800cbab2c00)
We try and add the {BP,cycles,br_insn} group (fd[3], fd[4], fd[15]). These events are 0:cycles and 4:br_insn, the BP event isn't x86_pmu so that's not visible.
group_sched_in() pmu->start_txn() /* nop - BP pmu */ event_sched_in() event->pmu->add()
So here we should end up with:
0: n_events = 3, n_added = 2, n_txn = 2
4: n_events = 4, n_added = 3, n_txn = 3
But seeing the below state on x86_pmu_enable(), the must have failed, because the 0 and 4 events aren't there anymore.
Looking at group_sched_in(), since the BP is the leader, its event_sched_in() must have succeeded, for otherwise we would not have seen the sibling adds.
But since neither 0 or 4 are in the below state; their event_sched_in() must have failed; but I don't see why, the complete state: 0,0,1:p,4 fits perfectly fine on a core2.
However, since we try and schedule 4 it means the 0 event must have succeeded! Therefore the 4 event must have failed, its failure will have put group_sched_in() into the fail path, which will call:
event_sched_out() event->pmu->del()
on 0 and the BP event.
Now x86_pmu_del() will reduce n_events; but it will not reduce n_added; giving what we see below:
n_event = 2, n_added = 2, n_txn = 2
> pec_1076_warn-2804 [000] d... 147.926177: x86_pmu_enable: x86_pmu_enable
> pec_1076_warn-2804 [000] d... 147.926177: x86_pmu_state: Events: {
> pec_1076_warn-2804 [000] d... 147.926179: x86_pmu_state: 0: state: .R config: ffffffffffffffff ( (null))
> pec_1076_warn-2804 [000] d... 147.926181: x86_pmu_state: 33: state: AR config: 0 (ffff88011ac99800)
> pec_1076_warn-2804 [000] d... 147.926182: x86_pmu_state: }
> pec_1076_warn-2804 [000] d... 147.926184: x86_pmu_state: n_events: 2, n_added: 2, n_txn: 2
> pec_1076_warn-2804 [000] d... 147.926184: x86_pmu_state: Assignment: {
> pec_1076_warn-2804 [000] d... 147.926186: x86_pmu_state: 0->33 tag: 1 config: 0 (ffff88011ac99800)
> pec_1076_warn-2804 [000] d... 147.926188: x86_pmu_state: 1->0 tag: 1 config: 1 (ffff880119ec8800)
> pec_1076_warn-2804 [000] d... 147.926188: x86_pmu_state: }
> pec_1076_warn-2804 [000] d... 147.926190: x86_pmu_enable: S0: hwc->idx: 33, hwc->last_cpu: 0, hwc->last_tag: 1 hwc->state: 0So the problem is that x86_pmu_del(), when called from a group_sched_in() that fails (for whatever reason), and without x86_pmu TXN support (because the leader is !x86_pmu), will corrupt the n_added state.
--- arch/x86/kernel/cpu/perf_event.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kernel/cpu/perf_event.c +3 -0
@@ -1165,6 +1165,9 @@ static void x86_pmu_del(struct perf_evenfor (i =0 ; i < cpuc->n_events; i++) {if (event == cpuc->event_list[i]) { +if (i >= cpuc->n_events - cpuc->n_added) + --cpuc->n_added; +if (x86_pmu.put_event_constraints) x86_pmu.put_event_constraints (cpuc, event);
Greg Kroah-Hartman
maintainerPATCH 28/99 ata: enable quirk from jmicron JMB350 for JMB394
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Denis V. Lunev" <[email protected]>
commit efb9e0f4f43780f0ae0c6428d66bd03e805c7539 upstream.
Without the patch the kernel generates the following error.
ata11.15: SATA link up 1.5 Gbps (SStatus 113 SControl 310) ata11.15: Port Multiplier vendor mismatch '0x197b' != '0x123' ata11.15: PMP revalidation failed (errno=-19) ata11.15: failed to recover PMP after 5 tries, giving up
This patch helps to bypass this error and the device becomes functional.
--- drivers/ata/libata-pmp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/ata/libata-pmp.c +5 -2
@@ -447,8 +447,11 @@ static void sata_pmp_quirks(struct ata_p* otherwise. Don't try hard to recover it. */ ap->pmp_link[ap->nr_pmp_links -1 ].flags |=ATA_LFLAG_NO_RETRY ; - }else if (vendor ==0x197b && devid ==0x2352 ) { -/* chip found in Thermaltake BlackX Duet, jmicron JMB350? */ + }else if (vendor ==0x197b && (devid ==0x2352 || devid ==0x0325 )) { +/* +* 0x2352: found in Thermaltake BlackX Duet, jmicron JMB350? +* 0x0325: jmicron JMB394. +*/ ata_for_each_link (link, ap,EDGE ) {/* SRST breaks detection and disks get misclassified * LPM disabled to avoid potential problems
Greg Kroah-Hartman
maintainerPATCH 29/99 sata_sil: apply MOD15WRITE quirk to TOSHIBA MK2561GSYN
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
commit 9f9c47f00ce99329b1a82e2ac4f70f0fe3db549c upstream.
It's a bit odd to see a newer device showing mod15write; however, the reported behavior is highly consistent and other factors which could contribute seem to have been verified well enough. Also, both sata_sil itself and the drive are fairly outdated at this point making the risk of this change fairly low. It is possible, probably likely, that other drive models in the same family have the same problem; however, for now, let's just add the specific model which was tested.
References: http://lkml.kernel.org/g/[email protected]
--- drivers/ata/sata_sil.c | 1 + 1 file changed, 1 insertion(+)
drivers/ata/sata_sil.c +1 -0
@@ -157,6 +157,7 @@ static const struct sil_drivelist { { "ST380011ASL", SIL_QUIRK_MOD15WRITE }, { "ST3120022ASL", SIL_QUIRK_MOD15WRITE }, { "ST3160021ASL", SIL_QUIRK_MOD15WRITE }, + { "TOSHIBA MK2561GSYN", SIL_QUIRK_MOD15WRITE }, { "Maxtor 4D060H3", SIL_QUIRK_UDMA5MAX }, { } };
Greg Kroah-Hartman
maintainerPATCH 30/99 PCI: Enable INTx if BIOS left them disabled
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjorn Helgaas <[email protected]>
commit 1f42db786b14a31bf807fc41ee5583a00c08fcb1 upstream.
Some firmware leaves the Interrupt Disable bit set even if the device uses INTx interrupts. Clear Interrupt Disable so we get those interrupts.
Based on the report mentioned below, if the user selects the "EHCI only" option in the Intel Baytrail BIOS, the EHCI device is handed off to the OS with the PCI_COMMAND_INTX_DISABLE bit set.
--- drivers/pci/pci.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/pci/pci.c +10 -0
@@ -1133,6 +1133,8 @@ EXPORT_SYMBOL_GPL(pci_load_and_free_savestatic int do_pci_enable_device (struct pci_dev *dev,int bars) {int err; +u16 cmd; +u8 pin; err =pci_set_power_state (dev,PCI_D0 );if (err <0 && err != -EIO )
@@ -1142,6 +1144,14 @@ static int do_pci_enable_device(struct preturn err;pci_fixup_device (pci_fixup_enable, dev); +pci_read_config_byte (dev,PCI_INTERRUPT_PIN , &pin); +if (pin) { +pci_read_config_word (dev,PCI_COMMAND , &cmd); +if (cmd &PCI_COMMAND_INTX_DISABLE ) +pci_write_config_word (dev,PCI_COMMAND , + cmd & ~PCI_COMMAND_INTX_DISABLE ); + } +return 0 ; }
Re: [PATCH 3.4 30/99] PCI: Enable INTx if BIOS left them disabled
[+cc Andreas]
Quoted 1 line · Greg Kroah-Hartman
3.4-stable review patch. If anyone has any objections, please let me know.
Let's hold off on this for a bit. Andreas found that this patch breaks pciehp, and we haven't figured out the best fix yet.
http://lkml.kernel.org/r/CAMxnaaXd9-VbxSYa9q1YVT+fwfDFYKGG2Hq-1jkc-awLX-HwtQ@mail.gmail.com
https://bugzilla.kernel.org/show_bug.cgi?id=71691
Quoted 53 lines
------------------
From: Bjorn Helgaas <[email protected]>
commit
1f42db786b14a31bf807fc41ee5583a00c08fcb1upstream.Some firmware leaves the Interrupt Disable bit set even if the device uses INTx interrupts. Clear Interrupt Disable so we get those interrupts.
Based on the report mentioned below, if the user selects the "EHCI only" option in the Intel Baytrail BIOS, the EHCI device is handed off to the OS with the
PCI_COMMAND_INTX_DISABLEbit set.Reported-by Chris Cheng <[email protected]>Reported-and-tested-by Jamie Chen <[email protected]>Signed-off-by Bjorn Helgaas <[email protected]>CC Sarah Sharp <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/pci/pci.c | 10 ++++++++++ 1 file changed, 10 insertions(+)drivers/pci/pci.c +10
-0@@ -1133,6 +1133,8 @@ EXPORT_SYMBOL_GPL(pci_load_and_free_savestatic int do_pci_enable_device (struct pci_dev *dev,int bars) {int err; +u16 cmd; +u8 pin; err =pci_set_power_state (dev,PCI_D0 );if (err <0 && err != -EIO )@@ -1142,6 +1144,14 @@ static int do_pci_enable_device(struct preturn err;pci_fixup_device (pci_fixup_enable, dev); +pci_read_config_byte (dev,PCI_INTERRUPT_PIN , &pin); +if (pin) { +pci_read_config_word (dev,PCI_COMMAND , &cmd); +if (cmd &PCI_COMMAND_INTX_DISABLE ) +pci_write_config_word (dev,PCI_COMMAND , + cmd & ~PCI_COMMAND_INTX_DISABLE ); + } +return 0 ; }
Greg Kroah-Hartman
maintainerRe: [PATCH 3.4 30/99] PCI: Enable INTx if BIOS left them disabled
Quoted 11 lines · Bjorn Helgaas
[+cc Andreas]
Quoted 1 line · Greg Kroah-Hartman
3.4-stable review patch. If anyone has any objections, please let me know.
Let's hold off on this for a bit. Andreas found that this patch breaks pciehp, and we haven't figured out the best fix yet.
http://lkml.kernel.org/r/CAMxnaaXd9-VbxSYa9q1YVT+fwfDFYKGG2Hq-1jkc-awLX-HwtQ@mail.gmail.com
https://bugzilla.kernel.org/show_bug.cgi?id=71691
Thanks for letting me know, now dropped.
greg k-h
Greg Kroah-Hartman
maintainerPATCH 31/99 i7core_edac: Fix PCI device reference count
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean Delvare <[email protected]>
commit c0f5eeed0f4cef4f05b74883a7160e7edde58b6a upstream.
The reference count changes done by pci_get_device can be a little misleading when the usage diverges from the most common scheme. The reference count of the device passed as the last parameter is always decreased, even if the function returns no new device. So if we are going to try alternative device IDs, we must manually increment the device reference count before each retry. If we don't, we end up decreasing the reference count, and after a few modprobe/rmmod cycles the PCI devices will vanish.
In other words and as Alan put it: without this fix the EDAC code corrupts the PCI device list.
This fixes kernel bug #50491:
https://bugzilla.kernel.org/show_bug.cgi?id=50491
--- drivers/edac/i7core_edac.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/edac/i7core_edac.c +7 -2
@@ -1365,14 +1365,19 @@ static int i7core_get_onedevice(struct p* is at addr 8086:2c40, instead of 8086:2c41. So, we need * to probe for the alternate address in case of failure */ -if (dev_descr->dev_id ==PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) +if (dev_descr->dev_id ==PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) { +pci_dev_get (*prev);/* pci_get_device will put it */ pdev =pci_get_device (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT , *prev); + } -if (dev_descr->dev_id ==PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) +if (dev_descr->dev_id ==PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && + !pdev) { +pci_dev_get (*prev);/* pci_get_device will put it */ pdev =pci_get_device (PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT , *prev); + }if (!pdev) {if (*prev) {
Greg Kroah-Hartman
maintainerPATCH 32/99 ACPI / video: Filter the _BCL table for duplicate brightness values
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit bd8ba20597f0cfef3ef65c3fd2aa92ab23d4c8e1 upstream.
Some devices have duplicate entries in there brightness levels table, ie on my Dell Latitude E6430 the table looks like this:
[ 3.686060] acpi backlight index 0, val 80 [ 3.686095] acpi backlight index 1, val 50 [ 3.686122] acpi backlight index 2, val 5 [ 3.686147] acpi backlight index 3, val 5 [ 3.686172] acpi backlight index 4, val 5 [ 3.686197] acpi backlight index 5, val 5 [ 3.686223] acpi backlight index 6, val 5 [ 3.686248] acpi backlight index 7, val 5 [ 3.686273] acpi backlight index 8, val 6 [ 3.686332] acpi backlight index 9, val 7 [ 3.686356] acpi backlight index 10, val 8 [ 3.686380] acpi backlight index 11, val 9
etc.
Notice that brightness values 0-5 are all mapped to 5. This means that if userspace writes any value between 0 and 5 to the brightness sysfs attribute and then reads it, it will always return 0, which is somewhat unexpected.
This is a problem for ie gnome-settings-daemon, which uses read-modify-write logic when the users presses the brightness up or down keys. This is done this way to take brightness changes from other sources into account.
On this specific laptop what happens once the brightness has been set to 0, is that gsd reads 0, adds 5, writes 5, and on the next brightness up key press again reads 0, so things get stuck at the lowest brightness setting.
Filtering out the duplicate table entries, makes any write to brightness read back as the written value as one would expect, fixing this.
--- drivers/acpi/video.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/acpi/video.c +7 -1
@@ -632,6 +632,7 @@ acpi_video_init_brightness(struct acpi_vunion acpi_object *o;struct acpi_video_device_brightness *br =NULL ;int result = -EINVAL ; +u32 value;if (!ACPI_SUCCESS (acpi_video_device_lcd_query_levels (device, &obj))) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@@ -662,7 +663,12 @@ acpi_video_init_brightness(struct acpi_v printk(KERN_ERR PREFIX "Invalid data\n");continue ; } - br->levels[count] = (u32 ) o->integer.value; + value = (u32 ) o->integer.value; +/* Skip duplicate entries */ +if (count >2 && br->levels[count -1 ] == value) +continue ; + + br->levels[count] = value;if (br->levels[count] > max_level) max_level = br->levels[count];
Greg Kroah-Hartman
maintainerPATCH 33/99 ACPI / processor: Rework processor throttling with work_on_cpu()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lan Tianyu <[email protected]>
commit f3ca4164529b875374c410193bbbac0ee960895f upstream.
acpi_processor_set_throttling() uses set_cpus_allowed_ptr() to make sure that the (struct acpi_processor)->acpi_processor_set_throttling() callback will run on the right CPU. However, the function may be called from a worker thread already bound to a different CPU in which case that won't work.
Make acpi_processor_set_throttling() use work_on_cpu() as appropriate instead of abusing set_cpus_allowed_ptr().
--- drivers/acpi/processor_throttling.c | 69 ++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 37 deletions(-)
drivers/acpi/processor_throttling.c +32 -37
@@ -59,6 +59,12 @@ struct throttling_tstate {int target_state;/* target T-state */ }; +struct acpi_processor_throttling_arg { +struct acpi_processor *pr; +int target_state; +bool force; +}; +#define THROTTLING_PRECHANGE (1)#define THROTTLING_POSTCHANGE (2)
@@ -1062,16 +1068,24 @@ static int acpi_processor_set_throttlingreturn 0 ; } +static long acpi_processor_throttling_fn (void *data) +{ +struct acpi_processor_throttling_arg *arg = data; +struct acpi_processor *pr = arg->pr; + +return pr->throttling.acpi_processor_set_throttling (pr, + arg->target_state, arg->force); +} +int acpi_processor_set_throttling (struct acpi_processor *pr,int state,bool force) { -cpumask_var_t saved_mask;int ret =0 ;unsigned int i;struct acpi_processor *match_pr;struct acpi_processor_throttling *p_throttling; +struct acpi_processor_throttling_arg arg;struct throttling_tstate t_state; -cpumask_var_t online_throttling_cpus;if (!pr)return -EINVAL ;
@@ -1082,14 +1096,6 @@ int acpi_processor_set_throttling(structif ((state <0 ) || (state > (pr->throttling.state_count -1 )))return -EINVAL ; -if (!alloc_cpumask_var (&saved_mask,GFP_KERNEL )) -return -ENOMEM ; - -if (!alloc_cpumask_var (&online_throttling_cpus,GFP_KERNEL )) { -free_cpumask_var (saved_mask); -return -ENOMEM ; - } -if (cpu_is_offline (pr->id)) {/* * the cpu pointed by pr->id is offline. Unnecessary to change
@@ -1098,17 +1104,15 @@ int acpi_processor_set_throttling(structreturn -ENODEV ; } -cpumask_copy (saved_mask, ¤t->cpus_allowed); t_state.target_state = state; p_throttling = &(pr->throttling); -cpumask_and (online_throttling_cpus, cpu_online_mask, - p_throttling->shared_cpu_map); +/* * The throttling notifier will be called for every * affected cpu in order to get one proper T-state. * The notifier event is THROTTLING_PRECHANGE. */ -for_each_cpu (i, online_throttling_cpus) { +for_each_cpu_and (i, cpu_online_mask, p_throttling->shared_cpu_map) { t_state.cpu = i;acpi_processor_throttling_notifier (THROTTLING_PRECHANGE , &t_state);
@@ -1120,21 +1124,18 @@ int acpi_processor_set_throttling(struct* it can be called only for the cpu pointed by pr. */ if (p_throttling->shared_type ==DOMAIN_COORD_TYPE_SW_ANY ) { -/* FIXME: use work_on_cpu() */ -if (set_cpus_allowed_ptr (current,cpumask_of (pr->id))) { -/* Can't migrate to the pr->id CPU. Exit */ - ret = -ENODEV ; - goto exit; - } - ret = p_throttling->acpi_processor_set_throttling (pr, - t_state.target_state, force); + arg.pr = pr; + arg.target_state = state; + arg.force = force; + ret =work_on_cpu (pr->id, acpi_processor_throttling_fn, &arg); }else {/* * When the T-state coordination is SW_ALL or HW_ALL, * it is necessary to set T-state for every affected * cpus. */ -for_each_cpu (i, online_throttling_cpus) { +for_each_cpu_and (i, cpu_online_mask, + p_throttling->shared_cpu_map) { match_pr =per_cpu (processors, i);/* * If the pointer is invalid, we will report the
@@ -1155,13 +1156,12 @@ int acpi_processor_set_throttling(struct "on CPU %d\n", i));continue ; } - t_state.cpu = i; -/* FIXME: use work_on_cpu() */ -if (set_cpus_allowed_ptr (current,cpumask_of (i))) -continue ; - ret = match_pr->throttling. -acpi_processor_set_throttling ( - match_pr, t_state.target_state, force); + + arg.pr = match_pr; + arg.target_state = state; + arg.force = force; + ret =work_on_cpu (pr->id, acpi_processor_throttling_fn, + &arg); } }/*
@@ -1170,17 +1170,12 @@ int acpi_processor_set_throttling(struct* affected cpu to update the T-states. * The notifier event is THROTTLING_POSTCHANGE */ -for_each_cpu (i, online_throttling_cpus) { +for_each_cpu_and (i, cpu_online_mask, p_throttling->shared_cpu_map) { t_state.cpu = i;acpi_processor_throttling_notifier (THROTTLING_POSTCHANGE , &t_state); } -/* restore the previous state */ -/* FIXME: use work_on_cpu() */ -set_cpus_allowed_ptr (current, saved_mask); -exit: -free_cpumask_var (online_throttling_cpus); -free_cpumask_var (saved_mask); +return ret; }
Greg Kroah-Hartman
maintainerPATCH 34/99 USB: serial: option: blacklist interface 4 for Cinterion PHS8 and PXS8
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksander Morgado <[email protected]>
commit 12df84d4a80278a5b1abfec3206795291da52fc9 upstream.
This interface is to be handled by the qmi_wwan driver.
--- drivers/usb/serial/option.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/serial/option.c +2 -1
@@ -1546,7 +1546,8 @@ static const struct usb_device_id option/* Cinterion */ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
Greg Kroah-Hartman
maintainerPATCH 35/99 USB: ftdi_sio: add Cressi Leonardo PID
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joerg Dorchain <[email protected]>
commit 6dbd46c849e071e6afc1e0cad489b0175bca9318 upstream.
Hello,
the following patch adds an entry for the PID of a Cressi Leonardo diving computer interface to kernel 3.13.0.
It is detected as FT232RL.
Works with subsurface.
--- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++ 2 files changed, 8 insertions(+)
drivers/usb/serial/ftdi_sio.c +2 -0
@@ -920,6 +920,8 @@ static struct usb_device_id id_table_com/* Crucible Devices */ { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, +/* Cressi Devices */ + { USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ };
drivers/usb/serial/ftdi_sio_ids.h +6 -0
@@ -1320,3 +1320,9 @@* Manufacturer: Smart GSM Team */ #define FTDI_Z3X_PID 0x0011 + +/* +* Product: Cressi PC Interface +* Manufacturer: Cressi +*/ +#define FTDI_CRESSI_PID 0x87d0
Greg Kroah-Hartman
maintainerPATCH 36/99 hwmon: (max1668) Fix writing the minimum temperature
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
commit 500a91571f0a5d0d3242d83802ea2fd1faccc66e upstream.
When trying to set the minimum temperature, the driver was erroneously writing the maximum temperature into the chip.
--- drivers/hwmon/max1668.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/max1668.c +1 -1
@@ -243,7 +243,7 @@ static ssize_t set_temp_min(struct devic data->temp_min[index] =SENSORS_LIMIT (temp/1000 ,-128 ,127 );if (i2c_smbus_write_byte_data (client,MAX1668_REG_LIML_WR (index), - data->temp_max[index])) + data->temp_min[index])) count = -EIO ;mutex_unlock (&data->update_lock);
Greg Kroah-Hartman
maintainerPATCH 37/99 workqueue: ensure @task is valid across kthread_stop()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lai Jiangshan <[email protected]>
commit 5bdfff96c69a4d5ab9c49e60abf9e070ecd2acbb upstream.
When a kworker should die, the kworkre is notified through WORKER_DIE flag instead of kthread_should_stop(). This, IIRC, is primarily to keep the test synchronized inside worker_pool lock. WORKER_DIE is first set while holding pool->lock, the lock is dropped and kthread_stop() is called.
Unfortunately, this means that there's a slight chance that the target kworker may see WORKER_DIE before kthread_stop() finishes and exits and frees the target task before or during kthread_stop().
Fix it by pinning the target task before setting WORKER_DIE and putting it after kthread_stop() is done.
tj: Improved patch description and comment. Moved pinning above
WORKER_DIE for better signify what it's protecting.
--- kernel/workqueue.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/workqueue.c +7 -0
@@ -1469,12 +1469,19 @@ static void destroy_worker(struct workerif (worker->flags &WORKER_IDLE ) gcwq->nr_idle--; +/* +* Once WORKER_DIE is set, the kworker may destroy itself at any +* point. Pin to ensure the task stays until we're done with it. +*/ +get_task_struct (worker->task); +list_del_init (&worker->entry); worker->flags |=WORKER_DIE ;spin_unlock_irq (&gcwq->lock);kthread_stop (worker->task); +put_task_struct (worker->task);kfree (worker);spin_lock_irq (&gcwq->lock);
Greg Kroah-Hartman
maintainerPATCH 38/99 perf: Fix hotplug splat
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
commit e3703f8cdfcf39c25c4338c3ad8e68891cca3731 upstream.
Drew Richardson reported that he could make the kernel go *boom* when hotplugging while having perf events active.
It turned out that when you have a group event, the code in __perf_event_exit_context() fails to remove the group siblings from the context.
We then proceed with destroying and freeing the event, and when you re-plug the CPU and try and add another event to that CPU, things go *boom* because you've still got dead entries there.
--- kernel/events/core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
kernel/events/core.c +6 -6
@@ -7149,14 +7149,14 @@ static void perf_pmu_rotate_stop(structstatic void __perf_event_exit_context (void *__info) {struct perf_event_context *ctx = __info; -struct perf_event *event, *tmp; +struct perf_event *event;perf_pmu_rotate_stop (ctx->pmu); -list_for_each_entry_safe (event, tmp, &ctx->pinned_groups, group_entry) -__perf_remove_from_context (event); -list_for_each_entry_safe (event, tmp, &ctx->flexible_groups, group_entry) +rcu_read_lock (); +list_for_each_entry_rcu (event, &ctx->event_list, event_entry)__perf_remove_from_context (event); +rcu_read_unlock (); }static void perf_event_exit_cpu_context (int cpu)
@@ -7180,11 +7180,11 @@ static void perf_event_exit_cpu(int cpu) {struct swevent_htable *swhash = &per_cpu (swevent_htable, cpu); +perf_event_exit_cpu_context (cpu); +mutex_lock (&swhash->hlist_mutex);swevent_hlist_release (swhash);mutex_unlock (&swhash->hlist_mutex); - -perf_event_exit_cpu_context (cpu); }#else static inline void perf_event_exit_cpu (int cpu) { }
Greg Kroah-Hartman
maintainerPATCH 39/99 SELinux: bigendian problems with filename trans rules
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Paris <[email protected]>
commit 9085a6422900092886da8c404e1c5340c4ff1cbf upstream.
When writing policy via /sys/fs/selinux/policy I wrote the type and class of filename trans rules in CPU endian instead of little endian. On x86_64 this works just fine, but it means that on big endian arch's like ppc64 and s390 userspace reads the policy and converts it from le32_to_cpu. So the values are all screwed up. Write the values in le format like it should have been to start.
--- security/selinux/ss/policydb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
security/selinux/ss/policydb.c +4 -4
@@ -3214,10 +3214,10 @@ static int filename_write_helper(void *kif (rc)return rc; - buf[0 ] = ft->stype; - buf[1 ] = ft->ttype; - buf[2 ] = ft->tclass; - buf[3 ] = otype->otype; + buf[0 ] =cpu_to_le32 (ft->stype); + buf[1 ] =cpu_to_le32 (ft->ttype); + buf[2 ] =cpu_to_le32 (ft->tclass); + buf[3 ] =cpu_to_le32 (otype->otype); rc =put_entry (buf,sizeof (u32),4 , fp);if (rc)
Greg Kroah-Hartman
maintainerPATCH 40/99 quota: Fix race between dqput() and dquot_scan_active()
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 1362f4ea20fa63688ba6026e586d9746ff13a846 upstream.
Currently last dqput() can race with dquot_scan_active() causing it to call callback for an already deactivated dquot. The race is as follows:
CPU1 CPU2
dqput()
spin_lock(&dq_list_lock);
if (atomic_read(&dquot->dq_count) > 1) {
- not taken
if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
spin_unlock(&dq_list_lock);
->release_dquot(dquot);
if (atomic_read(&dquot->dq_count) > 1)
- not taken
dquot_scan_active()
spin_lock(&dq_list_lock);
if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
- not taken
atomic_inc(&dquot->dq_count);
spin_unlock(&dq_list_lock);
- proceeds to release dquot
ret = fn(dquot, priv);
- called for inactive dquotFix the problem by making sure possible ->release_dquot() is finished by the time we call the callback and new calls to it will notice reference dquot_scan_active() has taken and bail out.
--- fs/quota/dquot.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
fs/quota/dquot.c +11 -3
@@ -580,9 +580,17 @@ int dquot_scan_active(struct super_blockdqstats_inc (DQST_LOOKUPS );dqput (old_dquot); old_dquot = dquot; - ret =fn (dquot, priv); -if (ret <0 ) - goto out; +/* +* ->release_dquot() can be racing with us. Our reference +* protects us from new calls to it so just wait for any +* outstanding call and recheck the DQ_ACTIVE_B after that. +*/ +wait_on_dquot (dquot); +if (test_bit (DQ_ACTIVE_B , &dquot->dq_flags)) { + ret =fn (dquot, priv); +if (ret <0 ) + goto out; + }spin_lock (&dq_list_lock);/* We are safe to continue now because our dquot could not * be moved out of the inuse list while we hold the reference */
Greg Kroah-Hartman
maintainerPATCH 41/99 dma: ste_dma40: dont dereference free:d descriptor
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <[email protected]>
commit e9baa9d9d520fb0e24cca671e430689de2d4a4b2 upstream.
It appears that in the DMA40 driver the DMA tasklet will very often dereference memory for a descriptor just free:d from the DMA40 slab. Nothing happens because no other part of the driver has yet had a chance to claim this memory, but it's really nasty to dereference free:d memory, so let's check the flag before the descriptor is free and store it in a bool variable.
--- drivers/dma/ste_dma40.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/dma/ste_dma40.c +3 -1
@@ -1409,6 +1409,7 @@ static void dma_tasklet(unsigned long dastruct d40_chan *d40c = (struct d40_chan *) data;struct d40_desc *d40d;unsigned long flags; +bool callback_active;dma_async_tx_callback callback;void *callback_param;
@@ -1432,6 +1433,7 @@ static void dma_tasklet(unsigned long da }/* Callback to client */ + callback_active = !!(d40d->txd.flags &DMA_PREP_INTERRUPT ); callback = d40d->txd.callback; callback_param = d40d->txd.callback_param;
@@ -1456,7 +1458,7 @@ static void dma_tasklet(unsigned long daspin_unlock_irqrestore (&d40c->lock, flags); -if (callback && (d40d->txd.flags &DMA_PREP_INTERRUPT )) +if (callback_active && callback)callback (callback_param);return ;
Greg Kroah-Hartman
maintainerPATCH 42/99 dm mpath: fix stalls when handling invalid ioctls
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke <[email protected]>
commit a1989b330093578ea5470bea0a00f940c444c466 upstream.
An invalid ioctl will never be valid, irrespective of whether multipath has active paths or not. So for invalid ioctls we do not have to wait for multipath to activate any paths, but can rather return an error code immediately. This fix resolves numerous instances of:
udevd[]: worker [] unexpectedly returned with status 0x0100
that have been seen during testing.
--- drivers/md/dm-mpath.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/md/dm-mpath.c +5 -2
@@ -1541,8 +1541,11 @@ static int multipath_ioctl(struct dm_tar/* * Only pass ioctls through if the device sizes match exactly. */ -if (!r && ti->len !=i_size_read (bdev->bd_inode) >>SECTOR_SHIFT ) - r =scsi_verify_blk_ioctl (NULL , cmd); +if (!bdev || ti->len !=i_size_read (bdev->bd_inode) >>SECTOR_SHIFT ) { +int err =scsi_verify_blk_ioctl (NULL , cmd); +if (err) + r = err; + }return r ? :__blkdev_driver_ioctl (bdev, mode, cmd, arg); }
Greg Kroah-Hartman
maintainerPATCH 43/99 mm: vmscan: fix endless loop in kswapd balancing
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <[email protected]>
commit 60cefed485a02bd99b6299dad70666fe49245da7 upstream.
Kswapd does not in all places have the same criteria for a balanced zone. Zones are only being reclaimed when their high watermark is breached, but compaction checks loop over the zonelist again when the zone does not meet the low watermark plus two times the size of the allocation. This gets kswapd stuck in an endless loop over a small zone, like the DMA zone, where the high watermark is smaller than the compaction requirement.
Add a function, zone_balanced(), that checks the watermark, and, for higher order allocations, if compaction has enough free memory. Then use it uniformly to check for balanced zones.
This makes sure that when the compaction watermark is not met, at least reclaim happens and progress is made - or the zone is declared unreclaimable at some point and skipped entirely.
--- mm/vmscan.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
mm/vmscan.c +18 -9
@@ -2569,6 +2569,19 @@ static void age_active_anon(struct zone }while (memcg); } +static bool zone_balanced (struct zone *zone,int order, +unsigned long balance_gap,int classzone_idx) +{ +if (!zone_watermark_ok_safe (zone, order,high_wmark_pages (zone) + + balance_gap, classzone_idx,0 )) +return false; + +if (COMPACTION_BUILD && order && !compaction_suitable (zone, order)) +return false; + +return true; +} +/* * pgdat_balanced is used when checking if a node is balanced for high-order * allocations. Only zones that meet watermarks and are in a zone allowed
@@ -2628,8 +2641,7 @@ static bool sleeping_prematurely(pg_datacontinue ; } -if (!zone_watermark_ok_safe (zone, order,high_wmark_pages (zone), - i,0 )) +if (!zone_balanced (zone, order,0 , i)) all_zones_ok = false;else balanced += zone->present_pages;
@@ -2741,8 +2753,7 @@ loop_again:break ; } -if (!zone_watermark_ok_safe (zone, order, -high_wmark_pages (zone),0 ,0 )) { +if (!zone_balanced (zone, order,0 ,0 )) { end_zone = i;break ; }else {
@@ -2817,9 +2828,8 @@ loop_again: testorder =0 ;if ((buffer_heads_over_limit &&is_highmem_idx (i)) || - !zone_watermark_ok_safe (zone, testorder, -high_wmark_pages (zone) + balance_gap, - end_zone,0 )) { + !zone_balanced (zone, testorder, + balance_gap, end_zone)) {shrink_zone (priority, zone, &sc); reclaim_state->reclaimed_slab =0 ;
@@ -2846,8 +2856,7 @@ loop_again:continue ; } -if (!zone_watermark_ok_safe (zone, testorder, -high_wmark_pages (zone), end_zone,0 )) { +if (!zone_balanced (zone, testorder,0 , end_zone)) { all_zones_ok =0 ;/* * We are still under min water mark. This
Greg Kroah-Hartman
maintainerPATCH 44/99 cgroup: cgroup_subsys->fork() should be called after the task is added to css_set
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
commit 5edee61edeaaebafe584f8fb7074c1ef4658596b upstream.
cgroup core has a bug which violates a basic rule about event notifications - when a new entity needs to be added, you add that to the notification list first and then make the new entity conform to the current state. If done in the reverse order, an event happening inbetween will be lost.
cgroup_subsys->fork() is invoked way before the new task is added to the css_set. Currently, cgroup_freezer is the only user of ->fork() and uses it to make new tasks conform to the current state of the freezer. If FROZEN state is requested while fork is in progress between cgroup_fork_callbacks() and cgroup_post_fork(), the child could escape freezing - the cgroup isn't frozen when ->fork() is called and the freezer couldn't see the new task on the css_set.
This patch moves cgroup_subsys->fork() invocation to cgroup_post_fork() after the new task is added to the css_set. cgroup_fork_callbacks() is removed.
Because now a task may be migrated during cgroup_subsys->fork(), freezer_fork() is updated so that it adheres to the usual RCU locking and the rather pointless comment on why locking can be different there is removed (if it doesn't make anything simpler, why even bother?).
[hq: Backported to 3.4:
- Adjust context
- Iterate over first CGROUP_BUILTIN_SUBSYS_COUNT elements of subsys]
--- include/linux/cgroup.h | 1 kernel/cgroup.c | 50 ++++++++++++++++++++---------------------------- kernel/cgroup_freezer.c | 13 +++--------- kernel/fork.c | 9 -------- 4 files changed, 26 insertions(+), 47 deletions(-)
include/linux/cgroup.h +0 -1
@@ -32,7 +32,6 @@ extern int cgroup_lock_is_held(void);extern bool cgroup_lock_live_group (struct cgroup *cgrp);extern void cgroup_unlock (void );extern void cgroup_fork (struct task_struct *p); -extern void cgroup_fork_callbacks (struct task_struct *p);extern void cgroup_post_fork (struct task_struct *p);extern void cgroup_exit (struct task_struct *p,int run_callbacks); extern int cgroupstats_build(struct cgroupstats *stats,
kernel/cgroup.c +21 -29
69 lines not on this page · raw message
kernel/cgroup_freezer.c +4 -9
@@ -186,23 +186,15 @@ static void freezer_fork(struct task_str {struct freezer *freezer; -/* -* No lock is needed, since the task isn't on tasklist yet, -* so it can't be moved to another cgroup, which means the -* freezer won't be removed and will be valid during this -* function call. Nevertheless, apply RCU read-side critical -* section to suppress RCU lockdep false positives. -*/ rcu_read_lock (); freezer =task_freezer (task); -rcu_read_unlock ();/* * The root cgroup is non-freezable, so we can skip the * following check. */ if (!freezer->css.cgroup->parent) -return ; + goto out;spin_lock_irq (&freezer->lock);BUG_ON (freezer->state ==CGROUP_FROZEN );
@@ -210,7 +202,10 @@ static void freezer_fork(struct task_str/* Locking avoids race with FREEZING -> THAWED transitions. */ if (freezer->state ==CGROUP_FREEZING )freeze_task (task); +spin_unlock_irq (&freezer->lock); +out: +rcu_read_unlock (); }/*
kernel/fork.c +1 -8
@@ -1124,7 +1124,6 @@ static struct task_struct *copy_process( {int retval;struct task_struct *p; -int cgroup_callbacks_done =0 ;if ((clone_flags & (CLONE_NEWNS |CLONE_FS )) == (CLONE_NEWNS |CLONE_FS ))return ERR_PTR (-EINVAL );
@@ -1383,12 +1382,6 @@ static struct task_struct *copy_process( p->group_leader = p;INIT_LIST_HEAD (&p->thread_group); -/* Now that the task is set up, run cgroup callbacks if -* necessary. We need to run them before the task is visible -* on the tasklist. */ -cgroup_fork_callbacks (p); - cgroup_callbacks_done =1 ; -/* Need tasklist lock for parent etc handling! */ write_lock_irq (&tasklist_lock);
@@ -1493,7 +1486,7 @@ bad_fork_cleanup_cgroup:#endif if (clone_flags &CLONE_THREAD )threadgroup_change_end (current); -cgroup_exit (p, cgroup_callbacks_done); +cgroup_exit (p,0 );delayacct_tsk_free (p);module_put (task_thread_info (p)->exec_domain->module); bad_fork_cleanup_count:
Greg Kroah-Hartman
maintainerPATCH 45/99 KVM: s390: move kvm_guest_enter,exit closer to sie
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dominik Dingel <[email protected]>
commit 2b29a9fdcb92bfc6b6f4c412d71505869de61a56 upstream.
Any uaccess between guest_enter and guest_exit could trigger a page fault, the page fault handler would handle it as a guest fault and translate a user address as guest address.
--- arch/s390/kvm/kvm-s390.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
arch/s390/kvm/kvm-s390.c +7 -5
@@ -525,13 +525,18 @@ static int __vcpu_run(struct kvm_vcpu *vif (!kvm_is_ucontrol (vcpu->kvm))kvm_s390_deliver_pending_interrupts (vcpu); +VCPU_EVENT (vcpu,6 ,"entering sie flags %x" , +atomic_read (&vcpu->arch.sie_block->cpuflags)); + vcpu->arch.sie_block->icptcode =0 ;local_irq_disable ();kvm_guest_enter ();local_irq_enable (); -VCPU_EVENT (vcpu,6 ,"entering sie flags %x" , -atomic_read (&vcpu->arch.sie_block->cpuflags)); rc =sie64a (vcpu->arch.sie_block, vcpu->run->s.regs.gprs); +local_irq_disable (); +kvm_guest_exit (); +local_irq_enable (); +if (rc) {if (kvm_is_ucontrol (vcpu->kvm)) { rc =SIE_INTERCEPT_UCONTROL ;
@@ -543,9 +548,6 @@ static int __vcpu_run(struct kvm_vcpu *v }VCPU_EVENT (vcpu,6 ,"exit sie icptcode %d" , vcpu->arch.sie_block->icptcode); -local_irq_disable (); -kvm_guest_exit (); -local_irq_enable ();memcpy (&vcpu->run->s.regs.gprs[14 ], &vcpu->arch.sie_block->gg14,16 );return rc;
Greg Kroah-Hartman
maintainerPATCH 46/99 s390/kvm: dont announce RRBM support
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Borntraeger <[email protected]>
commit 87cac8f879a5ecd7109dbe688087e8810b3364eb upstream.
Newer kernels (linux-next with the transparent huge page patches) use rrbm if the feature is announced via feature bit 66. RRBM will cause intercepts, so KVM does not handle it right now, causing an illegal instruction in the guest.
The easy solution is to disable the feature bit for the guest.
This fixes bugs like:
Kernel BUG at 0000000000124c2a [verbose debug info unavailable]
illegal operation: 0001 [#1] SMP
Modules linked in: virtio_balloon virtio_net ipv6 autofs4
CPU: 0 Not tainted 3.5.4 #1
Process fmempig (pid: 659, task: 000000007b712fd0, ksp: 000000007bed3670)
Krnl PSW : 0704d00180000000 0000000000124c2a (pmdp_clear_flush_young+0x5e/0x80)
R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:1 PM:0 EA:3
00000000003cc000 0000000000000004 0000000000000000 0000000079800000
0000000000040000 0000000000000000 000000007bed3918 000000007cf40000
0000000000000001 000003fff7f00000 000003d281a94000 000000007bed383c
000000007bed3918 00000000005ecbf8 00000000002314a6 000000007bed36e0
Krnl Code:>0000000000124c2a: b9810025 ogr %r2,%r5
0000000000124c2e: 41343000 la %r3,0(%r4,%r3)
0000000000124c32: a716fffa brct %r1,124c26
0000000000124c36: b9010022 lngr %r2,%r2
0000000000124c3a: e3d0f0800004 lg %r13,128(%r15)
0000000000124c40: eb22003f000c srlg %r2,%r2,63
[ 2150.713198] Call Trace:
[ 2150.713223] ([<00000000002312c4>] page_referenced_one+0x6c/0x27c)
[ 2150.713749] [<0000000000233812>] page_referenced+0x32a/0x410[...]
--- arch/s390/kvm/kvm-s390.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/kvm/kvm-s390.c +1 -1
@@ -904,7 +904,7 @@ static int __init kvm_s390_init(void) }memcpy (facilities, S390_lowcore.stfle_fac_list,16 ); facilities[0 ] &=0xff00fff3f47c0000ULL ; - facilities[1 ] &=0x201c000000000000ULL ; + facilities[1 ] &=0x001c000000000000ULL ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 47/99 KVM: PPC: Emulate dcbf
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Graf <[email protected]>
commit d3286144c92ec876da9e30320afa875699b7e0f1 upstream.
Guests can trigger MMIO exits using dcbf. Since we don't emulate cache incoherent MMIO, just do nothing and move on.
--- arch/powerpc/kvm/emulate.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/kvm/emulate.c +2 -0
@@ -36,6 +36,7 @@#define OP_TRAP_64 2#define OP_31_XOP_LWZX 23 +#define OP_31_XOP_DCBF 86#define OP_31_XOP_LBZX 87#define OP_31_XOP_STWX 151#define OP_31_XOP_STBX 215
@@ -373,6 +374,7 @@ int kvmppc_emulate_instruction(struct kvkvmppc_set_exit_type (vcpu,EMULATED_MTSPR_EXITS );break ; +case OP_31_XOP_DCBF :case OP_31_XOP_DCBI :/* Do nothing. The guest is performing dcbi because * hardware DMA is not snooped by the dcache, but
Greg Kroah-Hartman
maintainerPATCH 48/99 KVM: IOMMU: hva align mapping page size
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Edwards <[email protected]>
commit 27ef63c7e97d1e5dddd85051c03f8d44cc887f34 upstream.
When determining the page size we could use to map with the IOMMU, the page size should also be aligned with the hva, not just the gfn. The gfn may not reflect the real alignment within the hugetlbfs file.
Most of the time, this works fine. However, if the hugetlbfs file is backed by non-contiguous huge pages, a multi-huge page memslot starts at an unaligned offset within the hugetlbfs file, and the gfn is aligned with respect to the huge page size, kvm_host_page_size() will return the huge page size and we will use that to map with the IOMMU.
When we later unpin that same memslot, the IOMMU returns the unmap size as the huge page size, and we happily unpin that many pfns in monotonically increasing order, not realizing we are spanning non-contiguous huge pages and partially unpin the wrong huge page.
Ensure the IOMMU mapping page size is aligned with the hva corresponding to the gfn, which does reflect the alignment within the hugetlbfs file.
--- virt/kvm/iommu.c | 4 ++++ 1 file changed, 4 insertions(+)
virt/kvm/iommu.c +4 -0
@@ -101,6 +101,10 @@ int kvm_iommu_map_pages(struct kvm *kvm,while ((gfn <<PAGE_SHIFT ) & (page_size -1 )) page_size >>=1 ; +/* Make sure hva is aligned to the page size we want to map */ +while (gfn_to_hva_memslot (slot, gfn) & (page_size -1 )) + page_size >>=1 ; +/* * Pin all pages we are about to map in memory. This is * important because we unmap and unpin in 4kb steps later.
Greg Kroah-Hartman
maintainerPATCH 49/99 proc connector: reject unprivileged listener bumps
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
commit e70ab977991964a5a7ad1182799451d067e62669 upstream.
While PROC_CN_MCAST_LISTEN/IGNORE is entirely advisory, it was possible for an unprivileged user to turn off notifications for all listeners by sending PROC_CN_MCAST_IGNORE. Instead, require the same privileges as required for a multicast bind.
--- drivers/connector/cn_proc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/connector/cn_proc.c +8 -0
@@ -331,6 +331,12 @@ static void cn_proc_mcast_ctl(struct cn_if (msg->len !=sizeof (*mc_op))return ; +/* Can only change if privileged. */ +if (!capable (CAP_NET_ADMIN )) { + err =EPERM ; + goto out; + } + mc_op = (enum proc_cn_mcast_op *)msg->data;switch (*mc_op) {case PROC_CN_MCAST_LISTEN :
@@ -343,6 +349,8 @@ static void cn_proc_mcast_ctl(struct cn_ err =EINVAL ;break ; } + +out:cn_proc_ack (err, msg->seq, msg->ack); }
Greg Kroah-Hartman
maintainerPATCH 50/99 cgroup: fix RCU accesses to task->cgroups
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
commit 14611e51a57df10240817d8ada510842faf0ec51 upstream.
task->cgroups is a RCU pointer pointing to struct css_set. A task switches to a different css_set on cgroup migration but a css_set doesn't change once created and its pointers to cgroup_subsys_states aren't RCU protected.
task_subsys_state[_check]() is the macro to acquire css given a task and subsys_id pair. It RCU-dereferences task->cgroups->subsys[] not task->cgroups, so the RCU pointer task->cgroups ends up being dereferenced without read_barrier_depends() after it. It's broken.
Fix it by introducing task_css_set[_check]() which does RCU-dereference on task->cgroups. task_subsys_state[_check]() is reimplemented to directly dereference ->subsys[] of the css_set returned from task_css_set[_check]().
This removes some of sparse RCU warnings in cgroup.
v2: Fixed unbalanced parenthsis and there's no need to use
rcu_dereference_raw() when !CONFIG_PROVE_RCU. Both spotted by Li.
[bwh: Backported to 3.2:
- Adjust context
- Remove CONFIG_PROVE_RCU condition
- s/lockdep_is_held(&cgroup_mutex)/cgroup_lock_is_held()/]
--- include/linux/cgroup.h | 52 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-)
include/linux/cgroup.h +45 -7
@@ -513,16 +513,54 @@ static inline struct cgroup_subsys_statereturn cgrp->subsys[subsys_id]; } -/* -* function to get the cgroup_subsys_state which allows for extra -* rcu_dereference_check() conditions, such as locks used during the -* cgroup_subsys::attach() methods. +/** +* task_css_set_check - obtain a task's css_set with extra access conditions +* @task: the task to obtain css_set for +* @__c: extra condition expression to be passed to rcu_dereference_check() +* +* A task's css_set is RCU protected, initialized and exited while holding +* task_lock(), and can only be modified while holding both cgroup_mutex +* and task_lock() while the task is alive. This macro verifies that the +* caller is inside proper critical section and returns @task's css_set. +* +* The caller can also specify additional allowed conditions via @__c, such +* as locks used during the cgroup_subsys::attach() methods. +*/ +#define task_css_set_check (task, __c) \ + rcu_dereference_check((task)->cgroups, \ + lockdep_is_held(&(task)->alloc_lock) || \ + cgroup_lock_is_held() || (__c)) + +/** +* task_subsys_state_check - obtain css for (task, subsys) w/ extra access conds +* @task: the target task +* @subsys_id: the target subsystem ID +* @__c: extra condition expression to be passed to rcu_dereference_check() +* +* Return the cgroup_subsys_state for the (@task, @subsys_id) pair. The +* synchronization rules are the same as task_css_set_check(). */ #define task_subsys_state_check (task, subsys_id, __c) \ - rcu_dereference_check(task->cgroups->subsys[subsys_id], \ - lockdep_is_held(&task->alloc_lock) || \ - cgroup_lock_is_held() || (__c)) + task_css_set_check((task), (__c))->subsys[(subsys_id)] +/** +* task_css_set - obtain a task's css_set +* @task: the task to obtain css_set for +* +* See task_css_set_check(). +*/ +static inline struct css_set *task_css_set (struct task_struct *task) +{ +return task_css_set_check (task, false); +} + +/** +* task_subsys_state - obtain css for (task, subsys) +* @task: the target task +* @subsys_id: the target subsystem ID +* +* See task_subsys_state_check(). +*/ static inline struct cgroup_subsys_state *task_subsys_state (struct task_struct *task,int subsys_id) {
Greg Kroah-Hartman
maintainerPATCH 51/99 mm/hotplug: correctly add new zone to all other nodes zone lists
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiang Liu <[email protected]>
commit 08dff7b7d629807dbb1f398c68dd9cd58dd657a1 upstream.
When online_pages() is called to add new memory to an empty zone, it rebuilds all zone lists by calling build_all_zonelists(). But there's a bug which prevents the new zone to be added to other nodes' zone lists.
online_pages() {
build_all_zonelists()
.....
node_set_state(zone_to_nid(zone), N_HIGH_MEMORY)
}Here the node of the zone is put into N_HIGH_MEMORY state after calling build_all_zonelists(), but build_all_zonelists() only adds zones from nodes in N_HIGH_MEMORY state to the fallback zone lists. build_all_zonelists()
->__build_all_zonelists() ->build_zonelists() ->find_next_best_node() ->for_each_node_state(n, N_HIGH_MEMORY)
So memory in the new zone will never be used by other nodes, and it may cause strange behavor when system is under memory pressure. So put node into N_HIGH_MEMORY state before calling build_all_zonelists().
--- mm/memory_hotplug.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
mm/memory_hotplug.c +8 -7
@@ -515,19 +515,20 @@ int __ref online_pages(unsigned long pfn zone->present_pages += onlined_pages; zone->zone_pgdat->node_present_pages += onlined_pages; -if (need_zonelists_rebuild) -build_all_zonelists (zone); -else -zone_pcp_update (zone); +if (onlined_pages) { +node_set_state (zone_to_nid (zone),N_HIGH_MEMORY ); +if (need_zonelists_rebuild) +build_all_zonelists (zone); +else +zone_pcp_update (zone); + }mutex_unlock (&zonelists_mutex);init_per_zone_wmark_min (); -if (onlined_pages) { +if (onlined_pages)kswapd_run (zone_to_nid (zone)); -node_set_state (zone_to_nid (zone),N_HIGH_MEMORY ); - } vm_total_pages =nr_free_pagecache_pages ();
Greg Kroah-Hartman
maintainerPATCH 52/99 perf tools: Remove extraneous newline when parsing hardware cache events
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit 42e1fb776087713b5482cd7cf6cac998fbdd6544 upstream.
Noticed while developing a 'perf test' entry to verify that perf_evsel__name works.
--- tools/perf/util/parse-events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/parse-events.c +1 -1
@@ -413,7 +413,7 @@ int parse_events_add_cache(struct list_hfor (i =0 ; (i <2 ) && (op_result[i]); i++) {char *str = op_result[i]; -snprintf (name + n,MAX_NAME_LEN - n,"-%s\n" , str); +snprintf (name + n,MAX_NAME_LEN - n,"-%s" , str);if (cache_op ==-1 ) { cache_op = parse_aliases(str, hw_cache_op,
Greg Kroah-Hartman
maintainerPATCH 53/99 perf tools: Fix cache event name generation
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
commit 275ef3878f698941353780440fec6926107a320b upstream.
If the event name is specified with all 3 components, the last one overwrites the previous one during the name composing within the parse_events_add_cache function.
Fixing this by properly adjusting the string index.
LPU-Reference: [email protected]
--- tools/perf/util/parse-events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/parse-events.c +1 -1
@@ -413,7 +413,7 @@ int parse_events_add_cache(struct list_hfor (i =0 ; (i <2 ) && (op_result[i]); i++) {char *str = op_result[i]; -snprintf (name + n,MAX_NAME_LEN - n,"-%s" , str); + n +=snprintf (name + n,MAX_NAME_LEN - n,"-%s" , str);if (cache_op ==-1 ) { cache_op = parse_aliases(str, hw_cache_op,
Greg Kroah-Hartman
maintainerPATCH 54/99 nilfs2: fix issue with race condition of competition between segments for dirty blocks
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vyacheslav Dubeyko <[email protected]>
commit 7f42ec3941560f0902fe3671e36f2c20ffd3af0a upstream.
Many NILFS2 users were reported about strange file system corruption (for example):
NILFS: bad btree node (blocknr=185027): level = 0, flags = 0x0, nchildren = 768 NILFS error (device sda4): nilfs_bmap_last_key: broken bmap (inode number=11540)
But such error messages are consequence of file system's issue that takes place more earlier. Fortunately, Jerome Poulin <[email protected]> and Anton Eliasson <[email protected]> were reported about another issue not so recently. These reports describe the issue with segctor thread's crash:
BUG: unable to handle kernel paging request at 0000000000004c83 IP: nilfs_end_page_io+0x12/0xd0 [nilfs2] Call Trace: nilfs_segctor_do_construct+0xf25/0x1b20 [nilfs2] nilfs_segctor_construct+0x17b/0x290 [nilfs2] nilfs_segctor_thread+0x122/0x3b0 [nilfs2] kthread+0xc0/0xd0 ret_from_fork+0x7c/0xb0
These two issues have one reason. This reason can raise third issue too. Third issue results in hanging of segctor thread with eating of 100% CPU.
REPRODUCING PATH:
One of the possible way or the issue reproducing was described by Jermoe me Poulin <[email protected]>:
1. init S to get to single user mode.
2. sysrq+E to make sure only my shell is running
3. start network-manager to get my wifi connection up
4. login as root and launch "screen"
5. cd /boot/log/nilfs which is a ext3 mount point and can log when NILFS dies.
6. lscp | xz -9e > lscp.txt.xz
7. mount my snapshot using mount -o cp=3360839,ro /dev/vgUbuntu/root /mnt/nilfs
8. start a screen to dump /proc/kmsg to text file since rsyslog is killed
9. start a screen and launch strace -f -o find-cat.log -t find /mnt/nilfs -type f -exec cat {} > /dev/null \;
10. start a screen and launch strace -f -o apt-get.log -t apt-get update
11. launch the last command again as it did not crash the first time
12. apt-get crashes
13. ps aux > ps-aux-crashed.log
13. sysrq+W
14. sysrq+E wait for everything to terminate
15. sysrq+SUSB
Simplified way of the issue reproducing is starting kernel compilation task and "apt-get update" in parallel.
REPRODUCIBILITY:
The issue is reproduced not stable [60% - 80%]. It is very important to have proper environment for the issue reproducing. The critical conditions for successful reproducing:
(1) It should have big modified file by mmap() way.
(2) This file should have the count of dirty blocks are greater that several segments in size (for example, two or three) from time to time during processing.
(3) It should be intensive background activity of files modification in another thread.
INVESTIGATION:
First of all, it is possible to see that the reason of crash is not valid page address:
NILFS [nilfs_segctor_complete_write]:2100 bh->b_count 0, bh->b_blocknr 13895680, bh->b_size 13897727, bh->b_page 0000000000001a82 NILFS [nilfs_segctor_complete_write]:2101 segbuf->sb_segnum 6783
Moreover, value of b_page (0x1a82) is 6786. This value looks like segment number. And b_blocknr with b_size values look like block numbers. So, buffer_head's pointer points on not proper address value.
Detailed investigation of the issue is discovered such picture:
[-----------------------------SEGMENT 6783-------------------------------] NILFS [nilfs_segctor_do_construct]:2310 nilfs_segctor_begin_construction NILFS [nilfs_segctor_do_construct]:2321 nilfs_segctor_collect
NILFS [nilfs_segctor_do_construct]:2336 nilfs_segctor_assign
NILFS [nilfs_segctor_do_construct]:2367 nilfs_segctor_update_segusage NILFS [nilfs_segctor_do_construct]:2371 nilfs_segctor_prepare_write NILFS [nilfs_segctor_do_construct]:2376 nilfs_add_checksums_on_logs NILFS [nilfs_segctor_do_construct]:2381 nilfs_segctor_write
NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111149024, segbuf->sb_segnum 6783
[-----------------------------SEGMENT 6784-------------------------------]
NILFS [nilfs_segctor_do_construct]:2310 nilfs_segctor_begin_construction
NILFS [nilfs_segctor_do_construct]:2321 nilfs_segctor_collect
NILFS [nilfs_lookup_dirty_data_buffers]:782 bh->b_count 1, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824 NILFS [nilfs_lookup_dirty_data_buffers]:783 bh->b_assoc_buffers.next ffff8802174a6798, bh->b_assoc_buffers.prev ffff880221cffee8 NILFS [nilfs_segctor_do_construct]:2336 nilfs_segctor_assign
NILFS [nilfs_segctor_do_construct]:2367 nilfs_segctor_update_segusage
NILFS [nilfs_segctor_do_construct]:2371 nilfs_segctor_prepare_write
NILFS [nilfs_segctor_do_construct]:2376 nilfs_add_checksums_on_logs
NILFS [nilfs_segctor_do_construct]:2381 nilfs_segctor_write
NILFS [nilfs_segbuf_submit_bh]:575 bh->b_count 1, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824 NILFS [nilfs_segbuf_submit_bh]:576 segbuf->sb_segnum 6784
NILFS [nilfs_segbuf_submit_bh]:577 bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880218bcdf50 NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111150080, segbuf->sb_segnum 6784, segbuf->sb_nbio 0 [----------] ditto
NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111164416, segbuf->sb_segnum 6784, segbuf->sb_nbio 15
[-----------------------------SEGMENT 6785-------------------------------]
NILFS [nilfs_segctor_do_construct]:2310 nilfs_segctor_begin_construction
NILFS [nilfs_segctor_do_construct]:2321 nilfs_segctor_collect
NILFS [nilfs_lookup_dirty_data_buffers]:782 bh->b_count 2, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824 NILFS [nilfs_lookup_dirty_data_buffers]:783 bh->b_assoc_buffers.next ffff880219277e80, bh->b_assoc_buffers.prev ffff880221cffc88 NILFS [nilfs_segctor_do_construct]:2367 nilfs_segctor_update_segusage
NILFS [nilfs_segctor_do_construct]:2371 nilfs_segctor_prepare_write
NILFS [nilfs_segctor_do_construct]:2376 nilfs_add_checksums_on_logs
NILFS [nilfs_segctor_do_construct]:2381 nilfs_segctor_write
NILFS [nilfs_segbuf_submit_bh]:575 bh->b_count 2, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824 NILFS [nilfs_segbuf_submit_bh]:576 segbuf->sb_segnum 6785
NILFS [nilfs_segbuf_submit_bh]:577 bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880222cc7ee8 NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111165440, segbuf->sb_segnum 6785, segbuf->sb_nbio 0 [----------] ditto
NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111177728, segbuf->sb_segnum 6785, segbuf->sb_nbio 12
NILFS [nilfs_segctor_do_construct]:2399 nilfs_segctor_wait NILFS [nilfs_segbuf_wait]:676 segbuf->sb_segnum 6783 NILFS [nilfs_segbuf_wait]:676 segbuf->sb_segnum 6784 NILFS [nilfs_segbuf_wait]:676 segbuf->sb_segnum 6785
NILFS [nilfs_segctor_complete_write]:2100 bh->b_count 0, bh->b_blocknr 13895680, bh->b_size 13897727, bh->b_page 0000000000001a82
BUG: unable to handle kernel paging request at 0000000000001a82 IP: [<ffffffffa024d0f2>] nilfs_end_page_io+0x12/0xd0 [nilfs2]
Usually, for every segment we collect dirty files in list. Then, dirty blocks are gathered for every dirty file, prepared for write and submitted by means of nilfs_segbuf_submit_bh() call. Finally, it takes place complete write phase after calling nilfs_end_bio_write() on the block layer. Buffers/pages are marked as not dirty on final phase and processed files removed from the list of dirty files.
It is possible to see that we had three prepare_write and submit_bio phases before segbuf_wait and complete_write phase. Moreover, segments compete between each other for dirty blocks because on every iteration of segments processing dirty buffer_heads are added in several lists of payload_buffers:
[SEGMENT 6784]: bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880218bcdf50 [SEGMENT 6785]: bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880222cc7ee8
The next pointer is the same but prev pointer has changed. It means that buffer_head has next pointer from one list but prev pointer from another. Such modification can be made several times. And, finally, it can be resulted in various issues: (1) segctor hanging, (2) segctor crashing, (3) file system metadata corruption.
FIX:
This patch adds:
(1) setting of BH_Async_Write flag in nilfs_segctor_prepare_write()
for every proccessed dirty block;
(2) checking of BH_Async_Write flag in
nilfs_lookup_dirty_data_buffers() and
nilfs_lookup_dirty_node_buffers();(3) clearing of BH_Async_Write flag in nilfs_segctor_complete_write(), nilfs_abort_logs(), nilfs_forget_buffer(), nilfs_clear_dirty_page().
[bwh: Backported to 3.2: nilfs_clear_dirty_page() has not been separated
from nilfs_clear_dirty_pages()]
--- fs/nilfs2/page.c | 2 ++ fs/nilfs2/segment.c | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-)
fs/nilfs2/page.c +2 -0
@@ -94,6 +94,7 @@ void nilfs_forget_buffer(struct buffer_hclear_buffer_nilfs_volatile (bh);clear_buffer_nilfs_checked (bh);clear_buffer_nilfs_redirected (bh); +clear_buffer_async_write (bh);clear_buffer_dirty (bh);if (nilfs_page_buffers_clean (page))__nilfs_clear_page_dirty (page);
@@ -390,6 +391,7 @@ void nilfs_clear_dirty_pages(struct addr bh = head =page_buffers (page); do { lock_buffer(bh); + clear_buffer_async_write(bh); clear_buffer_dirty(bh); clear_buffer_nilfs_volatile(bh); clear_buffer_nilfs_checked(bh);
fs/nilfs2/segment.c +9 -2
@@ -662,7 +662,7 @@ static size_t nilfs_lookup_dirty_data_bu bh = head =page_buffers (page); do { - if (!buffer_dirty(bh)) + if (!buffer_dirty(bh) || buffer_async_write(bh)) continue; get_bh(bh); list_add_tail(&bh->b_assoc_buffers, listp);
@@ -696,7 +696,8 @@ static void nilfs_lookup_dirty_node_bufffor (i =0 ; i <pagevec_count (&pvec); i++) { bh = head =page_buffers (pvec.pages[i]); do { - if (buffer_dirty(bh)) { + if (buffer_dirty(bh) && + !buffer_async_write(bh)) { get_bh(bh); list_add_tail(&bh->b_assoc_buffers, listp);
@@ -1578,6 +1579,7 @@ static void nilfs_segctor_prepare_write(list_for_each_entry (bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) { +set_buffer_async_write (bh);if (bh->b_page != bd_page) {if (bd_page) {lock_page (bd_page);
@@ -1591,6 +1593,7 @@ static void nilfs_segctor_prepare_write(list_for_each_entry (bh, &segbuf->sb_payload_buffers, b_assoc_buffers) { +set_buffer_async_write (bh);if (bh == segbuf->sb_super_root) {if (bh->b_page != bd_page) {lock_page (bd_page);
@@ -1676,6 +1679,7 @@ static void nilfs_abort_logs(struct listlist_for_each_entry (segbuf, logs, sb_list) {list_for_each_entry (bh, &segbuf->sb_segsum_buffers, b_assoc_buffers) { +clear_buffer_async_write (bh);if (bh->b_page != bd_page) {if (bd_page)end_page_writeback (bd_page);
@@ -1685,6 +1689,7 @@ static void nilfs_abort_logs(struct listlist_for_each_entry (bh, &segbuf->sb_payload_buffers, b_assoc_buffers) { +clear_buffer_async_write (bh);if (bh == segbuf->sb_super_root) {if (bh->b_page != bd_page) {end_page_writeback (bd_page);
@@ -1754,6 +1759,7 @@ static void nilfs_segctor_complete_write b_assoc_buffers) {set_buffer_uptodate (bh);clear_buffer_dirty (bh); +clear_buffer_async_write (bh);if (bh->b_page != bd_page) {if (bd_page)end_page_writeback (bd_page);
@@ -1775,6 +1781,7 @@ static void nilfs_segctor_complete_write b_assoc_buffers) {set_buffer_uptodate (bh);clear_buffer_dirty (bh); +clear_buffer_async_write (bh);clear_buffer_delay (bh);clear_buffer_nilfs_volatile (bh);clear_buffer_nilfs_redirected (bh);
Greg Kroah-Hartman
maintainerPATCH 55/99 fuse: readdir: check for slash in names
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <[email protected]>
commit efeb9e60d48f7778fdcad4a0f3ad9ea9b19e5dfd upstream.
Userspace can add names containing a slash character to the directory listing. Don't allow this as it could cause all sorts of trouble.
[bwh: Backported to 3.2: drop changes to parse_dirplusfile() which we
don't have]
--- fs/fuse/dir.c | 2 ++ 1 file changed, 2 insertions(+)
fs/fuse/dir.c +2 -0
@@ -1103,6 +1103,8 @@ static int parse_dirfile(char *buf, sizereturn -EIO ;if (reclen > nbytes)break ; +if (memchr (dirent->name,'/' , dirent->namelen) !=NULL ) +return -EIO ; over =filldir (dstbuf, dirent->name, dirent->namelen, file->f_pos, dirent->ino, dirent->type);
Greg Kroah-Hartman
maintainerPATCH 56/99 fuse: hotfix truncate_pagecache() issue
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxim Patlasov <[email protected]>
commit 06a7c3c2781409af95000c60a5df743fd4e2f8b4 upstream.
The way how fuse calls truncate_pagecache() from fuse_change_attributes() is completely wrong. Because, w/o i_mutex held, we never sure whether 'oldsize' and 'attr->size' are valid by the time of execution of truncate_pagecache(inode, oldsize, attr->size). In fact, as soon as we released fc->lock in the middle of fuse_change_attributes(), we completely loose control of actions which may happen with given inode until we reach truncate_pagecache. The list of potentially dangerous actions includes mmap-ed reads and writes, ftruncate(2) and write(2) extending file size.
The typical outcome of doing truncate_pagecache() with outdated arguments is data corruption from user point of view. This is (in some sense) acceptable in cases when the issue is triggered by a change of the file on the server (i.e. externally wrt fuse operation), but it is absolutely intolerable in scenarios when a single fuse client modifies a file without any external intervention. A real life case I discovered by fsx-linux looked like this:
1. Shrinking ftruncate(2) comes to fuse_do_setattr(). The latter sends FUSE_SETATTR to the server synchronously, but before getting fc->lock ...
2. fuse_dentry_revalidate() is asynchronously called. It sends FUSE_LOOKUP to the server synchronously, then calls fuse_change_attributes(). The latter updates i_size, releases fc->lock, but before comparing oldsize vs attr->size..
3. fuse_do_setattr() from the first step proceeds by acquiring fc->lock and updating attributes and i_size, but now oldsize is equal to outarg.attr.size because i_size has just been updated (step 2). Hence, fuse_do_setattr() returns w/o calling truncate_pagecache().
4. As soon as ftruncate(2) completes, the user extends file size by write(2) making a hole in the middle of file, then reads data from the hole either by read(2) or mmap-ed read. The user expects to get zero data from the hole, but gets stale data because truncate_pagecache() is not executed yet.
The scenario above illustrates one side of the problem: not truncating the page cache even though we should. Another side corresponds to truncating page cache too late, when the state of inode changed significantly. Theoretically, the following is possible:
1. As in the previous scenario fuse_dentry_revalidate() discovered that i_size changed (due to our own fuse_do_setattr()) and is going to call truncate_pagecache() for some 'new_size' it believes valid right now. But by the time that particular truncate_pagecache() is called ...
2. fuse_do_setattr() returns (either having called truncate_pagecache() or not -- it doesn't matter).
3. The file is extended either by write(2) or ftruncate(2) or fallocate(2).
4. mmap-ed write makes a page in the extended region dirty.
The result will be the lost of data user wrote on the fourth step.
The patch is a hotfix resolving the issue in a simplistic way: let's skip dangerous i_size update and truncate_pagecache if an operation changing file size is in progress. This simplistic approach looks correct for the cases w/o external changes. And to handle them properly, more sophisticated and intrusive techniques (e.g. NFS-like one) would be required. I'd like to postpone it until the issue is well discussed on the mailing list(s).
Changed in v2:
- improved patch description to cover both sides of the issue.
--- fs/fuse/dir.c | 7 ++++++- fs/fuse/file.c | 8 +++++++- fs/fuse/fuse_i.h | 9 +++++++++ fs/fuse/inode.c | 4 +++- 4 files changed, 25 insertions(+), 3 deletions(-)
fs/fuse/dir.c +6 -1
@@ -1348,6 +1348,7 @@ static int fuse_do_setattr(struct dentry {struct inode *inode = entry->d_inode;struct fuse_conn *fc =get_fuse_conn (inode); +struct fuse_inode *fi =get_fuse_inode (inode);struct fuse_req *req;struct fuse_setattr_in inarg;struct fuse_attr_out outarg;
@@ -1378,8 +1379,10 @@ static int fuse_do_setattr(struct dentryif (IS_ERR (req))return PTR_ERR (req); -if (is_truncate) +if (is_truncate) {fuse_set_nowrite (inode); +set_bit (FUSE_I_SIZE_UNSTABLE , &fi->state); + }memset (&inarg,0 ,sizeof (inarg));memset (&outarg,0 ,sizeof (outarg));
@@ -1441,12 +1444,14 @@ static int fuse_do_setattr(struct dentryinvalidate_inode_pages2 (inode->i_mapping); } +clear_bit (FUSE_I_SIZE_UNSTABLE , &fi->state);return 0 ; error:if (is_truncate)fuse_release_nowrite (inode); +clear_bit (FUSE_I_SIZE_UNSTABLE , &fi->state);return err; }
fs/fuse/file.c +7 -1
@@ -515,7 +515,8 @@ static void fuse_read_update_size(structstruct fuse_inode *fi =get_fuse_inode (inode);spin_lock (&fc->lock); -if (attr_ver == fi->attr_version && size < inode->i_size) { +if (attr_ver == fi->attr_version && size < inode->i_size && + !test_bit (FUSE_I_SIZE_UNSTABLE , &fi->state)) { fi->attr_version = ++fc->attr_version;i_size_write (inode, size); }
@@ -877,12 +878,16 @@ static ssize_t fuse_perform_write(struct {struct inode *inode = mapping->host;struct fuse_conn *fc =get_fuse_conn (inode); +struct fuse_inode *fi =get_fuse_inode (inode);int err =0 ;ssize_t res =0 ;if (is_bad_inode (inode))return -EIO ; +if (inode->i_size < pos +iov_iter_count (ii)) +set_bit (FUSE_I_SIZE_UNSTABLE , &fi->state); + do { struct fuse_req *req; ssize_t count;
@@ -917,6 +922,7 @@ static ssize_t fuse_perform_write(structif (res >0 )fuse_write_update_size (inode, pos); +clear_bit (FUSE_I_SIZE_UNSTABLE , &fi->state);fuse_invalidate_attr (inode);return res >0 ? res : err;
fs/fuse/fuse_i.h +9 -0
@@ -103,6 +103,15 @@ struct fuse_inode {/** List of writepage requestst (pending or sent) */ struct list_head writepages; + +/** Miscellaneous bits describing inode state */ +unsigned long state; +}; + +/** FUSE inode state bits */ +enum { +/** An operation changing file size is in progress */ +FUSE_I_SIZE_UNSTABLE , };struct fuse_conn ;
fs/fuse/inode.c +3 -1
@@ -92,6 +92,7 @@ static struct inode *fuse_alloc_inode(st fi->attr_version =0 ; fi->writectr =0 ; fi->orig_ino =0 ; + fi->state =0 ;INIT_LIST_HEAD (&fi->write_files);INIT_LIST_HEAD (&fi->queued_writes);INIT_LIST_HEAD (&fi->writepages);
@@ -199,7 +200,8 @@ void fuse_change_attributes(struct inodeloff_t oldsize;spin_lock (&fc->lock); -if (attr_version !=0 && fi->attr_version > attr_version) { +if ((attr_version !=0 && fi->attr_version > attr_version) || +test_bit (FUSE_I_SIZE_UNSTABLE , &fi->state)) {spin_unlock (&fc->lock);return ; }
Greg Kroah-Hartman
maintainerPATCH 57/99 libceph: unregister request in __map_request failed and nofail == false
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: majianpeng <[email protected]>
commit 73d9f7eef3d98c3920e144797cc1894c6b005a1e upstream.
For nofail == false request, if __map_request failed, the caller does cleanup work, like releasing the relative pages. It doesn't make any sense to retry this request.
--- net/ceph/osd_client.c | 2 ++ 1 file changed, 2 insertions(+)
net/ceph/osd_client.c +2 -0
@@ -1721,6 +1721,8 @@ int ceph_osdc_start_request(struct ceph_dout ("osdc_start_request failed map, " " will retry %lld\n" , req->r_tid); rc =0 ; + }else { +__unregister_request (osdc, req); } goto out_unlock; }
Greg Kroah-Hartman
maintainerPATCH 58/99 cifs: dont instantiate new dentries in readdir for inodes that need to be revalidated immediately
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
commit 757c4f6260febff982276818bb946df89c1105aa upstream.
David reported that commit c2b93e06 (cifs: only set ops for inodes in I_NEW state) caused a regression with mfsymlinks. Prior to that patch, if a mfsymlink dentry was instantiated at readdir time, the inode would get a new set of ops when it was revalidated. After that patch, this did not occur.
This patch addresses this by simply skipping instantiating dentries in the readdir codepath when we know that they will need to be immediately revalidated. The next attempt to use that dentry will cause a new lookup to occur (which is basically what we want to happen anyway).
--- fs/cifs/readdir.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/cifs/readdir.c +8 -0
@@ -96,6 +96,14 @@ cifs_readdir_lookup(struct dentry *parendput (dentry); } +/* +* If we know that the inode will need to be revalidated immediately, +* then don't create a new dentry for it. We'll end up doing an on +* the wire call either way and this spares us an invalidation. +*/ +if (fattr->cf_flags &CIFS_FATTR_NEED_REVAL ) +return NULL ; + dentry =d_alloc (parent, name);if (dentry ==NULL )return NULL ;
Greg Kroah-Hartman
maintainerPATCH 59/99 ncpfs: fix rmdir returns Device or resource busy
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Chiluk <[email protected]>
commit 698b8223631472bf982ed570b0812faa61955683 upstream.
1d2ef5901483004d74947bbf78d5146c24038fe7 caused a regression in ncpfs such that directories could no longer be removed. This was because ncp_rmdir checked to see if a dentry could be unhashed before allowing it to be removed. Since 1d2ef5901483004d74947bbf78d5146c24038fe7 introduced a change that incremented dentry->d_count causing it to always be greater than 1 unhash would always fail. Thus causing the error path in ncp_rmdir to always be taken. Removing this error path is safe as unhashing is still accomplished by calls to dput from vfs_rmdir.
--- fs/ncpfs/dir.c | 9 --------- 1 file changed, 9 deletions(-)
fs/ncpfs/dir.c +0 -9
@@ -1033,15 +1033,6 @@ static int ncp_rmdir(struct inode *dir,DPRINTK ("ncp_rmdir: removing %s/%s\n" , dentry->d_parent->d_name.name, dentry->d_name.name); -/* -* fail with EBUSY if there are still references to this -* directory. -*/ -dentry_unhash (dentry); - error = -EBUSY ; -if (!d_unhashed (dentry)) - goto out; - len =sizeof (__name); error =ncp_io2vol (server, __name, &len, dentry->d_name.name, dentry->d_name.len, !ncp_preserve_case (dir));
Greg Kroah-Hartman
maintainerPATCH 60/99 ext4/jbd2: dont wait (forever) for stale tid caused by wraparound
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit d76a3a77113db020d9bb1e894822869410450bd9 upstream.
In the case where an inode has a very stale transaction id (tid) in i_datasync_tid or i_sync_tid, it's possible that after a very large (2**31) number of transactions, that the tid number space might wrap, causing tid_geq()'s calculations to fail.
Commit deeeaf13 "jbd2: fix fsync() tid wraparound bug", later modified by commit e7b04ac0 "jbd2: don't wake kjournald unnecessarily", attempted to fix this problem, but it only avoided kjournald spinning forever by fixing the logic in jbd2_log_start_commit().
Unfortunately, in the codepaths in fs/ext4/fsync.c and fs/ext4/inode.c that might call jbd2_log_start_commit() with a stale tid, those functions will subsequently call jbd2_log_wait_commit() with the same stale tid, and then wait for a very long time. To fix this, we replace the calls to jbd2_log_start_commit() and jbd2_log_wait_commit() with a call to a new function, jbd2_complete_transaction(), which will correctly handle stale tid's.
As a bonus, jbd2_complete_transaction() will avoid locking j_state_lock for writing unless a commit needs to be started. This should have a small (but probably not measurable) improvement for ext4's scalability.
--- fs/ext4/fsync.c | 3 +-- fs/ext4/inode.c | 3 +-- fs/jbd2/journal.c | 31 +++++++++++++++++++++++++++++++ include/linux/jbd2.h | 1 + 4 files changed, 34 insertions(+), 4 deletions(-)
fs/ext4/fsync.c +1 -2
@@ -260,8 +260,7 @@ int ext4_sync_file(struct file *file, loif (journal->j_flags &JBD2_BARRIER && !jbd2_trans_will_send_data_barrier (journal, commit_tid)) needs_barrier = true; -jbd2_log_start_commit (journal, commit_tid); - ret =jbd2_log_wait_commit (journal, commit_tid); + ret =jbd2_complete_transaction (journal, commit_tid);if (needs_barrier)blkdev_issue_flush (inode->i_sb->s_bdev,GFP_KERNEL ,NULL ); out:
fs/ext4/inode.c +1 -2
@@ -149,8 +149,7 @@ void ext4_evict_inode(struct inode *inodjournal_t *journal =EXT4_SB (inode->i_sb)->s_journal;tid_t commit_tid =EXT4_I (inode)->i_datasync_tid; -jbd2_log_start_commit (journal, commit_tid); -jbd2_log_wait_commit (journal, commit_tid); +jbd2_complete_transaction (journal, commit_tid);filemap_write_and_wait (&inode->i_data); }truncate_inode_pages (&inode->i_data,0 );
fs/jbd2/journal.c +31 -0
@@ -662,6 +662,37 @@ int jbd2_log_wait_commit(journal_t *jour }/* +* When this function returns the transaction corresponding to tid +* will be completed. If the transaction has currently running, start +* committing that transaction before waiting for it to complete. If +* the transaction id is stale, it is by definition already completed, +* so just return SUCCESS. +*/ +int jbd2_complete_transaction (journal_t *journal,tid_t tid) +{ +int need_to_wait =1 ; + +read_lock (&journal->j_state_lock); +if (journal->j_running_transaction && + journal->j_running_transaction->t_tid == tid) { +if (journal->j_commit_request != tid) { +/* transaction not yet started, so request it */ +read_unlock (&journal->j_state_lock); +jbd2_log_start_commit (journal, tid); + goto wait_commit; + } + }else if (!(journal->j_committing_transaction && + journal->j_committing_transaction->t_tid == tid)) + need_to_wait =0 ; +read_unlock (&journal->j_state_lock); +if (!need_to_wait) +return 0 ; +wait_commit: +return jbd2_log_wait_commit (journal, tid); +} +EXPORT_SYMBOL (jbd2_complete_transaction); + +/* * Log buffer allocation routines: */
include/linux/jbd2.h +1 -0
@@ -1178,6 +1178,7 @@ int __jbd2_log_start_commit(journal_t *jint jbd2_journal_start_commit (journal_t *journal,tid_t *tid);int jbd2_journal_force_commit_nested (journal_t *journal);int jbd2_log_wait_commit (journal_t *journal,tid_t tid); +int jbd2_complete_transaction (journal_t *journal,tid_t tid);int jbd2_log_do_checkpoint (journal_t *journal);int jbd2_trans_will_send_data_barrier (journal_t *journal,tid_t tid);
Greg Kroah-Hartman
maintainerPATCH 61/99 UBIFS: fix double free of ubifs_orphan objects
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adam Thomas <[email protected]>
commit 8afd500cb52a5d00bab4525dd5a560d199f979b9 upstream.
The last orphan in the dnext list has its dnext set to NULL. Because of that, ubifs_delete_orphan assumes that it is not on the dnext list and frees it immediately instead ignoring it as a second delete. The orphan is later freed again by erase_deleted.
This change adds an explicit flag to ubifs_orphan indicating whether it is pending delete.
--- fs/ubifs/orphan.c | 5 ++++- fs/ubifs/ubifs.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-)
fs/ubifs/orphan.c +4 -1
@@ -130,13 +130,14 @@ void ubifs_delete_orphan(struct ubifs_inelse if (inum > o->inum) p = p->rb_right;else { -if (o->dnext) { +if (o->del) {spin_unlock (&c->orphan_lock);dbg_gen ("deleted twice ino %lu" , (unsigned long )inum);return ; }if (o->cnext) { + o->del =1 ; o->dnext = c->orph_dnext; c->orph_dnext = o;spin_unlock (&c->orphan_lock);
@@ -447,6 +448,7 @@ static void erase_deleted(struct ubifs_i orphan = dnext; dnext = orphan->dnext;ubifs_assert (!orphan->new); +ubifs_assert (orphan->del);rb_erase (&orphan->rb, &c->orph_tree);list_del (&orphan->list); c->tot_orphans -=1 ;
@@ -536,6 +538,7 @@ static int insert_dead_orphan(struct ubirb_link_node (&orphan->rb, parent, p);rb_insert_color (&orphan->rb, &c->orph_tree);list_add_tail (&orphan->list, &c->orph_list); + orphan->del =1 ; orphan->dnext = c->orph_dnext; c->orph_dnext = orphan; dbg_mnt("ino %lu, new %d, tot %d", (unsigned long)inum,
fs/ubifs/ubifs.h +2 -0
@@ -905,6 +905,7 @@ struct ubifs_budget_req {* @dnext: next orphan to delete * @inum: inode number * @new: %1 => added since the last commit, otherwise %0 +* @del: %1 => delete pending, otherwise %0 */ struct ubifs_orphan {struct rb_node rb;
@@ -914,6 +915,7 @@ struct ubifs_orphan {struct ubifs_orphan *dnext;ino_t inum;int new; + unsigned del:1; };/**
Greg Kroah-Hartman
maintainerPATCH 62/99 ext4: fix possible use-after-free with AIO
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 091e26dfc156aeb3b73bc5c5f277e433ad39331c upstream.
Running AIO is pinning inode in memory using file reference. Once AIO is completed using aio_complete(), file reference is put and inode can be freed from memory. So we have to be sure that calling aio_complete() is the last thing we do with the inode.
--- fs/ext4/inode.c | 2 +- fs/ext4/page-io.c | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-)
fs/ext4/inode.c +1 -1
@@ -2800,9 +2800,9 @@ static void ext4_end_io_dio(struct kiocbif (!(io_end->flag &EXT4_IO_END_UNWRITTEN )) {ext4_free_io_end (io_end); out: +inode_dio_done (inode);if (is_async)aio_complete (iocb, ret,0 ); -inode_dio_done (inode);return ; }
fs/ext4/page-io.c +4 -5
@@ -107,14 +107,13 @@ int ext4_end_io_nolock(ext4_io_end_t *io inode->i_ino, offset, size, ret); } -if (io->iocb) -aio_complete (io->iocb, io->result,0 ); - -if (io->flag &EXT4_IO_END_DIRECT ) -inode_dio_done (inode);/* Wake up anyone waiting on unwritten extent conversion */ if (atomic_dec_and_test (&EXT4_I (inode)->i_aiodio_unwritten))wake_up_all (ext4_ioend_wq (io->inode)); +if (io->flag &EXT4_IO_END_DIRECT ) +inode_dio_done (inode); +if (io->iocb) +aio_complete (io->iocb, io->result,0 );return ret; }
Greg Kroah-Hartman
maintainerPATCH 63/99 cifs: adjust sequence number downward after signing NT_CANCEL request
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
commit 31efee60f489c759c341454d755a9fd13de8c03d upstream.
When a call goes out, the signing code adjusts the sequence number upward by two to account for the request and the response. An NT_CANCEL however doesn't get a response of its own, it just hurries the server along to get it to respond to the original request more quickly. Therefore, we must adjust the sequence number back down by one after signing a NT_CANCEL request.
--- fs/cifs/transport.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/cifs/transport.c +7 -0
@@ -511,6 +511,13 @@ send_nt_cancel(struct TCP_Server_Info *smutex_unlock (&server->srv_mutex);return rc; } + +/* +* The response to this call was already factored into the sequence +* number when the call went out, so we must adjust it back downward +* after signing here. +*/ + --server->sequence_number; rc =smb_send (server, in_buf,be32_to_cpu (in_buf->smb_buf_length));mutex_unlock (&server->srv_mutex);
Greg Kroah-Hartman
maintainerPATCH 64/99 nbd: correct disconnect behavior
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Clements <[email protected]>
commit c378f70adbc1bbecd9e6db145019f14b2f688c7c upstream.
Currently, when a disconnect is requested by the user (via NBD_DISCONNECT ioctl) the return from NBD_DO_IT is undefined (it is usually one of several error codes). This means that nbd-client does not know if a manual disconnect was performed or whether a network error occurred. Because of this, nbd-client's persist mode (which tries to reconnect after error, but not after manual disconnect) does not always work correctly.
This change fixes this by causing NBD_DO_IT to always return 0 if a user requests a disconnect. This means that nbd-client can correctly either persist the connection (if an error occurred) or disconnect (if the user requested it).
--- drivers/block/nbd.c | 8 +++++++- include/linux/nbd.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/block/nbd.c +7 -1
@@ -590,8 +590,11 @@ static int __nbd_ioctl(struct block_devinbd_cmd (&sreq) =NBD_CMD_DISC ;if (!nbd->sock)return -EINVAL ; + + nbd->disconnect =1 ; +nbd_send_req (nbd, &sreq); -return 0 ; +return 0 ; }case NBD_CLEAR_SOCK : {
@@ -620,6 +623,7 @@ static int __nbd_ioctl(struct block_devi nbd->sock =SOCKET_I (inode);if (max_part >0 ) bdev->bd_invalidated =1 ; + nbd->disconnect =0 ;/* we're connected now */ return 0 ; }else {fput (file);
@@ -691,6 +695,8 @@ static int __nbd_ioctl(struct block_deviset_capacity (nbd->disk,0 );if (max_part >0 )ioctl_by_bdev (bdev,BLKRRPART ,0 ); +if (nbd->disconnect)/* user requested, ignore socket errors */ +return 0 ;return nbd->harderror; }
include/linux/nbd.h +1 -0
@@ -68,6 +68,7 @@ struct nbd_device {u64 bytesize;pid_t pid;/* pid of nbd-client, if attached */ int xmit_timeout; + int disconnect; /* a disconnect has been requested by user */ };#endif
Greg Kroah-Hartman
maintainerPATCH 65/99 block: Dont access request after it might be freed
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roland Dreier <[email protected]>
commit 893d290f1d7496db97c9471bc352ad4a11dc8a25 upstream.
After we've done __elv_add_request() and __blk_run_queue() in blk_execute_rq_nowait(), the request might finish and be freed immediately. Therefore checking if the type is REQ_TYPE_PM_RESUME isn't safe afterwards, because if it isn't, rq might be gone. Instead, check beforehand and stash the result in a temporary.
This fixes crashes in blk_execute_rq_nowait() I get occasionally when running with lots of memory debugging options enabled -- I think this race is usually harmless because the window for rq to be reallocated is so small.
--- block/blk-exec.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
block/blk-exec.c +11 -1
@@ -49,8 +49,18 @@ void blk_execute_rq_nowait(struct reques rq_end_io_fn *done) {int where = at_head ?ELEVATOR_INSERT_FRONT :ELEVATOR_INSERT_BACK ; +bool is_pm_resume;WARN_ON (irqs_disabled ()); + + rq->rq_disk = bd_disk; + rq->end_io = done; +/* +* need to check this before __blk_run_queue(), because rq can +* be freed before that returns. +*/ + is_pm_resume = rq->cmd_type ==REQ_TYPE_PM_RESUME ; +spin_lock_irq (q->queue_lock);if (unlikely (blk_queue_dead (q))) {
@@ -66,7 +76,7 @@ void blk_execute_rq_nowait(struct reques__elv_add_request (q, rq, where);__blk_run_queue (q);/* the queue is stopped so it won't be run */ -if (rq->cmd_type ==REQ_TYPE_PM_RESUME ) +if (is_pm_resume) q->request_fn (q);spin_unlock_irq (q->queue_lock); }
Greg Kroah-Hartman
maintainerPATCH 66/99 ext4: return ENOMEM if sb_getblk() fails
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 860d21e2c585f7ee8a4ecc06f474fdc33c9474f4 upstream.
The only reason for sb_getblk() failing is if it can't allocate the buffer_head. So ENOMEM is more appropriate than EIO. In addition, make sure that the file system is marked as being inconsistent if sb_getblk() fails.
[xr: Backported to 3.4:
- Drop change to inline.c
- Call to ext4_ext_check() from ext4_ext_find_extent() is conditional]
--- fs/ext4/extents.c | 25 ++++++++++++++----------- fs/ext4/indirect.c | 9 ++++++--- fs/ext4/inode.c | 9 +++------ fs/ext4/mmp.c | 2 ++ fs/ext4/resize.c | 8 ++++---- fs/ext4/xattr.c | 3 ++- 6 files changed, 31 insertions(+), 25 deletions(-)
fs/ext4/extents.c +14 -11
@@ -670,6 +670,7 @@ ext4_ext_find_extent(struct inode *inodestruct ext4_extent_header *eh;struct buffer_head *bh;short int depth, i, ppos =0 , alloc =0 ; +int ret; eh =ext_inode_hdr (inode); depth =ext_depth (inode);
@@ -699,12 +700,15 @@ ext4_ext_find_extent(struct inode *inode path[ppos].p_ext =NULL ; bh =sb_getblk (inode->i_sb, path[ppos].p_block); -if (unlikely (!bh)) +if (unlikely (!bh)) { + ret = -ENOMEM ; goto err; + }if (!bh_uptodate_or_lock (bh)) {trace_ext4_ext_load_extent (inode, block, path[ppos].p_block); -if (bh_submit_read (bh) <0 ) { + ret =bh_submit_read (bh); +if (ret <0 ) {put_bh (bh); goto err; }
@@ -717,13 +721,15 @@ ext4_ext_find_extent(struct inode *inodeput_bh (bh);EXT4_ERROR_INODE (inode,"ppos %d > depth %d" , ppos, depth); + ret = -EIO ; goto err; } path[ppos].p_bh = bh; path[ppos].p_hdr = eh; i--; -if (need_to_validate &&ext4_ext_check (inode, eh, i)) + ret = need_to_validate ?ext4_ext_check (inode, eh, i) :0 ; +if (ret <0 ) goto err; }
@@ -745,7 +751,7 @@ err:ext4_ext_drop_refs (path);if (alloc)kfree (path); -return ERR_PTR (-EIO ); +return ERR_PTR (ret); }/*
@@ -900,7 +906,7 @@ static int ext4_ext_split(handle_t *hand } bh =sb_getblk (inode->i_sb, newblock);if (!bh) { - err = -EIO ; + err = -ENOMEM ; goto cleanup; }lock_buffer (bh);
@@ -972,7 +978,7 @@ static int ext4_ext_split(handle_t *hand newblock = ablocks[--a]; bh =sb_getblk (inode->i_sb, newblock);if (!bh) { - err = -EIO ; + err = -ENOMEM ; goto cleanup; }lock_buffer (bh);
@@ -1083,11 +1089,8 @@ static int ext4_ext_grow_indepth(handle_return err; bh =sb_getblk (inode->i_sb, newblock); -if (!bh) { - err = -EIO ; -ext4_std_error (inode->i_sb, err); -return err; - } +if (!bh) +return -ENOMEM ;lock_buffer (bh); err =ext4_journal_get_create_access (handle, bh);
fs/ext4/indirect.c +6 -3
@@ -145,6 +145,7 @@ static Indirect *ext4_get_branch(structstruct super_block *sb = inode->i_sb;Indirect *p = chain;struct buffer_head *bh; +int ret = -EIO ; *err =0 ;/* i_data is not going away, no lock needed */
@@ -153,8 +154,10 @@ static Indirect *ext4_get_branch(struct goto no_block;while (--depth) { bh =sb_getblk (sb,le32_to_cpu (p->key)); -if (unlikely (!bh)) +if (unlikely (!bh)) { + ret = -ENOMEM ; goto failure; + }if (!bh_uptodate_or_lock (bh)) {if (bh_submit_read (bh) <0 ) {
@@ -176,7 +179,7 @@ static Indirect *ext4_get_branch(structreturn NULL ; failure: - *err = -EIO ; + *err = ret; no_block:return p; }
@@ -470,7 +473,7 @@ static int ext4_alloc_branch(handle_t *h*/ bh =sb_getblk (inode->i_sb, new_blocks[n-1 ]);if (unlikely (!bh)) { - err = -EIO ; + err = -ENOMEM ; goto failed; }
fs/ext4/inode.c +3 -6
@@ -663,7 +663,7 @@ struct buffer_head *ext4_getblk(handle_t bh =sb_getblk (inode->i_sb, map.m_pblk);if (!bh) { - *errp = -EIO ; + *errp = -ENOMEM ;return NULL ; }if (map.m_flags &EXT4_MAP_NEW ) {
@@ -3461,11 +3461,8 @@ static int __ext4_get_inode_loc(struct i iloc->offset = (inode_offset % inodes_per_block) *EXT4_INODE_SIZE (sb); bh =sb_getblk (sb, block); -if (!bh) { -EXT4_ERROR_INODE_BLOCK (inode, block, -"unable to read itable block" ); -return -EIO ; - } +if (!bh) +return -ENOMEM ;if (!buffer_uptodate (bh)) {lock_buffer (bh);
fs/ext4/mmp.c +2 -0
@@ -41,6 +41,8 @@ static int read_mmp_block(struct super_b* is not blocked in the elevator. */ if (!*bh) *bh =sb_getblk (sb, mmp_block); +if (!*bh) +return -ENOMEM ;if (*bh) {get_bh (*bh);lock_buffer (*bh);
fs/ext4/resize.c +4 -4
@@ -315,7 +315,7 @@ static struct buffer_head *bclean(handle bh =sb_getblk (sb, blk);if (!bh) -return ERR_PTR (-EIO ); +return ERR_PTR (-ENOMEM );if ((err =ext4_journal_get_write_access (handle, bh))) {brelse (bh); bh =ERR_PTR (err);
@@ -392,7 +392,7 @@ static int set_flexbg_block_bitmap(struc bh =sb_getblk (sb, flex_gd->groups[group].block_bitmap);if (!bh) -return -EIO ; +return -ENOMEM ; err =ext4_journal_get_write_access (handle, bh);if (err)
@@ -470,7 +470,7 @@ static int setup_new_flex_group_blocks(s gdb =sb_getblk (sb, block);if (!gdb) { - err = -EIO ; + err = -ENOMEM ; goto out; }
@@ -991,7 +991,7 @@ static void update_backups(struct super_ bh =sb_getblk (sb, group * bpg + blk_off);if (!bh) { - err = -EIO ; + err = -ENOMEM ;break ; } ext4_debug("update metadata backup %#04lx\n",
fs/ext4/xattr.c +2 -1
@@ -840,16 +840,17 @@ inserted: new_bh =sb_getblk (sb, block);if (!new_bh) { + error = -ENOMEM ; getblk_failed:ext4_free_blocks (handle, inode,NULL , block,1 ,EXT4_FREE_BLOCKS_METADATA ); - error = -EIO ; goto cleanup; }lock_buffer (new_bh); error =ext4_journal_get_create_access (handle, new_bh);if (error) {unlock_buffer (new_bh); + error = -EIO ; goto getblk_failed; }memcpy (new_bh->b_data, s->base, new_bh->b_size);
Greg Kroah-Hartman
maintainerPATCH 67/99 saa7134: Fix unlocked snd_pcm_stop() call
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit e6355ad7b1c6f70e2f48ae159f5658b441ccff95 upstream.
snd_pcm_stop() must be called in the PCM substream lock context.
--- drivers/media/video/saa7134/saa7134-alsa.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/media/video/saa7134/saa7134-alsa.c +2 -0
@@ -172,7 +172,9 @@ static void saa7134_irq_alsa_done(structdprintk ("irq: overrun [full=%d/%d] - Blocks in %d\n" ,dev->dmasound.read_count, dev->dmasound.bufsize, dev->dmasound.blocks);spin_unlock (&dev->slock); +snd_pcm_stream_lock (dev->dmasound.substream);snd_pcm_stop (dev->dmasound.substream,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock (dev->dmasound.substream);return ; }
Greg Kroah-Hartman
maintainerPATCH 68/99 xen/boot: Disable BIOS SMP MP table search.
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Rzeszutek Wilk <[email protected]>
commit bd49940a35ec7d488ae63bd625639893b3385b97 upstream.
As the initial domain we are able to search/map certain regions of memory to harvest configuration data. For all low-level we use ACPI tables - for interrupts we use exclusively ACPI _PRT (so DSDT) and MADT for INT_SRC_OVR.
The SMP MP table is not used at all. As a matter of fact we do not even support machines that only have SMP MP but no ACPI tables.
Lets follow how Moorestown does it and just disable searching for BIOS SMP tables.
This also fixes an issue on HP Proliant BL680c G5 and DL380 G6:
9f->100 for 1:1 PTE
Freeing 9f-100 pfn range: 97 pages freed
1-1 mapping on 9f->100
.. snip..
e820: BIOS-provided physical RAM map:
Xen: [mem 0x0000000000000000-0x000000000009efff] usable
Xen: [mem 0x000000000009f400-0x00000000000fffff] reserved
Xen: [mem 0x0000000000100000-0x00000000cfd1dfff] usable
.. snip..
Scan for SMP in [mem 0x00000000-0x000003ff]
Scan for SMP in [mem 0x0009fc00-0x0009ffff]
Scan for SMP in [mem 0x000f0000-0x000fffff]
found SMP MP-table at [mem 0x000f4fa0-0x000f4faf] mapped at [ffff8800000f4fa0]
(XEN) mm.c:908:d0 Error getting mfn 100 (pfn 5555555555555555) from L1 entry 0000000000100461 for l1e_owner=0, pg_owner=0 (XEN) mm.c:4995:d0 ptwr_emulate: could not get_page_from_l1e()
BUG: unable to handle kernel NULL pointer dereference at (null) IP: [<ffffffff81ac07e2>] xen_set_pte_init+0x66/0x71 . snip.. Pid: 0, comm: swapper Not tainted 3.6.0-rc6upstream-00188-gb6fb969-dirty #2 HP ProLiant BL680c G5 .. snip.. Call Trace: [<ffffffff81ad31c6>] __early_ioremap+0x18a/0x248 [<ffffffff81624731>] ? printk+0x48/0x4a [<ffffffff81ad32ac>] early_ioremap+0x13/0x15 [<ffffffff81acc140>] get_mpc_size+0x2f/0x67 [<ffffffff81acc284>] smp_scan_config+0x10c/0x136 [<ffffffff81acc2e4>] default_find_smp_config+0x36/0x5a [<ffffffff81ac3085>] setup_arch+0x5b3/0xb5b [<ffffffff81624731>] ? printk+0x48/0x4a [<ffffffff81abca7f>] start_kernel+0x90/0x390 [<ffffffff81abc356>] x86_64_start_reservations+0x131/0x136 [<ffffffff81abfa83>] xen_start_kernel+0x65f/0x661
(XEN) Domain 0 crashed: 'noreboot' set - not rebooting.
which is that ioremap would end up mapping 0xff using _PAGE_IOMAP (which is what early_ioremap sticks as a flag) - which meant we would get MFN 0xFF (pte ff461, which is OK), and then it would also map 0x100 (b/c ioremap tries to get page aligned request, and it was trying to map 0xf4fa0 + PAGE_SIZE - so it mapped the next page) as _PAGE_IOMAP. Since 0x100 is actually a RAM page, and the _PAGE_IOMAP bypasses the P2M lookup we would happily set the PTE to 1000461. Xen would deny the request since we do not have access to the Machine Frame Number (MFN) of 0x100. The P2M[0x100] is for example 0x80140.
Fixes-Oracle-Bugzilla: https://bugzilla.oracle.com/bugzilla/show_bug.cgi?id=13665
--- arch/x86/xen/enlighten.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/x86/xen/enlighten.c +4 -0
@@ -1448,6 +1448,10 @@ asmlinkage void __init xen_start_kernel(/* Make sure ACS will be enabled */ pci_request_acs (); + +/* Avoid searching for BIOS MP tables */ + x86_init.mpparse.find_smp_config = x86_init_noop; + x86_init.mpparse.get_smp_config = x86_init_uint_noop; }#ifdef CONFIG_PCI /* PCI BIOS service won't work from a PV guest. */
Greg Kroah-Hartman
maintainerPATCH 69/99 xen/smp: Fix leakage of timer interrupt line for every CPU online/offline.
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Rzeszutek Wilk <[email protected]>
commit 888b65b4bc5e7fcbbb967023300cd5d44dba1950 upstream.
In the PVHVM path when we do CPU online/offline path we would leak the timer%d IRQ line everytime we do a offline event. The online path (xen_hvm_setup_cpu_clockevents via x86_cpuinit.setup_percpu_clockev) would allocate a new interrupt line for the timer%d.
But we would still use the old interrupt line leading to:
kernel BUG at /home/konrad/ssd/konrad/linux/kernel/hrtimer.c:1261! invalid opcode: 0000 [#1] SMP
RIP: 0010:[<ffffffff810b9e21>] [<ffffffff810b9e21>] hrtimer_interrupt+0x261/0x270 .. snip.. <IRQ> [<ffffffff810445ef>] xen_timer_interrupt+0x2f/0x1b0 [<ffffffff81104825>] ? stop_machine_cpu_stop+0xb5/0xf0 [<ffffffff8111434c>] handle_irq_event_percpu+0x7c/0x240 [<ffffffff811175b9>] handle_percpu_irq+0x49/0x70 [<ffffffff813a74a3>] __xen_evtchn_do_upcall+0x1c3/0x2f0 [<ffffffff813a760a>] xen_evtchn_do_upcall+0x2a/0x40 [<ffffffff8167c26d>] xen_hvm_callback_vector+0x6d/0x80 <EOI> [<ffffffff81666d01>] ? start_secondary+0x193/0x1a8 [<ffffffff81666cfd>] ? start_secondary+0x18f/0x1a8
There is also the oddity (timer1) in the /proc/interrupts after offlining CPU1:
64: 1121 0 xen-percpu-virq timer0 78: 0 0 xen-percpu-virq timer1 84: 0 2483 xen-percpu-virq timer2
This patch fixes it.
--- arch/x86/xen/smp.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/xen/smp.c +1 -0
@@ -576,6 +576,7 @@ static void xen_hvm_cpu_die(unsigned intunbind_from_irqhandler (per_cpu (xen_callfunc_irq, cpu),NULL );unbind_from_irqhandler (per_cpu (xen_debug_irq, cpu),NULL );unbind_from_irqhandler (per_cpu (xen_callfuncsingle_irq, cpu),NULL ); +xen_teardown_timer (cpu);native_cpu_die (cpu); }
Greg Kroah-Hartman
maintainerPATCH 70/99 xen/smp/spinlock: Fix leakage of the spinlock interrupt line for every CPU online/offline
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Rzeszutek Wilk <[email protected]>
commit 66ff0fe9e7bda8aec99985b24daad03652f7304e upstream.
While we don't use the spinlock interrupt line (see for details commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 -
xen: disable PV spinlocks on HVM) - we should still do the proper init / deinit sequence. We did not do that correctly and for the CPU init for PVHVM guest we would allocate an interrupt line - but failed to deallocate the old interrupt line.
This resulted in leakage of an irq_desc but more importantly this splat as we online an offlined CPU:
genirq: Flags mismatch irq 71. 0002cc20 (spinlock1) vs. 0002cc20 (spinlock1)
Pid: 2542, comm: init.late Not tainted 3.9.0-rc6upstream #1
Call Trace: [<ffffffff811156de>] __setup_irq+0x23e/0x4a0 [<ffffffff81194191>] ? kmem_cache_alloc_trace+0x221/0x250 [<ffffffff811161bb>] request_threaded_irq+0xfb/0x160 [<ffffffff8104c6f0>] ? xen_spin_trylock+0x20/0x20 [<ffffffff813a8423>] bind_ipi_to_irqhandler+0xa3/0x160 [<ffffffff81303758>] ? kasprintf+0x38/0x40 [<ffffffff8104c6f0>] ? xen_spin_trylock+0x20/0x20 [<ffffffff810cad35>] ? update_max_interval+0x15/0x40 [<ffffffff816605db>] xen_init_lock_cpu+0x3c/0x78 [<ffffffff81660029>] xen_hvm_cpu_notify+0x29/0x33 [<ffffffff81676bdd>] notifier_call_chain+0x4d/0x70 [<ffffffff810bb2a9>] __raw_notifier_call_chain+0x9/0x10 [<ffffffff8109402b>] __cpu_notify+0x1b/0x30 [<ffffffff8166834a>] _cpu_up+0xa0/0x14b [<ffffffff816684ce>] cpu_up+0xd9/0xec [<ffffffff8165f754>] store_online+0x94/0xd0 [<ffffffff8141d15b>] dev_attr_store+0x1b/0x20 [<ffffffff81218f44>] sysfs_write_file+0xf4/0x170 [<ffffffff811a2864>] vfs_write+0xb4/0x130 [<ffffffff811a302a>] sys_write+0x5a/0xa0 [<ffffffff8167ada9>] system_call_fastpath+0x16/0x1b
cpu 1 spinlock event irq -16
smpboot: Booting Node 0 Processor 1 APIC 0x2
And if one looks at the /proc/interrupts right after offlining (CPU1):
70: 0 0 xen-percpu-ipi spinlock0 71: 0 0 xen-percpu-ipi spinlock1 77: 0 0 xen-percpu-ipi spinlock2
There is the oddity of the 'spinlock1' still being present.
--- arch/x86/xen/smp.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/xen/smp.c +1 -0
@@ -576,6 +576,7 @@ static void xen_hvm_cpu_die(unsigned intunbind_from_irqhandler (per_cpu (xen_callfunc_irq, cpu),NULL );unbind_from_irqhandler (per_cpu (xen_debug_irq, cpu),NULL );unbind_from_irqhandler (per_cpu (xen_callfuncsingle_irq, cpu),NULL ); +xen_uninit_lock_cpu (cpu);xen_teardown_timer (cpu);native_cpu_die (cpu); }
Greg Kroah-Hartman
maintainerPATCH 71/99 xen-netback: fix sparse warning
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: stephen hemminger <[email protected]>
commit 9eaee8beeeb3bca0d9b14324fd9d467d48db784c upstream.
Fix warning about 0 used as NULL.
--- drivers/net/xen-netback/netback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/xen-netback/netback.c +1 -1
@@ -1522,7 +1522,7 @@ static void xen_netbk_idx_release(structxenvif_put (vif); - netbk->mmap_pages[pending_idx]->mapping =0 ; + netbk->mmap_pages[pending_idx]->mapping =NULL ;put_page (netbk->mmap_pages[pending_idx]); netbk->mmap_pages[pending_idx] =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 72/99 xen-netback: coalesce slots in TX path and fix regressions
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Liu <[email protected]>
commit 2810e5b9a7731ca5fce22bfbe12c96e16ac44b6f upstream.
This patch tries to coalesce tx requests when constructing grant copy structures. It enables netback to deal with situation when frontend's MAX_SKB_FRAGS is larger than backend's MAX_SKB_FRAGS.
With the help of coalescing, this patch tries to address two regressions avoid reopening the security hole in XSA-39.
Regression 1. The reduction of the number of supported ring entries (slots) per packet (from 18 to 17). This regression has been around for some time but remains unnoticed until XSA-39 security fix. This is fixed by coalescing slots.
Regression 2. The XSA-39 security fix turning "too many frags" errors from just dropping the packet to a fatal error and disabling the VIF. This is fixed by coalescing slots (handling 18 slots when backend's MAX_SKB_FRAGS is 17) which rules out false positive (using 18 slots is legit) and dropping packets using 19 to max_skb_slots slots.
To avoid reopening security hole in XSA-39, frontend sending packet using more than max_skb_slots is considered malicious.
The behavior of netback for packet is thus:
1-18 slots: valid
19-max_skb_slots slots: drop and respond with an error
max_skb_slots+ slots: fatal error
max_skb_slots is configurable by admin, default value is 20.
Also change variable name from "frags" to "slots" in netbk_count_requests.
Please note that RX path still has dependency on MAX_SKB_FRAGS. This will be fixed with separate patch.
--- drivers/net/xen-netback/netback.c | 273 +++++++++++++++++++++++++++++++------- include/xen/interface/io/netif.h | 18 ++ 2 files changed, 241 insertions(+), 50 deletions(-)
drivers/net/xen-netback/netback.c +223 -50
@@ -46,11 +46,25 @@#include <asm/xen/hypercall.h> #include <asm/xen/page.h> +/* +* This is the maximum slots a skb can have. If a guest sends a skb +* which exceeds this limit it is considered malicious. +*/ +#define MAX_SKB_SLOTS_DEFAULT 20 +static unsigned int max_skb_slots =MAX_SKB_SLOTS_DEFAULT ; +module_param (max_skb_slots, uint,0444 ); + +typedef unsigned int pending_ring_idx_t ; +#define INVALID_PENDING_RING_IDX (~0U) +struct pending_tx_info { -struct xen_netif_tx_request req; +struct xen_netif_tx_request req;/* coalesced tx request */ struct xenvif *vif; +pending_ring_idx_t head;/* head != INVALID_PENDING_RING_IDX +* if it is head of one or more tx +* reqs +*/ }; -typedef unsigned int pending_ring_idx_t ;struct netbk_rx_meta {int id;
@@ -101,7 +115,11 @@ struct xen_netbk {atomic_t netfront_count;struct pending_tx_info pending_tx_info[MAX_PENDING_REQS ]; -struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS ]; +/* Coalescing tx requests before copying makes number of grant +* copy ops greater or equal to number of slots required. In +* worst case a tx request consumes 2 gnttab_copy. +*/ +struct gnttab_copy tx_copy_ops[2 *MAX_PENDING_REQS ];u16 pending_ring[MAX_PENDING_REQS ];
@@ -117,6 +135,16 @@ struct xen_netbk {static struct xen_netbk *xen_netbk;static int xen_netbk_group_nr; +/* +* If head != INVALID_PENDING_RING_IDX, it means this tx request is head of +* one or more merged tx requests, otherwise it is the continuation of +* previous tx request. +*/ +static inline int pending_tx_is_head (struct xen_netbk *netbk,RING_IDX idx) +{ +return netbk->pending_tx_info[idx].head !=INVALID_PENDING_RING_IDX ; +} +void xen_netbk_add_xenvif (struct xenvif *vif) {int i;
@@ -249,6 +277,7 @@ static int max_required_rx_slots(struct {int max =DIV_ROUND_UP (vif->dev->mtu,PAGE_SIZE ); +/* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */ if (vif->can_sg || vif->gso || vif->gso_prefix) max +=MAX_SKB_FRAGS +1 ;/* extra_info + frags */
@@ -627,6 +656,7 @@ static void xen_netbk_rx_action(struct x__skb_queue_tail (&rxq, skb);/* Filled the batch queue? */ +/* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */ if (count +MAX_SKB_FRAGS >=XEN_NETIF_RX_RING_SIZE )break ; }
@@ -870,47 +900,78 @@ static void netbk_fatal_tx_err(struct xestatic int netbk_count_requests (struct xenvif *vif,struct xen_netif_tx_request *first, +RING_IDX first_idx,struct xen_netif_tx_request *txp,int work_to_do) {RING_IDX cons = vif->tx.req_cons; -int frags =0 ; +int slots =0 ; +int drop_err =0 ;if (!(first->flags & XEN_NETTXF_more_data))return 0 ;do { -if (frags >= work_to_do) { -netdev_err (vif->dev,"Need more frags\n" ); +if (slots >= work_to_do) { +netdev_err (vif->dev, +"Asked for %d slots but exceeds this limit\n" , + work_to_do);netbk_fatal_tx_err (vif);return -ENODATA ; } -if (unlikely (frags >=MAX_SKB_FRAGS )) { -netdev_err (vif->dev,"Too many frags\n" ); +/* This guest is really using too many slots and +* considered malicious. +*/ +if (unlikely (slots >= max_skb_slots)) { +netdev_err (vif->dev, +"Malicious frontend using %d slots, threshold %u\n" , + slots, max_skb_slots);netbk_fatal_tx_err (vif);return -E2BIG ; } -memcpy (txp,RING_GET_REQUEST (&vif->tx, cons + frags), +/* Xen network protocol had implicit dependency on +* MAX_SKB_FRAGS. XEN_NETIF_NR_SLOTS_MIN is set to the +* historical MAX_SKB_FRAGS value 18 to honor the same +* behavior as before. Any packet using more than 18 +* slots but less than max_skb_slots slots is dropped +*/ +if (!drop_err && slots >=XEN_NETIF_NR_SLOTS_MIN ) { +if (net_ratelimit ()) +netdev_dbg (vif->dev, +"Too many slots (%d) exceeding limit (%d), dropping packet\n" , + slots,XEN_NETIF_NR_SLOTS_MIN ); + drop_err = -E2BIG ; + } + +memcpy (txp,RING_GET_REQUEST (&vif->tx, cons + slots),sizeof (*txp));if (txp->size > first->size) { -netdev_err (vif->dev,"Frag is bigger than frame.\n" ); +netdev_err (vif->dev, +"Invalid tx request, slot size %u > remaining size %u\n" , + txp->size, first->size);netbk_fatal_tx_err (vif);return -EIO ; } first->size -= txp->size; - frags++; + slots++;if (unlikely ((txp->offset + txp->size) >PAGE_SIZE )) { -netdev_err (vif->dev,"txp->offset: %x, size: %u\n" , +netdev_err (vif->dev,"Cross page boundary, txp->offset: %x, size: %u\n" , txp->offset, txp->size);netbk_fatal_tx_err (vif);return -EINVAL ; } }while ((txp++)->flags & XEN_NETTXF_more_data); -return frags; + +if (drop_err) { +netbk_tx_err (vif, first, first_idx + slots); +return drop_err; + } + +return slots; } static struct page *xen_netbk_alloc_page(struct xen_netbk *netbk,
@@ -934,48 +995,114 @@ static struct gnttab_copy *xen_netbk_getstruct skb_shared_info *shinfo =skb_shinfo (skb);skb_frag_t *frags = shinfo->frags;u16 pending_idx = *((u16 *)skb->data); -int i, start; +u16 head_idx =0 ; +int slot, start; +struct page *page; +pending_ring_idx_t index, start_idx =0 ; +uint16_t dst_offset; +unsigned int nr_slots; +struct pending_tx_info *first =NULL ; + +/* At this point shinfo->nr_frags is in fact the number of +* slots, which can be as large as XEN_NETIF_NR_SLOTS_MIN. +*/ + nr_slots = shinfo->nr_frags;/* Skip first skb fragment if it is on same page as header fragment. */ start = (frag_get_pending_idx (&shinfo->frags[0 ]) == pending_idx); -for (i = start; i < shinfo->nr_frags; i++, txp++) { -struct page *page; -pending_ring_idx_t index; +/* Coalesce tx requests, at this point the packet passed in +* should be <= 64K. Any packets larger than 64K have been +* handled in netbk_count_requests(). +*/ +for (shinfo->nr_frags = slot = start; slot < nr_slots; + shinfo->nr_frags++) {struct pending_tx_info *pending_tx_info = netbk->pending_tx_info; - index =pending_index (netbk->pending_cons++); - pending_idx = netbk->pending_ring[index]; - page =xen_netbk_alloc_page (netbk, pending_idx); + page =alloc_page (GFP_KERNEL |__GFP_COLD);if (!page) goto err; - gop->source.u.ref = txp->gref; - gop->source.domid = vif->domid; - gop->source.offset = txp->offset; + dst_offset =0 ; + first =NULL ; +while (dst_offset <PAGE_SIZE && slot < nr_slots) { + gop->flags = GNTCOPY_source_gref; + + gop->source.u.ref = txp->gref; + gop->source.domid = vif->domid; + gop->source.offset = txp->offset; + + gop->dest.domid =DOMID_SELF ; + + gop->dest.offset = dst_offset; + gop->dest.u.gmfn =virt_to_mfn (page_address (page)); + +if (dst_offset + txp->size >PAGE_SIZE ) { +/* This page can only merge a portion +* of tx request. Do not increment any +* pointer / counter here. The txp +* will be dealt with in future +* rounds, eventually hitting the +* `else` branch. +*/ + gop->len =PAGE_SIZE - dst_offset; + txp->offset += gop->len; + txp->size -= gop->len; + dst_offset += gop->len;/* quit loop */ + }else { +/* This tx request can be merged in the page */ + gop->len = txp->size; + dst_offset += gop->len; + + index =pending_index (netbk->pending_cons++); + + pending_idx = netbk->pending_ring[index]; + +memcpy (&pending_tx_info[pending_idx].req, txp, +sizeof (*txp)); +xenvif_get (vif); + + pending_tx_info[pending_idx].vif = vif; + +/* Poison these fields, corresponding +* fields for head tx req will be set +* to correct values after the loop. +*/ + netbk->mmap_pages[pending_idx] = (void *)(~0UL ); + pending_tx_info[pending_idx].head = +INVALID_PENDING_RING_IDX ; + +if (!first) { + first = &pending_tx_info[pending_idx]; + start_idx = index; + head_idx = pending_idx; + } - gop->dest.u.gmfn =virt_to_mfn (page_address (page)); - gop->dest.domid =DOMID_SELF ; - gop->dest.offset = txp->offset; - - gop->len = txp->size; - gop->flags = GNTCOPY_source_gref; + txp++; + slot++; + } - gop++; + gop++; + } -memcpy (&pending_tx_info[pending_idx].req, txp,sizeof (*txp)); -xenvif_get (vif); - pending_tx_info[pending_idx].vif = vif; -frag_set_pending_idx (&frags[i], pending_idx); + first->req.offset =0 ; + first->req.size = dst_offset; + first->head = start_idx; +set_page_ext (page, netbk, head_idx); + netbk->mmap_pages[head_idx] = page; +frag_set_pending_idx (&frags[shinfo->nr_frags], head_idx); } +BUG_ON (shinfo->nr_frags >MAX_SKB_FRAGS ); +return gop; err:/* Unwind, freeing all pages and sending error responses. */ -while (i-- > start) { -xen_netbk_idx_release (netbk,frag_get_pending_idx (&frags[i]), -XEN_NETIF_RSP_ERROR ); +while (shinfo->nr_frags-- > start) { +xen_netbk_idx_release (netbk, +frag_get_pending_idx (&frags[shinfo->nr_frags]), +XEN_NETIF_RSP_ERROR ); }/* The head too, if necessary. */ if (start)
@@ -991,8 +1118,10 @@ static int xen_netbk_tx_check_gop(structstruct gnttab_copy *gop = *gopp;u16 pending_idx = *((u16 *)skb->data);struct skb_shared_info *shinfo =skb_shinfo (skb); +struct pending_tx_info *tx_info;int nr_frags = shinfo->nr_frags;int i, err, start; +u16 peek;/* peek into next tx request */ /* Check status of header. */ err = gop->status;
@@ -1004,11 +1133,20 @@ static int xen_netbk_tx_check_gop(structfor (i = start; i < nr_frags; i++) {int j, newerr; +pending_ring_idx_t head; pending_idx =frag_get_pending_idx (&shinfo->frags[i]); + tx_info = &netbk->pending_tx_info[pending_idx]; + head = tx_info->head;/* Check error status: if okay then remember grant handle. */ - newerr = (++gop)->status; +do { + newerr = (++gop)->status; +if (newerr) +break ; + peek = netbk->pending_ring[pending_index (++head)]; + }while (!pending_tx_is_head (netbk, peek)); +if (likely (!newerr)) {/* Had a previous error? Invalidate this fragment. */ if (unlikely (err))
@@ -1233,11 +1371,12 @@ static unsigned xen_netbk_tx_build_gops(struct sk_buff *skb;int ret; -while (((nr_pending_reqs (netbk) +MAX_SKB_FRAGS ) <MAX_PENDING_REQS ) && +while ((nr_pending_reqs (netbk) +XEN_NETIF_NR_SLOTS_MIN + <MAX_PENDING_REQS ) && !list_empty (&netbk->net_schedule_list)) {struct xenvif *vif;struct xen_netif_tx_request txreq; -struct xen_netif_tx_request txfrags[MAX_SKB_FRAGS ]; +struct xen_netif_tx_request txfrags[max_skb_slots];struct page *page;struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX -1 ];u16 pending_idx;
@@ -1298,7 +1437,8 @@ static unsigned xen_netbk_tx_build_gops(continue ; } - ret =netbk_count_requests (vif, &txreq, txfrags, work_to_do); + ret =netbk_count_requests (vif, &txreq, idx, + txfrags, work_to_do);if (unlikely (ret <0 ))continue ;
@@ -1325,7 +1465,7 @@ static unsigned xen_netbk_tx_build_gops( pending_idx = netbk->pending_ring[index]; data_len = (txreq.size >PKT_PROT_LEN && - ret <MAX_SKB_FRAGS ) ? + ret <XEN_NETIF_NR_SLOTS_MIN ) ?PKT_PROT_LEN : txreq.size; skb = alloc_skb(data_len + NET_SKB_PAD + NET_IP_ALIGN,
@@ -1375,6 +1515,7 @@ static unsigned xen_netbk_tx_build_gops(memcpy (&netbk->pending_tx_info[pending_idx].req, &txreq,sizeof (txreq)); netbk->pending_tx_info[pending_idx].vif = vif; + netbk->pending_tx_info[pending_idx].head = index; *((u16 *)skb->data) = pending_idx;__skb_put (skb, data_len);
@@ -1505,7 +1646,10 @@ static void xen_netbk_idx_release(struct {struct xenvif *vif;struct pending_tx_info *pending_tx_info; -pending_ring_idx_t index; +pending_ring_idx_t head; +u16 peek;/* peek into next tx request */ + +BUG_ON (netbk->mmap_pages[pending_idx] == (void *)(~0UL ));/* Already complete? */ if (netbk->mmap_pages[pending_idx] ==NULL )
@@ -1514,19 +1658,40 @@ static void xen_netbk_idx_release(struct pending_tx_info = &netbk->pending_tx_info[pending_idx]; vif = pending_tx_info->vif; + head = pending_tx_info->head; -make_tx_response (vif, &pending_tx_info->req, status); +BUG_ON (!pending_tx_is_head (netbk, head)); +BUG_ON (netbk->pending_ring[pending_index (head)] != pending_idx); - index =pending_index (netbk->pending_prod++); - netbk->pending_ring[index] = pending_idx; +do { +pending_ring_idx_t index; +pending_ring_idx_t idx =pending_index (head); +u16 info_idx = netbk->pending_ring[idx]; -xenvif_put (vif); + pending_tx_info = &netbk->pending_tx_info[info_idx]; +make_tx_response (vif, &pending_tx_info->req, status); - netbk->mmap_pages[pending_idx]->mapping =NULL ; +/* Setting any number other than +* INVALID_PENDING_RING_IDX indicates this slot is +* starting a new packet / ending a previous packet. +*/ + pending_tx_info->head =0 ; + + index =pending_index (netbk->pending_prod++); + netbk->pending_ring[index] = netbk->pending_ring[info_idx]; + +xenvif_put (vif); + + peek = netbk->pending_ring[pending_index (++head)]; + + }while (!pending_tx_is_head (netbk, peek)); + + netbk->mmap_pages[pending_idx]->mapping =0 ;put_page (netbk->mmap_pages[pending_idx]); netbk->mmap_pages[pending_idx] =NULL ; } +static void make_tx_response (struct xenvif *vif,struct xen_netif_tx_request *txp,s8 st)
@@ -1579,8 +1744,9 @@ static inline int rx_work_todo(struct xestatic inline int tx_work_todo (struct xen_netbk *netbk) { -if (((nr_pending_reqs (netbk) +MAX_SKB_FRAGS ) <MAX_PENDING_REQS ) && - !list_empty (&netbk->net_schedule_list)) +if ((nr_pending_reqs (netbk) +XEN_NETIF_NR_SLOTS_MIN + <MAX_PENDING_REQS ) && + !list_empty (&netbk->net_schedule_list))return 1 ;return 0 ;
@@ -1663,6 +1829,13 @@ static int __init netback_init(void)if (!xen_domain ())return -ENODEV ; +if (max_skb_slots <XEN_NETIF_NR_SLOTS_MIN ) { +printk (KERN_INFO +"xen-netback: max_skb_slots too small (%d), bump it to XEN_NETIF_NR_SLOTS_MIN (%d)\n" , + max_skb_slots,XEN_NETIF_NR_SLOTS_MIN ); + max_skb_slots =XEN_NETIF_NR_SLOTS_MIN ; + } + xen_netbk_group_nr =num_online_cpus (); xen_netbk =vzalloc (sizeof (struct xen_netbk ) * xen_netbk_group_nr);if (!xen_netbk)
include/xen/interface/io/netif.h +18 -0
@@ -13,6 +13,24 @@#include "../grant_table.h" /* +* Older implementation of Xen network frontend / backend has an +* implicit dependency on the MAX_SKB_FRAGS as the maximum number of +* ring slots a skb can use. Netfront / netback may not work as +* expected when frontend and backend have different MAX_SKB_FRAGS. +* +* A better approach is to add mechanism for netfront / netback to +* negotiate this value. However we cannot fix all possible +* frontends, so we need to define a value which states the minimum +* slots backend must support. +* +* The minimum value derives from older Linux kernel's MAX_SKB_FRAGS +* (18), which is proved to work with most frontends. Any new backend +* which doesn't negotiate with frontend should expect frontend to +* send a valid packet using slots up to this value. +*/ +#define XEN_NETIF_NR_SLOTS_MIN 18 + +/* * Notifications after enqueuing any type of message should be conditional on * the appropriate req_event or rsp_event field in the shared ring. * If the client sends notification for rx requests then it should specify
Greg Kroah-Hartman
maintainerPATCH 73/99 xen-netback: dont disconnect frontend when seeing oversize packet
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Liu <[email protected]>
commit 03393fd5cc2b6cdeec32b704ecba64dbb0feae3c upstream.
Some frontend drivers are sending packets > 64 KiB in length. This length overflows the length field in the first slot making the following slots have an invalid length.
Turn this error back into a non-fatal error by dropping the packet. To avoid having the following slots having fatal errors, consume all slots in the packet.
This does not reopen the security hole in XSA-39 as if the packet as an invalid number of slots it will still hit fatal error case.
--- drivers/net/xen-netback/netback.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/net/xen-netback/netback.c +16 -6
@@ -947,12 +947,22 @@ static int netbk_count_requests(struct xmemcpy (txp,RING_GET_REQUEST (&vif->tx, cons + slots),sizeof (*txp)); -if (txp->size > first->size) { -netdev_err (vif->dev, -"Invalid tx request, slot size %u > remaining size %u\n" , - txp->size, first->size); -netbk_fatal_tx_err (vif); -return -EIO ; + +/* If the guest submitted a frame >= 64 KiB then +* first->size overflowed and following slots will +* appear to be larger than the frame. +* +* This cannot be fatal error as there are buggy +* frontends that do this. +* +* Consume all slots and drop the packet. +*/ +if (!drop_err && txp->size > first->size) { +if (net_ratelimit ()) +netdev_dbg (vif->dev, +"Invalid tx request, slot size %u > remaining size %u\n" , + txp->size, first->size); + drop_err = -EIO ; } first->size -= txp->size;
Greg Kroah-Hartman
maintainerPATCH 74/99 xen/io/ring.h: new macro to detect whether there are too many requests on the ring
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Beulich <[email protected]>
commit 8d9256906a97c24e97e016482b9be06ea2532b05 upstream.
Backends may need to protect themselves against an insane number of produced requests stored by a frontend, in case they iterate over requests until reaching the req_prod value. There can't be more requests on the ring than the difference between produced requests and produced (but possibly not yet published) responses.
This is a more strict alternative to a patch previously posted by Konrad Rzeszutek Wilk <[email protected]>.
--- include/xen/interface/io/ring.h | 5 +++++ 1 file changed, 5 insertions(+)
include/xen/interface/io/ring.h +5 -0
@@ -188,6 +188,11 @@ struct __name##_back_ring { \#define RING_REQUEST_CONS_OVERFLOW (_r, _cons) \ (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r)) +/* Ill-behaved frontend determination: Can there be this many requests? */ +#define RING_REQUEST_PROD_OVERFLOW (_r, _prod) \ + (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r)) + +#define RING_PUSH_REQUESTS (_r) do { \ wmb();/* back sees requests /before/ updated producer index */ \ (_r)->sring->req_prod = (_r)->req_prod_pvt; \
Greg Kroah-Hartman
maintainerPATCH 75/99 xen/blkback: Check for insane amounts of request on the ring (v6).
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Rzeszutek Wilk <[email protected]>
commit 9371cadbbcc7c00c81753b9727b19fb3bc74d458 upstream.
commit 8e3f8755545cc4a7f4da8e9ef76d6d32e0dca576 upstream.
Check that the ring does not have an insane amount of requests (more than there could fit on the ring).
If we detect this case we will stop processing the requests and wait until the XenBus disconnects the ring.
The existing check RING_REQUEST_CONS_OVERFLOW which checks for how many responses we have created in the past (rsp_prod_pvt) vs requests consumed (req_cons) and whether said difference is greater or equal to the size of the ring, does not catch this case.
Wha the condition does check if there is a need to process more as we still have a backlog of responses to finish. Note that both of those values (rsp_prod_pvt and req_cons) are not exposed on the shared ring.
To understand this problem a mini crash course in ring protocol response/request updates is in place.
There are four entries: req_prod and rsp_prod; req_event and rsp_event to track the ring entries. We are only concerned about the first two - which set the tone of this bug.
The req_prod is a value incremented by frontend for each request put on the ring. Conversely the rsp_prod is a value incremented by the backend for each response put on the ring (rsp_prod gets set by rsp_prod_pvt when pushing the responses on the ring). Both values can
wrap and are modulo the size of the ring (in block case that is 32). Please see RING_GET_REQUEST and RING_GET_RESPONSE for the more details.
The culprit here is that if the difference between the req_prod and req_cons is greater than the ring size we have a problem. Fortunately for us, the '__do_block_io_op' loop:
rc = blk_rings->common.req_cons;
rp = blk_rings->common.sring->req_prod;
while (rc != rp) {
..
blk_rings->common.req_cons = ++rc; /* before make_response() */
}will loop up to the point when rc == rp. The macros inside of the loop (RING_GET_REQUEST) is smart and is indexing based on the modulo of the ring size. If the frontend has provided a bogus req_prod value we will loop until the 'rc == rp' - which means we could be processing already processed requests (or responses) often.
The reason the RING_REQUEST_CONS_OVERFLOW is not helping here is b/c it only tracks how many responses we have internally produced and whether we would should process more. The astute reader will notice that the macro RING_REQUEST_CONS_OVERFLOW provides two arguments - more on this later.
For example, if we were to enter this function with these values:
blk_rings->common.sring->req_prod = X+31415 (X is the value from
the last time __do_block_io_op was called).
blk_rings->common.req_cons = X
blk_rings->common.rsp_prod_pvt = XThe RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, blk_rings->common.req_cons) is doing:
req_cons - rsp_prod_pvt >= 32
Which is,
X - X >= 32 or 0 >= 32
And that is false, so we continue on looping (this bug).
If we re-use said macro RING_REQUEST_CONS_OVERFLOW and pass in the rp instead (sring->req_prod) of rc, the this macro can do the check:
req_prod - rsp_prov_pvt >= 32
Which is,
X + 31415 - X >= 32 , or 31415 >= 32
which is true, so we can error out and break out of the function.
Unfortunatly the difference between rsp_prov_pvt and req_prod can be at 32 (which would error out in the macro). This condition exists when the backend is lagging behind with the responses and still has not finished responding to all of them (so make_response has not been called), and the rsp_prov_pvt + 32 == req_cons. This ends up with us not being able to use said macro.
Hence introducing a new macro called RING_REQUEST_PROD_OVERFLOW which does a simple check of:
req_prod - rsp_prod_pvt > RING_SIZE
And with the X values from above:
X + 31415 - X > 32
Returns true. Also not that if the ring is full (which is where the RING_REQUEST_CONS_OVERFLOW triggered), we would not hit the same condition:
X + 32 - X > 32
Which is false.
Lets use that macro.
Note that in v5 of this patchset the macro was different - we used an earlier version.
--- drivers/block/xen-blkback/blkback.c | 13 ++++++++++++- drivers/block/xen-blkback/common.h | 2 ++ drivers/block/xen-blkback/xenbus.c | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-)
drivers/block/xen-blkback/blkback.c +12 -1
@@ -274,6 +274,7 @@ int xen_blkif_schedule(void *arg) {struct xen_blkif *blkif = arg;struct xen_vbd *vbd = &blkif->vbd; +int ret;xen_blkif_get (blkif);
@@ -294,8 +295,12 @@ int xen_blkif_schedule(void *arg) blkif->waiting_reqs =0 ;smp_mb ();/* clear flag *before* checking for work */ -if (do_block_io_op (blkif)) + ret =do_block_io_op (blkif); +if (ret >0 ) blkif->waiting_reqs =1 ; +if (ret == -EACCES ) +wait_event_interruptible (blkif->shutdown_wq, +kthread_should_stop ());if (log_stats &&time_after (jiffies, blkif->st_print))print_stats (blkif);
@@ -531,6 +536,12 @@ __do_block_io_op(struct xen_blkif *blkif rp = blk_rings->common.sring->req_prod;rmb ();/* Ensure we see queued requests up to 'rp'. */ +if (RING_REQUEST_PROD_OVERFLOW (&blk_rings->common, rp)) { + rc = blk_rings->common.rsp_prod_pvt; +pr_warn (DRV_PFX "Frontend provided bogus ring requests (%d - %d = %d). Halting ring processing on dev=%04x\n" , + rp, rc, rp - rc, blkif->vbd.pdevice); +return -EACCES ; + }while (rc != rp) {if (RING_REQUEST_CONS_OVERFLOW (&blk_rings->common, rc))
drivers/block/xen-blkback/common.h +2 -0
@@ -216,6 +216,8 @@ struct xen_blkif {int st_wr_sect;wait_queue_head_t waiting_to_free; +/* Thread shutdown wait queue. */ +wait_queue_head_t shutdown_wq; };
drivers/block/xen-blkback/xenbus.c +2 -0
@@ -118,6 +118,7 @@ static struct xen_blkif *xen_blkif_allocatomic_set (&blkif->drain,0 ); blkif->st_print = jiffies;init_waitqueue_head (&blkif->waiting_to_free); +init_waitqueue_head (&blkif->shutdown_wq);return blkif; }
@@ -178,6 +179,7 @@ static void xen_blkif_disconnect(struct {if (blkif->xenblkd) {kthread_stop (blkif->xenblkd); +wake_up (&blkif->shutdown_wq); blkif->xenblkd =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 76/99 xen/events: mask events when changing their VCPU binding
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Vrabel <[email protected]>
commit 5e72fdb8d827560893642e85a251d339109a00f4 upstream.
commit 4704fe4f03a5ab27e3c36184af85d5000e0f8a48 upstream.
When a event is being bound to a VCPU there is a window between the EVTCHNOP_bind_vpcu call and the adjustment of the local per-cpu masks where an event may be lost. The hypervisor upcalls the new VCPU but the kernel thinks that event is still bound to the old VCPU and ignores it.
There is even a problem when the event is being bound to the same VCPU as there is a small window beween the clear_bit() and set_bit() calls in bind_evtchn_to_cpu(). When scanning for pending events, the kernel may read the bit when it is momentarily clear and ignore the event.
Avoid this by masking the event during the whole bind operation.
--- drivers/xen/events.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/xen/events.c +11 -0
@@ -1422,8 +1422,10 @@ void rebind_evtchn_irq(int evtchn, int i/* Rebind an evtchn so that it gets delivered to a specific cpu */ static int rebind_irq_to_cpu (unsigned irq,unsigned tcpu) { +struct shared_info *s = HYPERVISOR_shared_info;struct evtchn_bind_vcpu bind_vcpu;int evtchn =evtchn_from_irq (irq); +int masked;if (!VALID_EVTCHN (evtchn))return -1 ;
@@ -1440,6 +1442,12 @@ static int rebind_irq_to_cpu(unsigned ir bind_vcpu.vcpu = tcpu;/* +* Mask the event while changing the VCPU binding to prevent +* it being delivered on an unexpected VCPU. +*/ + masked =sync_test_and_set_bit (evtchn, s->evtchn_mask); + +/* * If this fails, it usually just indicates that we're dealing with a * virq or IPI channel, which don't actually need to be rebound. Ignore * it, but don't do the xenlinux-level rebind in that case.
@@ -1447,6 +1455,9 @@ static int rebind_irq_to_cpu(unsigned irif (HYPERVISOR_event_channel_op (EVTCHNOP_bind_vcpu, &bind_vcpu) >=0 )bind_evtchn_to_cpu (evtchn, tcpu); +if (!masked) +unmask_evtchn (evtchn); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 77/99 sunrpc: clarify comments on rpc_make_runnable
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
commit 506026c3ec270e18402f0c9d33fee37482c23861 upstream.
rpc_make_runnable is not generally called with the queue lock held, unless it's waking up a task that has been sitting on a waitqueue. This is safe when the task has not entered the FSM yet, but the comments don't really spell this out.
--- net/sunrpc/sched.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/sunrpc/sched.c +3 -2
@@ -302,8 +302,9 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_complet/* * Make an RPC task runnable. * -* Note: If the task is ASYNC, this must be called with -* the spinlock held to protect the wait queue operation. +* Note: If the task is ASYNC, and is being made runnable after sitting on an +* rpc_wait_queue, this must be called with the queue spinlock held to protect +* the wait queue operation. */ static void rpc_make_runnable (struct rpc_task *task) {
Greg Kroah-Hartman
maintainerPATCH 78/99 SUNRPC: Prevent an rpc_task wakeup race
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trond Myklebust <[email protected]>
commit a3c3cac5d31879cd9ae2de7874dc6544ca704aec upstream.
The lockless RPC_IS_QUEUED() test in __rpc_execute means that we need to be careful about ordering the calls to rpc_test_and_set_running(task) and rpc_clear_queued(task). If we get the order wrong, then we may end up testing the RPC_TASK_RUNNING flag after __rpc_execute() has looped and changed the state of the rpc_task.
--- net/sunrpc/sched.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/sunrpc/sched.c +7 -1
@@ -305,11 +305,17 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_complet* Note: If the task is ASYNC, and is being made runnable after sitting on an * rpc_wait_queue, this must be called with the queue spinlock held to protect * the wait queue operation. +* Note the ordering of rpc_test_and_set_running() and rpc_clear_queued(), +* which is needed to ensure that __rpc_execute() doesn't loop (due to the +* lockless RPC_IS_QUEUED() test) before we've had a chance to test +* the RPC_TASK_RUNNING flag. */ static void rpc_make_runnable (struct rpc_task *task) { +bool need_wakeup = !rpc_test_and_set_running (task); +rpc_clear_queued (task); -if (rpc_test_and_set_running (task)) +if (!need_wakeup)return ;if (RPC_IS_ASYNC (task)) {INIT_WORK (&task->u.tk_work, rpc_async_schedule);
Greg Kroah-Hartman
maintainerPATCH 79/99 ASoC: imx-ssi: Fix occasional AC97 reset failure
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sascha Hauer <[email protected]>
commit b6e51600f4e983e757b1b6942becaa1ae7d82e67 upstream.
--- sound/soc/imx/imx-ssi.c | 5 +++++ 1 file changed, 5 insertions(+)
sound/soc/imx/imx-ssi.c +5 -0
@@ -497,6 +497,8 @@ static void imx_ssi_ac97_reset(struct snif (imx_ssi->ac97_reset) imx_ssi->ac97_reset (ac97); +/* First read sometimes fails, do a dummy read */ +imx_ssi_ac97_read (ac97,0 ); }static void imx_ssi_ac97_warm_reset (struct snd_ac97 *ac97)
@@ -505,6 +507,9 @@ static void imx_ssi_ac97_warm_reset(struif (imx_ssi->ac97_warm_reset) imx_ssi->ac97_warm_reset (ac97); + +/* First read sometimes fails, do a dummy read */ +imx_ssi_ac97_read (ac97,0 ); }struct snd_ac97_bus_ops soc_ac97_ops = {
Greg Kroah-Hartman
maintainerPATCH 80/99 ASoC: sglt5000: Fix the default value of CHIP_SSS_CTRL
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabio Estevam <[email protected]>
commit 016fcab8ff46fca29375d484226ec91932aa4a07 upstream.
According to the sgtl5000 reference manual, the default value of CHIP_SSS_CTRL is 0x10.
--- sound/soc/codecs/sgtl5000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/sgtl5000.c +1 -1
@@ -37,7 +37,7 @@static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET ] = { [SGTL5000_CHIP_CLK_CTRL ] =0x0008 , [SGTL5000_CHIP_I2S_CTRL ] =0x0010 , - [SGTL5000_CHIP_SSS_CTRL ] =0x0008 , + [SGTL5000_CHIP_SSS_CTRL ] =0x0010 , [SGTL5000_CHIP_DAC_VOL ] =0x3c3c , [SGTL5000_CHIP_PAD_STRENGTH ] =0x015f , [SGTL5000_CHIP_ANA_HP_CTRL ] =0x1818 ,
Greg Kroah-Hartman
maintainerPATCH 81/99 ALSA: atiixp: Fix unlocked snd_pcm_stop() call
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit cc7282b8d5abbd48c81d1465925d464d9e3eaa8f upstream.
snd_pcm_stop() must be called in the PCM substream lock context.
--- sound/pci/atiixp.c | 2 ++ sound/pci/atiixp_modem.c | 2 ++ 2 files changed, 4 insertions(+)
sound/pci/atiixp.c +2 -0
@@ -688,7 +688,9 @@ static void snd_atiixp_xrun_dma(struct aif (! dma->substream || ! dma->running)return ;snd_printdd ("atiixp: XRUN detected (DMA %d)\n" , dma->ops->type); +snd_pcm_stream_lock (dma->substream);snd_pcm_stop (dma->substream,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock (dma->substream); }/*
sound/pci/atiixp_modem.c +2 -0
@@ -638,7 +638,9 @@ static void snd_atiixp_xrun_dma(struct aif (! dma->substream || ! dma->running)return ;snd_printdd ("atiixp-modem: XRUN detected (DMA %d)\n" , dma->ops->type); +snd_pcm_stream_lock (dma->substream);snd_pcm_stop (dma->substream,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock (dma->substream); }/*
Greg Kroah-Hartman
maintainerPATCH 82/99 ALSA: 6fire: Fix unlocked snd_pcm_stop() call
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 5b9ab3f7324a1b94a5a5a76d44cf92dfeb3b5e80 upstream.
snd_pcm_stop() must be called in the PCM substream lock context.
--- sound/usb/6fire/pcm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
sound/usb/6fire/pcm.c +10 -2
@@ -639,17 +639,25 @@ int __devinit usb6fire_pcm_init(struct svoid usb6fire_pcm_abort (struct sfire_chip *chip) {struct pcm_runtime *rt = chip->pcm; +unsigned long flags;int i;if (rt) { rt->panic = true; -if (rt->playback.instance) +if (rt->playback.instance) { +snd_pcm_stream_lock_irqsave (rt->playback.instance, flags);snd_pcm_stop (rt->playback.instance,SNDRV_PCM_STATE_XRUN ); -if (rt->capture.instance) +snd_pcm_stream_unlock_irqrestore (rt->playback.instance, flags); + } + +if (rt->capture.instance) { +snd_pcm_stream_lock_irqsave (rt->capture.instance, flags);snd_pcm_stop (rt->capture.instance,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock_irqrestore (rt->capture.instance, flags); + }for (i =0 ; i <PCM_N_URBS ; i++) {usb_poison_urb (&rt->in_urbs[i].instance);
Greg Kroah-Hartman
maintainerPATCH 83/99 ALSA: ua101: Fix unlocked snd_pcm_stop() call
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 9538aa46c2427d6782aa10036c4da4c541605e0e upstream.
snd_pcm_stop() must be called in the PCM substream lock context.
--- sound/usb/misc/ua101.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
sound/usb/misc/ua101.c +12 -2
@@ -613,14 +613,24 @@ static int start_usb_playback(struct ua1static void abort_alsa_capture (struct ua101 *ua) { -if (test_bit (ALSA_CAPTURE_RUNNING , &ua->states)) +unsigned long flags; + +if (test_bit (ALSA_CAPTURE_RUNNING , &ua->states)) { +snd_pcm_stream_lock_irqsave (ua->capture.substream, flags);snd_pcm_stop (ua->capture.substream,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock_irqrestore (ua->capture.substream, flags); + } }static void abort_alsa_playback (struct ua101 *ua) { -if (test_bit (ALSA_PLAYBACK_RUNNING , &ua->states)) +unsigned long flags; + +if (test_bit (ALSA_PLAYBACK_RUNNING , &ua->states)) { +snd_pcm_stream_lock_irqsave (ua->playback.substream, flags);snd_pcm_stop (ua->playback.substream,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock_irqrestore (ua->playback.substream, flags); + } } static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
Greg Kroah-Hartman
maintainerPATCH 84/99 ALSA: usx2y: Fix unlocked snd_pcm_stop() call
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 5be1efb4c2ed79c3d7c0cbcbecae768377666e84 upstream.
snd_pcm_stop() must be called in the PCM substream lock context.
--- sound/usb/usx2y/usbusx2yaudio.c | 4 ++++ 1 file changed, 4 insertions(+)
sound/usb/usx2y/usbusx2yaudio.c +4 -0
@@ -273,7 +273,11 @@ static void usX2Y_clients_stop(struct usstruct snd_usX2Y_substream *subs = usX2Y->subs[s];if (subs) {if (atomic_read (&subs->state) >= state_PRERUNNING) { +unsigned long flags; + +snd_pcm_stream_lock_irqsave (subs->pcm_substream, flags);snd_pcm_stop (subs->pcm_substream,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock_irqrestore (subs->pcm_substream, flags); }for (u =0 ; u <NRURBS ; u++) {struct urb *urb = subs->urb[u];
Greg Kroah-Hartman
maintainerPATCH 85/99 ALSA: pxa2xx: Fix unlocked snd_pcm_stop() call
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 46f6c1aaf790be9ea3c8ddfc8f235a5f677d08e2 upstream.
snd_pcm_stop() must be called in the PCM substream lock context.
--- sound/arm/pxa2xx-pcm-lib.c | 2 ++ 1 file changed, 2 insertions(+)
sound/arm/pxa2xx-pcm-lib.c +2 -0
@@ -166,7 +166,9 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void }else {printk (KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n" , rtd->params->name, dma_ch, dcsr); +snd_pcm_stream_lock (substream);snd_pcm_stop (substream,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock (substream); } }EXPORT_SYMBOL (pxa2xx_pcm_dma_irq);
Greg Kroah-Hartman
maintainerPATCH 86/99 ASoC: s6000: Fix unlocked snd_pcm_stop() call
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 61be2b9a18ec70f3cbe3deef7a5f77869c71b5ae upstream.
snd_pcm_stop() must be called in the PCM substream lock context.
--- sound/soc/s6000/s6000-pcm.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/s6000/s6000-pcm.c +2 -0
@@ -128,7 +128,9 @@ static irqreturn_t s6000_pcm_irq(int irq substream->runtime && snd_pcm_running(substream)) {dev_dbg (pcm->dev,"xrun\n" ); +snd_pcm_stream_lock (substream);snd_pcm_stop (substream,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock (substream); ret =IRQ_HANDLED ; }
Greg Kroah-Hartman
maintainerPATCH 87/99 staging: line6: Fix unlocked snd_pcm_stop() call
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 86f0b5b86d142b9323432fef078a6cf0fb5dda74 upstream.
snd_pcm_stop() must be called in the PCM substream lock context.
--- drivers/staging/line6/pcm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/staging/line6/pcm.c +4 -1
@@ -378,8 +378,11 @@ static int snd_line6_pcm_free(struct snd*/ static void pcm_disconnect_substream (struct snd_pcm_substream *substream) { -if (substream->runtime &&snd_pcm_running (substream)) +if (substream->runtime &&snd_pcm_running (substream)) { +snd_pcm_stream_lock_irq (substream);snd_pcm_stop (substream,SNDRV_PCM_STATE_DISCONNECTED ); +snd_pcm_stream_unlock_irq (substream); + } }/*
Greg Kroah-Hartman
maintainerPATCH 88/99 ALSA: asihpi: Fix unlocked snd_pcm_stop() call
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 60478295d6876619f8f47f6d1a5c25eaade69ee3 upstream.
snd_pcm_stop() must be called in the PCM substream lock context.
--- sound/pci/asihpi/asihpi.c | 3 +++ 1 file changed, 3 insertions(+)
sound/pci/asihpi/asihpi.c +3 -0
@@ -769,7 +769,10 @@ static void snd_card_asihpi_timer_functi s->number); ds->drained_count++;if (ds->drained_count >20 ) { +unsigned long flags; +snd_pcm_stream_lock_irqsave (s, flags);snd_pcm_stop (s,SNDRV_PCM_STATE_XRUN ); +snd_pcm_stream_unlock_irqrestore (s, flags);continue ; } }else {
Greg Kroah-Hartman
maintainerPATCH 89/99 iwlwifi: fix flow handler debug code
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 94543a8d4fb302817014981489f15cb3b92ec3c2 upstream.
iwl_dbgfs_fh_reg_read() can cause crashes and/or BUG_ON in slub because the ifdefs are wrong, the code in iwl_dump_fh() should use DEBUGFS, not DEBUG to protect the buffer writing code.
Also, while at it, clean up the arguments to the function, some code and make it generally safer.
--- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 - drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 2 - drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 27 +++++++++++----------- 3 files changed, 16 insertions(+), 15 deletions(-)
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +1 -1
@@ -352,7 +352,7 @@ int iwl_queue_space(const struct iwl_que******************************************************/ int iwl_dump_nic_event_log (struct iwl_trans *trans,bool full_log,char **buf,bool display); -int iwl_dump_fh (struct iwl_trans *trans,char **buf,bool display); +int iwl_dump_fh (struct iwl_trans *trans,char **buf);void iwl_dump_csr (struct iwl_trans *trans);/*****************************************************
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +1 -1
@@ -695,7 +695,7 @@ static void iwl_irq_handle_error(structiwl_dump_nic_error_log (trans);iwl_dump_csr (trans); -iwl_dump_fh (trans,NULL , false); +iwl_dump_fh (trans,NULL );iwl_dump_nic_event_log (trans, false,NULL , false);iwl_op_mode_nic_error (trans->op_mode);
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +14 -13
@@ -1768,13 +1768,9 @@ static const char *get_fh_string(int cmd } } -int iwl_dump_fh (struct iwl_trans *trans,char **buf,bool display) +int iwl_dump_fh (struct iwl_trans *trans,char **buf) {int i; -#ifdef CONFIG_IWLWIFI_DEBUG -int pos =0 ; -size_t bufsz =0 ; -#endif static const u32 fh_tbl[] = {FH_RSCSR_CHNL0_STTS_WPTR_REG ,FH_RSCSR_CHNL0_RBDCB_BASE_REG ,
@@ -1786,29 +1782,34 @@ int iwl_dump_fh(struct iwl_trans *trans,FH_TSSR_TX_STATUS_REG ,FH_TSSR_TX_ERROR_REG }; -#ifdef CONFIG_IWLWIFI_DEBUG -if (display) { + +#ifdef CONFIG_IWLWIFI_DEBUGFS +if (buf) { +int pos =0 ; +size_t bufsz =ARRAY_SIZE (fh_tbl) *48 +40 ; + bufsz =ARRAY_SIZE (fh_tbl) *48 +40 ; *buf =kmalloc (bufsz,GFP_KERNEL );if (!*buf)return -ENOMEM ; pos +=scnprintf (*buf + pos, bufsz - pos,"FH register values:\n" ); -for (i =0 ; i <ARRAY_SIZE (fh_tbl); i++) { + +for (i =0 ; i <ARRAY_SIZE (fh_tbl); i++) pos +=scnprintf (*buf + pos, bufsz - pos," %34s: 0X%08x\n" ,get_fh_string (fh_tbl[i]),iwl_read_direct32 (trans, fh_tbl[i])); - } +return pos; }#endif IWL_ERR (trans,"FH register values:\n" ); -for (i =0 ; i <ARRAY_SIZE (fh_tbl); i++) { +for (i =0 ; i <ARRAY_SIZE (fh_tbl); i++)IWL_ERR (trans," %34s: 0X%08x\n" ,get_fh_string (fh_tbl[i]),iwl_read_direct32 (trans, fh_tbl[i])); - } +return 0 ; }
@@ -2152,11 +2153,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(str size_t count, loff_t *ppos) { struct iwl_trans *trans = file->private_data; -char *buf; +char *buf =NULL ;int pos =0 ;ssize_t ret = -EFAULT ; - ret = pos =iwl_dump_fh (trans, &buf, true); + ret = pos =iwl_dump_fh (trans, &buf);if (buf) { ret =simple_read_from_buffer (user_buf, count, ppos, buf, pos);
Greg Kroah-Hartman
maintainerPATCH 90/99 iwlwifi: protect SRAM debugfs
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 4fc79db178f0a0ede479b4713e00df2d106028b3 upstream.
If the device is not started, we can't read its SRAM and attempting to do so will cause issues. Protect the debugfs read.
--- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/iwlwifi/iwl-debugfs.c +3 -0
@@ -227,6 +227,9 @@ static ssize_t iwl_dbgfs_sram_read(strucconst struct fw_img *img;size_t bufsz; +if (!iwl_is_ready_rf (priv)) +return -EAGAIN ; +/* default is to dump the entire data segment */ if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { priv->dbgfs_sram_offset =0x800000 ;
Greg Kroah-Hartman
maintainerPATCH 91/99 iwlwifi: dont handle masked interrupt
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
commit 25a172655f837bdb032e451f95441bb4acec51bb upstream.
This can lead to a panic if the driver isn't ready to handle them. Since our interrupt line is shared, we can get an interrupt at any time (and CONFIG_DEBUG_SHIRQ checks that even when the interrupt is being freed).
If the op_mode has gone away, we musn't call it. To avoid this the transport disables the interrupts when the hw is stopped and the op_mode is leaving.
If there is an event that would cause an interrupt the INTA register is updated regardless of the enablement of the
interrupts: even if the interrupts are disabled, the INTA will be changed, but the device won't issue an interrupt. But the ISR can be called at any time, so we ought ignore the value in the INTA otherwise we can call the op_mode after it was freed.
I found this bug when the op_mode_start failed, and called iwl_trans_stop_hw(trans, true). Then I played with the RFKILL button, and removed the module.
While removing the module, the IRQ is freed, and the ISR is called (CONFIG_DEBUG_SHIRQ enabled). Panic.
[bwh: Backported to 3.2:
- Adjust context
- Pass bus(trans), not trans, to iwl_{read,write}32()]
[wujg: Backported to 3.4:
- adjust context
- Pass trans to iwl_{read,write}32()}]
--- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +10 -2
@@ -1264,12 +1264,20 @@ static irqreturn_t iwl_isr(int irq, void* back-to-back ISRs and sporadic interrupts from our NIC. * If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask =iwl_read32 (trans,CSR_INT_MASK );/* just for debug */ + inta_mask =iwl_read32 (trans,CSR_INT_MASK );iwl_write32 (trans,CSR_INT_MASK ,0x00000000 );/* Discover which interrupts are active/pending */ inta =iwl_read32 (trans,CSR_INT ); +if (inta & (~inta_mask)) { +IWL_DEBUG_ISR (trans, +"We got a masked interrupt (0x%08x)...Ack and ignore\n" , + inta & (~inta_mask)); +iwl_write32 (trans,CSR_INT , inta & (~inta_mask)); + inta &= inta_mask; + } +/* Ignore interrupt if there's nothing in NIC to service. * This may be due to IRQ shared with another device, * or due to sporadic interrupts thrown from our NIC. */
@@ -1353,7 +1361,7 @@ irqreturn_t iwl_isr_ict(int irq, void *d* If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask =iwl_read32 (trans,CSR_INT_MASK );/* just for debug */ + inta_mask =iwl_read32 (trans,CSR_INT_MASK );iwl_write32 (trans,CSR_INT_MASK ,0x00000000 );
Greg Kroah-Hartman
maintainerPATCH 92/99 iwlwifi: handle DMA mapping failures
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 7c34158231b2eda8dcbd297be2bb1559e69cb433 upstream.
The RX replenish code doesn't handle DMA mapping failures, which will cause issues if there actually is a failure. This was reported by Shuah Khan who found a DMA mapping framework warning ("device driver failed to check map error").
[bwh: Backported to 3.2:
- Adjust filename, context, indentation
- Use bus(trans) instead of trans where necessary
- Use hw_params(trans).rx_page_order instead of trans_pcie->rx_page_order]
[wujg: Backported to 3.4:
- Adjust context
- Use trans instead of bus(trans)
- Use hw_params(trans).rx_page_order instead of trans_pcie->rx_page_order]
--- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +21 -2
@@ -315,6 +315,14 @@ static void iwlagn_rx_allocate(struct iw rxb->page_dma =dma_map_page (trans->dev, page,0 ,PAGE_SIZE <<hw_params (trans).rx_page_order,DMA_FROM_DEVICE ); +if (dma_mapping_error (trans->dev, rxb->page_dma)) { + rxb->page =NULL ; +spin_lock_irqsave (&rxq->lock, flags); +list_add (&rxb->list, &rxq->rx_used); +spin_unlock_irqrestore (&rxq->lock, flags); +__free_pages (page,hw_params (trans).rx_page_order); +return ; + }/* dma address must be no more than 36 bits */ BUG_ON (rxb->page_dma & ~DMA_BIT_MASK (36 ));/* and also 256 byte aligned! */
@@ -450,8 +458,19 @@ static void iwl_rx_handle_rxbuf(struct idma_map_page (trans->dev, rxb->page,0 ,PAGE_SIZE <<hw_params (trans).rx_page_order,DMA_FROM_DEVICE ); -list_add_tail (&rxb->list, &rxq->rx_free); - rxq->free_count++; +if (dma_mapping_error (trans->dev, rxb->page_dma)) { +/* +* free the page(s) as well to not break +* the invariant that the items on the used +* list have no page(s) +*/ +__free_pages (rxb->page,hw_params (trans).rx_page_order); + rxb->page =NULL ; +list_add_tail (&rxb->list, &rxq->rx_used); + }else { +list_add_tail (&rxb->list, &rxq->rx_free); + rxq->free_count++; + } }else list_add_tail (&rxb->list, &rxq->rx_used);spin_unlock_irqrestore (&rxq->lock, flags);
Greg Kroah-Hartman
maintainerPATCH 93/99 iwlwifi: always copy first 16 bytes of commands
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 upstream.
The FH hardware will always write back to the scratch field in commands, even host commands not just TX commands, which can overwrite parts of the command. This is problematic if the command is re-used (with IWL_HCMD_DFL_NOCOPY) and can cause calibration issues.
Address this problem by always putting at least the first 16 bytes into the buffer we also use for the command header and therefore make the DMA engine write back into this.
For commands that are smaller than 16 bytes also always map enough memory for the DMA engine to write back to.
[bwh: Backported to 3.2:
- Adjust context
- Drop the IWL_HCMD_DFL_DUP handling
- Fix descriptor addresses and lengths for tracepoint, but otherwise leave it unchanged]
--- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 9 +++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 65 +++++++++++++++++----- 2 files changed, 62 insertions(+), 12 deletions(-)
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +9 -0
@@ -209,6 +209,15 @@ struct iwl_queue {#define TFD_TX_CMD_SLOTS 256#define TFD_CMD_SLOTS 32 +/* +* The FH will write back to the first TB only, so we need +* to copy some data into the buffer regardless of whether +* it should be mapped or not. This indicates how much to +* copy, even for HCMDs it must be big enough to fit the +* DRAM scratch from the TX cmd, at least 16 bytes. +*/ +#define IWL_HCMD_MIN_COPY_SIZE 16 +struct iwl_tx_queue {struct iwl_queue q;struct iwl_tfd *tfds;
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +53 -12
115 lines not on this page · raw message
Re: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
Original Message from: Greg Kroah-Hartman <[email protected]>
Quoted 7 lines
3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit
8a964f44e01ad3bbc208c3e80d931ba91b9ea786upstream.
Forwarding original message to make sure it isn't lost - this patch breaks iwlwifi in >=3.4.83 for at least some people, including me and my Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74.
Reverting the patch so far has been a workaround. Before sending, I also tried out 3.4.83 + current stable-queue to make sure the problem persists.
Original Message From: Andres Bertens <[email protected]>
Subject: Linux 3.4.83 update: wireless card (iwlwifi) stop working
Date: Wednesday 12 March 2014, 14:46:14
Quoted 46 lines
Hi,
I updated today to 3.4.83 kernel and my wireless card stop working (log
says: iwlwifi 0000:03:00.0: Unable to initialize device).My laptop is a Lenovo Thinkpad X230, with an Intel 6205 AGN card.
Reverting patch
Johannes Berg <[email protected]>
iwlwifi: always copy first 16 bytes of commands
makes it work again.Regards,
Andres BertensLinux mintaka 3.4.83-smp #1 SMP Wed Mar 12 13:10:44 CLST 2014
x86_64x86_64x86_64GNU/Linux--------------------------------
iwlwifi 0000:03:00.0:pci_resource_len=0x00002000
iwlwifi 0000:03:00.0:pci_resource_base=ffffc90006618000iwlwifi 0000:03:00.0: HW Revision ID =0x34
iwlwifi 0000:03:00.0: irq 42 for MSI/MSI-X
iwlwifi 0000:03:00.0: loaded firmware version 18.168.6.1 iwlwifi 0000:03:00.0:CONFIG_IWLWIFI_DEBUGdisabled
iwlwifi 0000:03:00.0:CONFIG_IWLWIFI_DEBUGFSdisabled iwlwifi 0000:03:00.0:CONFIG_IWLWIFI_DEVICE_TRACINGdisabled iwlwifi 0000:03:00.0:CONFIG_IWLWIFI_DEVICE_TESTMODEdisabled iwlwifi 0000:03:00.0:CONFIG_IWLWIFI_P2Pdisabled
iwlwifi 0000:03:00.0: Detected Intel(R) Centrino(R) Advanced-N 6205 AGN, REV=0xB0
iwlwifi 0000:03:00.0: L1 Enabled; Disabling L0S
iwlwifi 0000:03:00.0: device EEPROM VER=0x715, CALIB=0x6 iwlwifi 0000:03:00.0: Device SKU:0x1F0
iwlwifi 0000:03:00.0: Valid Tx ant:0x3, Valid Rx ant:0x3iwlwifi 0000:03:00.0: Tunable channels: 13 802.11bg, 24 802.11a channels iwlwifi 0000:03:00.0: L1 Enabled; Disabling L0S
iwlwifi 0000:03:00.0: Radio type=0x1-0x2-0x0
iwlwifi 0000:03:00.0: Error sendingCALIBRATION_CFG_CMD: time out after 2000ms.
iwlwifi 0000:03:00.0: Current CMD queueread_ptr2write_ptr3 iwlwifi 0000:03:00.0: Failing on timeout while stopping DMA channel 7 [0x077f0001]
iwlwifi 0000:03:00.0: Failed to run INIT ucode: -110
iwlwifi 0000:03:00.0: Unable to initialize device.
Greg Kroah-Hartman
maintainerRe: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
Quoted 7 lines · Andreas Sturmlechner
Original Message from: Greg Kroah-Hartman <[email protected]>
Quoted 6 lines
3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
Quoted 8 lines
Quoted 1 line
commit
8a964f44e01ad3bbc208c3e80d931ba91b9ea786upstream.Forwarding original message to make sure it isn't lost - this patch breaks iwlwifi in >=3.4.83 for at least some people, including me and my Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74.
Reverting the patch so far has been a workaround. Before sending, I also tried out 3.4.83 + current stable-queue to make sure the problem persists.
Ok, that's not good.
Does Linus's tree also have this problem for you? Or does it work there? If it works there, perhaps we just missed backporting something to 3.4?
thanks,
greg k-h
Re: Re: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
Original Message from: Greg Kroah-Hartman <[email protected]>
Quoted 5 lines
Does Linus's tree also have this problem for you? Or does it work there? If it works there, perhaps we just missed backporting something to 3.4?
Other trouble aside, iwlwifi works fine - writing this from today's build of 3.14.0-rc7+.
Greg Kroah-Hartman
maintainerRe: Re: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
Quoted 9 lines · Andreas Sturmlechner
Original Message from: Greg Kroah-Hartman <[email protected]>
Quoted 5 lines
Does Linus's tree also have this problem for you? Or does it work there? If it works there, perhaps we just missed backporting something to 3.4?
Other trouble aside, iwlwifi works fine - writing this from today's build of 3.14.0-rc7+.
Hm. Any linux-wifi developers have an idea? I can always just revert this patch, but finding out the root cause would be nice...
greg k-h
Re: Re: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
Quoted 8 lines · Greg Kroah-Hartman
Quoted 7 lines · Andreas Sturmlechner
Original Message from: Greg Kroah-Hartman <[email protected]>
Quoted 5 lines
Does Linus's tree also have this problem for you? Or does it work there? If it works there, perhaps we just missed backporting something to 3.4?
Quoted 5 lines
Quoted 2 lines
Other trouble aside, iwlwifi works fine - writing this from today's build of 3.14.0-rc7+.
Hm. Any linux-wifi developers have an idea? I can always just revert this patch, but finding out the root cause would be nice...
Andreas, could you test whether this regression is also present in 3.2.55? This patch is based on my backport for 3.2.y.
Ben.
Signature · 2 lines
Ben Hutchings I'm not a reverse psychological virus. Please don't copy me into your sig.
RE: Re: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
Quoted 10 lines · Greg Kroah-Hartman
Quoted 9 lines · Andreas Sturmlechner
Quoted 8 lines
Original Message from: Greg Kroah-Hartman
<[email protected]>Quoted 5 lines
Does Linus's tree also have this problem for you? Or does it work there? If it works there, perhaps we just missed backporting something to 3.4?
Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
Other trouble aside, iwlwifi works fine - writing this from today's build of 3.14.0-rc7+.
Hm. Any linux-wifi developers have an idea? I can always just revert this patch, but finding out the root cause would be nice...
Reverting the patch is obviously the first thing to do. Finding the root would be nice but I am afraid the time won't allow it... In any case, this patch is meant to avoid a few DMAR fault and possibly some calibration mismatch upon suspend resume. Nothing critical in my eyes.
Quoted 9 lines
Andreas, could you test whether this regression is also present in 3.2.55? This patch is based on my backport for 3.2.y.
Ben.
--
Ben Hutchings
I'm not a reverse psychological virus. Please don't copy me into your sig.
Re: Re: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
In reply to Ben HutchingsOriginal Message from: Ben Hutchings <[email protected]>
Quoted 4 lines
Andreas, could you test whether this regression is also present in 3.2.55? This patch is based on my backport for 3.2.y.
3.2.55 is OK here.
Re: Re: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
Quoted 7 lines · Andreas Sturmlechner
Original Message from: Ben Hutchings <[email protected]>
Quoted 4 lines
Andreas, could you test whether this regression is also present in 3.2.55? This patch is based on my backport for 3.2.y.
3.2.55 is OK here.
One piece of my backport to 3.2.y went missing in the forward-port to 3.4.y. Can you test 3.4.83 with this patch on top?
Ben.
---
From: Ben Hutchings <[email protected]>
Date: Tue, 25 Mar 2014 02:49:14 +0000
Subject: iwlwifi: Complete backport of "iwlwifi: always copy first 16 bytes of commands"
Linux 3.4.83 included an incomplete backport of commit 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 ('iwlwifi: always copy first 16 bytes of commands') which causes a regression for this driver. This is the missing piece.
---
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +4 -3
@@ -825,14 +825,15 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) trace_idx =1 ;#endif +/* map the remaining (adjusted) nocopy/dup fragments */ for (i =0 ; i <IWL_MAX_CMD_TFDS ; i++) { -if (!cmd->len[i]) +if (!cmdlen[i])continue ;if (!(cmd->dataflags[i] &IWL_HCMD_DFL_NOCOPY ))continue ; phys_addr =dma_map_single (trans->dev, - (void *)cmd->data[i], - cmd->len[i],DMA_BIDIRECTIONAL ); + (void *)cmddata[i], + cmdlen[i],DMA_BIDIRECTIONAL );if (dma_mapping_error (trans->dev, phys_addr)) { iwlagn_unmap_tfd(trans, out_meta, &txq->tfds[q->write_ptr],
Signature · 2 lines
Ben Hutchings Make three consecutive correct guesses and you will be considered an expert.
Re: Re: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
Original Message from: Ben Hutchings <[email protected]>
Quoted 5 lines
One piece of my backport to 3.2.y went missing in the forward-port to 3.4.y. Can you test 3.4.83 with this patch on top?
Ben.
iwlwifi works with the additional patch, thanks :)
Re: [PATCH 3.4 93/99] iwlwifi: always copy first 16 bytes of commands
Quoted 11 lines · Andreas Sturmlechner
Original Message from: Ben Hutchings <[email protected]>
Quoted 5 lines
One piece of my backport to 3.2.y went missing in the forward-port to 3.4.y. Can you test 3.4.83 with this patch on top?
Ben.
iwlwifi works with the additional patch, thanks :)
Sorry for the missing part, thanks, Ben.
PATCH 1/1 iwlwifi: Complete backport of "iwlwifi: always copy first 16 bytes of commands"
In reply to Ben HutchingsLinux 3.4.83 included an incomplete backport of commit 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 ('iwlwifi: always copy first 16 bytes of commands') which causes a regression for this driver. This is the missing piece.
---
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +4 -3
@@ -825,14 +825,15 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) trace_idx =1 ;#endif +/* map the remaining (adjusted) nocopy/dup fragments */ for (i =0 ; i <IWL_MAX_CMD_TFDS ; i++) { -if (!cmd->len[i]) +if (!cmdlen[i])continue ;if (!(cmd->dataflags[i] &IWL_HCMD_DFL_NOCOPY ))continue ; phys_addr =dma_map_single (trans->dev, - (void *)cmd->data[i], - cmd->len[i],DMA_BIDIRECTIONAL ); + (void *)cmddata[i], + cmdlen[i],DMA_BIDIRECTIONAL );if (dma_mapping_error (trans->dev, phys_addr)) { iwlagn_unmap_tfd(trans, out_meta, &txq->tfds[q->write_ptr],
Signature · 2 lines
Ben Hutchings Make three consecutive correct guesses and you will be considered an expert.
Greg Kroah-Hartman
maintainerRe: [PATCH 3.4] iwlwifi: Complete backport of "iwlwifi: always copy first 16 bytes of commands"
Quoted 11 lines · Ben Hutchings
Linux 3.4.83 included an incomplete backport of commit
8a964f44e01ad3bbc208c3e80d931ba91b9ea786('iwlwifi: always copy first 16 bytes of commands') which causes a regression for this driver. This is the missing piece.Reported-by Andreas Sturmlechner <[email protected]>Cc Johannes Berg <[email protected]>Cc Emmanuel Grumbach <[email protected]>Cc Jianguo Wu <[email protected]>Tested-by Andreas Sturmlechner <[email protected]>Signed-off-by Ben Hutchings <[email protected]>
Thanks for tracking this down and for the patch, I'll queue it up for the next 3.4-stable release.
greg k-h
Greg Kroah-Hartman
maintainerPATCH 94/99 iwlwifi: dvm: dont send BT_CONFIG on devices w/o Bluetooth
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
commit 707aee401d2467baa785a697f40a6e2d9ee79ad5 upstream.
The BT_CONFIG command that is sent to the device during startup will enable BT coex unless the module parameter turns it off, but on devices without Bluetooth this may cause problems, as reported in Redhat BZ 885407.
Fix this by sending the BT_CONFIG command only when the device has Bluetooth.
[bwh: Backported to 3.2:
- Adjust filename
- s/priv->lib/priv->cfg/]
[wujg: Backported to 3.4:
- s/priv->cfg/priv->shrd->cfg/]
--- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/iwl-agn.c +1 -1
@@ -680,7 +680,7 @@ int iwl_alive_start(struct iwl_priv *pri BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);if (ret)return ret; - }else { + }else if (priv->shrd->cfg->bt_params) {/* * default is 2-wire BT coexexistence support */
Greg Kroah-Hartman
maintainerPATCH 95/99 iwlwifi: dvm: fix calling ieee80211_chswitch_done() with NULL
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanislaw Gruszka <[email protected]>
commit 9186a1fd9ed190739423db84bc344d258ef3e3d7 upstream.
If channel switch is pending and we remove interface we can crash like showed below due to passing NULL vif to mac80211:
BUG: unable to handle kernel paging request at fffffffffffff8cc IP: [<ffffffff8130924d>] strnlen+0xd/0x40 Call Trace: [<ffffffff8130ad2e>] string.isra.3+0x3e/0xd0 [<ffffffff8130bf99>] vsnprintf+0x219/0x640 [<ffffffff8130c481>] vscnprintf+0x11/0x30 [<ffffffff81061585>] vprintk_emit+0x115/0x4f0 [<ffffffff81657bd5>] printk+0x61/0x63 [<ffffffffa048987f>] ieee80211_chswitch_done+0xaf/0xd0 [mac80211] [<ffffffffa04e7b34>] iwl_chswitch_done+0x34/0x40 [iwldvm] [<ffffffffa04f83c3>] iwlagn_commit_rxon+0x2a3/0xdc0 [iwldvm] [<ffffffffa04ebc50>] ? iwlagn_set_rxon_chain+0x180/0x2c0 [iwldvm] [<ffffffffa04e5e76>] iwl_set_mode+0x36/0x40 [iwldvm] [<ffffffffa04e5f0d>] iwlagn_mac_remove_interface+0x8d/0x1b0 [iwldvm] [<ffffffffa0459b3d>] ieee80211_do_stop+0x29d/0x7f0 [mac80211]
This is because we nulify ctx->vif in iwlagn_mac_remove_interface() before calling some other functions that teardown interface. To fix just check ctx->vif on iwl_chswitch_done(). We should not call ieee80211_chswitch_done() as channel switch works were already canceled by mac80211 in ieee80211_do_stop() -> ieee80211_mgd_stop().
Resolve:
https://bugzilla.redhat.com/show_bug.cgi?id=979581
--- drivers/net/wireless/iwlwifi/iwl-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/iwl-core.c +4 -1
@@ -801,7 +801,10 @@ void iwl_chswitch_done(struct iwl_priv *if (test_bit (STATUS_EXIT_PENDING , &priv->status))return ; -if (test_and_clear_bit (STATUS_CHANNEL_SWITCH_PENDING , &priv->status)) +if (!test_and_clear_bit (STATUS_CHANNEL_SWITCH_PENDING , &priv->status)) +return ; + +if (ctx->vif)ieee80211_chswitch_done (ctx->vif, is_success); }
Greg Kroah-Hartman
maintainerPATCH 96/99 iwlwifi: pcie: add SKUs for 6000, 6005 and 6235 series
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emmanuel Grumbach <[email protected]>
commit 08a5dd3842f2ac61c6d69661d2d96022df8ae359 upstream.
Add some new PCI IDs to the table for 6000, 6005 and 6235 series.
[bwh: Backported to 3.2:
- Adjust filenames
- Drop const from struct iwl_cfg]
[wujg: Backported to 3.4:
- Adjust context
- Do not drop const from struct iwl_cfg]
--- drivers/net/wireless/iwlwifi/iwl-6000.c | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-cfg.h | 1 + drivers/net/wireless/iwlwifi/iwl-pci.c | 10 ++++++++++ 3 files changed, 17 insertions(+)
drivers/net/wireless/iwlwifi/iwl-6000.c +6 -0
@@ -459,6 +459,12 @@ const struct iwl_cfg iwl6035_2agn_cfg = .ht_params = &iwl6000_ht_params, }; +const struct iwl_cfg iwl6035_2agn_sff_cfg = { + .name ="Intel(R) Centrino(R) Ultimate-N 6235 AGN" , +IWL_DEVICE_6035 , + .ht_params = &iwl6000_ht_params, +}; +const struct iwl_cfg iwl1030_bgn_cfg = { .name ="Intel(R) Centrino(R) Wireless-N 1030 BGN" ,IWL_DEVICE_6030 ,
drivers/net/wireless/iwlwifi/iwl-cfg.h +1 -0
@@ -106,6 +106,7 @@ extern const struct iwl_cfg iwl2000_2bgnextern const struct iwl_cfg iwl2000_2bgn_d_cfg;extern const struct iwl_cfg iwl2030_2bgn_cfg;extern const struct iwl_cfg iwl6035_2agn_cfg; +extern const struct iwl_cfg iwl6035_2agn_sff_cfg;extern const struct iwl_cfg iwl105_bgn_cfg;extern const struct iwl_cfg iwl105_bgn_d_cfg;extern const struct iwl_cfg iwl135_bgn_cfg;
drivers/net/wireless/iwlwifi/iwl-pci.c +10 -0
@@ -138,13 +138,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_ca/* 6x00 Series */ {IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1108, iwl6000_3agn_cfg)}, {IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x422B, 0x1128, iwl6000_3agn_cfg)}, {IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)}, {IWL_PCI_DEVICE(0x422C, 0x1306, iwl6000i_2abg_cfg)}, {IWL_PCI_DEVICE(0x422C, 0x1307, iwl6000i_2bg_cfg)}, {IWL_PCI_DEVICE(0x422C, 0x1321, iwl6000i_2agn_cfg)}, {IWL_PCI_DEVICE(0x422C, 0x1326, iwl6000i_2abg_cfg)}, {IWL_PCI_DEVICE(0x4238, 0x1111, iwl6000_3agn_cfg)}, + {IWL_PCI_DEVICE(0x4238, 0x1118, iwl6000_3agn_cfg)}, {IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)}, {IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
@@ -152,12 +155,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_ca {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6005_2agn_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6005_2abg_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6005_2bg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1308, iwl6005_2agn_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6005_2agn_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6005_2abg_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1328, iwl6005_2agn_cfg)}, {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6005_2agn_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0x1318, iwl6005_2agn_cfg)}, {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, + {IWL_PCI_DEVICE(0x0085, 0xC228, iwl6005_2agn_sff_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)}, {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */ {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */
@@ -239,8 +246,11 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_ca/* 6x35 Series */ {IWL_PCI_DEVICE(0x088E, 0x4060, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x406A, iwl6035_2agn_sff_cfg)}, {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x426A, iwl6035_2agn_sff_cfg)}, {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6035_2agn_sff_cfg)}, {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)},/* 105 Series */
Greg Kroah-Hartman
maintainerPATCH 97/99 rtlwifi: Fix endian error in extracting packet type
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Cave-Ayland <[email protected]>
commit 0c5d63f0ab6728f05ddefa25aff55e31297f95e6 upstream.
All of the rtlwifi drivers have an error in the routine that tests if the data is "special". If it is, the subsequant transmission will be at the lowest rate to enhance reliability. The 16-bit quantity is big-endian, but was being extracted in native CPU mode. One of the effects of this bug is to inhibit association under some conditions as the TX rate is too high.
Based on suggestions by Joe Perches, the entire routine is rewritten.
One of the local headers contained duplicates of some of the ETH_P_XXX definitions. These are deleted.
[wujg: Backported to 3.4:
- adjust context
- remove rtlpriv->enter_ps = false
- use schedule_work(&rtlpriv->works.lps_leave_work)]
--- drivers/net/wireless/rtlwifi/base.c | 93 ++++++++++++++++-------------------- drivers/net/wireless/rtlwifi/wifi.h | 6 -- 2 files changed, 43 insertions(+), 56 deletions(-)
drivers/net/wireless/rtlwifi/base.c +42 -51
@@ -37,6 +37,7 @@#include <linux/ip.h> #include <linux/module.h> +#include <linux/udp.h> /* *NOTICE!!!: This file will be very big, we should
@@ -957,61 +958,51 @@ u8 rtl_is_special_data(struct ieee80211_if (!ieee80211_is_data (fc))return false; + ip = (const struct iphdr *)(skb->data + mac_hdr_len + +SNAP_SIZE +PROTOC_TYPE_SIZE ); + ether_type =be16_to_cpup ((__be16 *) + (skb->data + mac_hdr_len +SNAP_SIZE )); + +switch (ether_type) { +case ETH_P_IP : { +struct udphdr *udp; +u16 src; +u16 dst; + +if (ip->protocol !=IPPROTO_UDP ) +return false; + udp = (struct udphdr *)((u8 *)ip + (ip->ihl <<2 )); + src =be16_to_cpu (udp->source); + dst =be16_to_cpu (udp->dest); + +/* If this case involves port 68 (UDP BOOTP client) connecting +* with port 67 (UDP BOOTP server), then return true so that +* the lowest speed is used. +*/ +if (!((src ==68 && dst ==67 ) || (src ==67 && dst ==68 ))) +return false; - ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + -SNAP_SIZE +PROTOC_TYPE_SIZE ); - ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len +SNAP_SIZE ); -/* ether_type = ntohs(ether_type); */ - -if (ETH_P_IP == ether_type) { -if (IPPROTO_UDP == ip->protocol) { -struct udphdr *udp = (struct udphdr *)((u8 *) ip + - (ip->ihl <<2 )); -if (((((u8 *) udp)[1 ] ==68 ) && - (((u8 *) udp)[3 ] ==67 )) || - ((((u8 *) udp)[1 ] ==67 ) && - (((u8 *) udp)[3 ] ==68 ))) { -/* -* 68 : UDP BOOTP client -* 67 : UDP BOOTP server -*/ -RT_TRACE (rtlpriv, (COMP_SEND |COMP_RECV ), -DBG_DMESG ,"dhcp %s !!\n" , - is_tx ?"Tx" :"Rx" ); - -if (is_tx) { -schedule_work (&rtlpriv-> - works.lps_leave_work); - ppsc->last_delaylps_stamp_jiffies = - jiffies; - } - -return true; - } - } - }else if (ETH_P_ARP == ether_type) { -if (is_tx) { -schedule_work (&rtlpriv->works.lps_leave_work); - ppsc->last_delaylps_stamp_jiffies = jiffies; - } - -return true; - }else if (ETH_P_PAE == ether_type) { +RT_TRACE (rtlpriv, (COMP_SEND |COMP_RECV ),DBG_DMESG , +"dhcp %s !!\n" , is_tx ?"Tx" :"Rx" ); +break ; + } +case ETH_P_ARP : +break ; +case ETH_P_PAE :RT_TRACE (rtlpriv, (COMP_SEND |COMP_RECV ),DBG_DMESG ,"802.1X %s EAPOL pkt!!\n" , is_tx ?"Tx" :"Rx" ); - -if (is_tx) { -schedule_work (&rtlpriv->works.lps_leave_work); - ppsc->last_delaylps_stamp_jiffies = jiffies; - } - -return true; - }else if (ETH_P_IPV6 == ether_type) { -/* IPv6 */ -return true; +break ; +case ETH_P_IPV6 : +/* TODO: Is this right? */ +return false; +default : +return false; } - -return false; +if (is_tx) { +schedule_work (&rtlpriv->works.lps_leave_work); + ppsc->last_delaylps_stamp_jiffies = jiffies; + } +return true; }/*********************************************************
drivers/net/wireless/rtlwifi/wifi.h +1 -5
@@ -77,11 +77,7 @@#define RTL_SLOT_TIME_9 9#define RTL_SLOT_TIME_20 20 -/*related with tcp/ip. */ -/*if_ehther.h*/ -#define ETH_P_PAE 0x888E/*Port Access Entity (IEEE 802.1X) */ -#define ETH_P_IP 0x0800/*Internet Protocol packet */ -#define ETH_P_ARP 0x0806/*Address Resolution packet */ +/*related to tcp/ip. */ #define SNAP_SIZE 6#define PROTOC_TYPE_SIZE 2
Greg Kroah-Hartman
maintainerPATCH 98/99 net: asix: handle packets crossing URB boundaries
In reply to Greg Kroah-Hartman3.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas Stach <[email protected]>
commit 8b5b6f5413e97c3e8bafcdd67553d508f4f698cd upstream.
ASIX AX88772B started to pack data even more tightly. Packets and the ASIX packet header may now cross URB boundaries. To handle this we have to introduce some state between individual calls to asix_rx_fixup().
--- drivers/net/usb/asix.c | 125 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 97 insertions(+), 28 deletions(-)
drivers/net/usb/asix.c +97 -28
@@ -183,6 +183,17 @@ struct ax88172_int_data {__le16 res3; } __packed; +struct asix_rx_fixup_info { +struct sk_buff *ax_skb; +u32 header; +u16 size; +bool split_head; +}; + +struct asix_common_private { +struct asix_rx_fixup_info rx_fixup_info; +}; +static int asix_read_cmd (struct usbnet *dev,u8 cmd,u16 value,u16 index,u16 size,void *data) {
@@ -304,49 +315,89 @@ asix_write_cmd_async(struct usbnet *dev, } } -static int asix_rx_fixup (struct usbnet *dev,struct sk_buff *skb) +static int asix_rx_fixup_internal (struct usbnet *dev,struct sk_buff *skb, +struct asix_rx_fixup_info *rx) {int offset =0 ; -while (offset +sizeof (u32) < skb->len) { -struct sk_buff *ax_skb; -u16 size; -u32 header =get_unaligned_le32 (skb->data + offset); - - offset +=sizeof (u32); - -/* get the packet length */ - size = (u16) (header &0x7ff ); -if (size != ((~header >>16 ) &0x07ff )) { -netdev_err (dev->net,"asix_rx_fixup() Bad Header Length\n" ); -return 0 ; +while (offset +sizeof (u16) <= skb->len) { +u16 remaining =0 ; +unsigned char *data; + +if (!rx->size) { +if ((skb->len - offset ==sizeof (u16)) || + rx->split_head) { +if (!rx->split_head) { + rx->header =get_unaligned_le16 ( + skb->data + offset); + rx->split_head = true; + offset +=sizeof (u16); +break ; + }else { + rx->header |= (get_unaligned_le16 ( + skb->data + offset) + <<16 ); + rx->split_head = false; + offset +=sizeof (u16); + } + }else { + rx->header =get_unaligned_le32 (skb->data + + offset); + offset +=sizeof (u32); + } + +/* get the packet length */ + rx->size = (u16) (rx->header &0x7ff ); +if (rx->size != ((~rx->header >>16 ) &0x7ff )) { +netdev_err (dev->net,"asix_rx_fixup() Bad Header Length 0x%x, offset %d\n" , + rx->header, offset); + rx->size =0 ; +return 0 ; + } + rx->ax_skb =netdev_alloc_skb_ip_align (dev->net, + rx->size); +if (!rx->ax_skb) +return 0 ; } -if ((size > dev->net->mtu +ETH_HLEN +VLAN_HLEN ) || - (size + offset > skb->len)) { +if (rx->size > dev->net->mtu +ETH_HLEN +VLAN_HLEN ) {netdev_err (dev->net,"asix_rx_fixup() Bad RX Length %d\n" , - size); + rx->size); +kfree_skb (rx->ax_skb);return 0 ; } - ax_skb =netdev_alloc_skb_ip_align (dev->net, size); -if (!ax_skb) -return 0 ; -skb_put (ax_skb, size); -memcpy (ax_skb->data, skb->data + offset, size); -usbnet_skb_return (dev, ax_skb); +if (rx->size > skb->len - offset) { + remaining = rx->size - (skb->len - offset); + rx->size = skb->len - offset; + } + + data =skb_put (rx->ax_skb, rx->size); +memcpy (data, skb->data + offset, rx->size); +if (!remaining) +usbnet_skb_return (dev, rx->ax_skb); - offset += (size +1 ) &0xfffe ; + offset += (rx->size +1 ) &0xfffe ; + rx->size = remaining; }if (skb->len != offset) { -netdev_err (dev->net,"asix_rx_fixup() Bad SKB Length %d\n" , - skb->len); +netdev_err (dev->net,"asix_rx_fixup() Bad SKB Length %d, %d\n" , + skb->len, offset);return 0 ; } +return 1 ; } +static int asix_rx_fixup_common (struct usbnet *dev,struct sk_buff *skb) +{ +struct asix_common_private *dp = dev->driver_priv; +struct asix_rx_fixup_info *rx = &dp->rx_fixup_info; + +return asix_rx_fixup_internal (dev, skb, rx); +} +static struct sk_buff *asix_tx_fixup (struct usbnet *dev,struct sk_buff *skb,gfp_t flags) {
@@ -1110,9 +1161,19 @@ static int ax88772_bind(struct usbnet *d dev->rx_urb_size =2048 ; } + dev->driver_priv =kzalloc (sizeof (struct asix_common_private ), +GFP_KERNEL ); +if (!dev->driver_priv) +return -ENOMEM ; +return 0 ; } +static void ax88772_unbind (struct usbnet *dev,struct usb_interface *intf) +{ +kfree (dev->driver_priv); +} +static const struct ethtool_ops ax88178_ethtool_ops = { .get_drvinfo = asix_get_drvinfo, .get_link = asix_get_link,
@@ -1445,6 +1506,11 @@ static int ax88178_bind(struct usbnet *d dev->rx_urb_size =2048 ; } + dev->driver_priv =kzalloc (sizeof (struct asix_common_private ), +GFP_KERNEL ); +if (!dev->driver_priv) +return -ENOMEM ; +return 0 ; }
@@ -1491,22 +1557,25 @@ static const struct driver_info hawking_static const struct driver_info ax88772_info = { .description ="ASIX AX88772 USB 2.0 Ethernet" , .bind = ax88772_bind, + .unbind = ax88772_unbind, .status = asix_status, .link_reset = ax88772_link_reset, .reset = ax88772_reset, - .flags =FLAG_ETHER |FLAG_FRAMING_AX |FLAG_LINK_INTR |FLAG_MULTI_PACKET , - .rx_fixup = asix_rx_fixup, + .flags =FLAG_ETHER |FLAG_FRAMING_AX |FLAG_LINK_INTR | +FLAG_MULTI_PACKET , + .rx_fixup = asix_rx_fixup_common, .tx_fixup = asix_tx_fixup, };static const struct driver_info ax88178_info = { .description ="ASIX AX88178 USB 2.0 Ethernet" , .bind = ax88178_bind, + .unbind = ax88772_unbind, .status = asix_status, .link_reset = ax88178_link_reset, .reset = ax88178_reset, .flags =FLAG_ETHER |FLAG_FRAMING_AX |FLAG_LINK_INTR , - .rx_fixup = asix_rx_fixup, + .rx_fixup = asix_rx_fixup_common, .tx_fixup = asix_tx_fixup, };
At Fri, 7 Mar 2014 17:06:56 -0800,
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
This kernel passed my test.
- Test Cases:
- Build this kernel.
- Boot this kernel.
- Build the latest mainline kernel with this kernel.
- Test Tool:
https://github.com/satoru-takeuchi/test-linux-stable
- Test Result (kernel .config, ktest config and test log):
http://satoru-takeuchi.org/test-linux-stable/results/<version>-<test datetime>.xz
- Build Environment:
- OS: Debian Jessy x86_64
- CPU: Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz x 4
- memory: 8GB
- Test Target Environment:
- Debian Jessy x86_64 (KVM guest on the Build Environment)
- # of vCPU: 2
- memory: 2GB
Thanks,
Satoru
Quoted 8 lines · Satoru Takeuchi
At Fri, 7 Mar 2014 17:06:56 -0800,
Quoted 6 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 5 lines
Quoted 2 lines
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
This kernel passed my test.
Same here.
Built results:
total: 119 pass: 97 skipped: 18 fail: 4
qemu tests all passed.
Details are available at http://server.roeck-us.net:8010/builders.
Guenter
Greg Kroah-Hartman
maintainerQuoted 15 lines · Guenter Roeck
Quoted 8 lines · Satoru Takeuchi
At Fri, 7 Mar 2014 17:06:56 -0800,
Quoted 6 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 5 lines
Quoted 2 lines
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
This kernel passed my test.
Quoted 8 lines
Same here.
Built results:
total: 119 pass: 97 skipped: 18 fail: 4qemu tests all passed.
Details are available at http://server.roeck-us.net:8010/builders.
Thanks to both of you for testing this, much appreciated.
greg k-h
Quoted 18 lines · Greg Kroah-Hartman
Quoted 17 lines · Guenter Roeck
Quoted 8 lines · Satoru Takeuchi
At Fri, 7 Mar 2014 17:06:56 -0800,
Quoted 6 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 5 lines
Quoted 2 lines
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
This kernel passed my test.
Same here.
Quoted 9 lines
Quoted 6 lines
Built results:
total: 119 pass: 97 skipped: 18 fail: 4qemu tests all passed.
Details are available at http://server.roeck-us.net:8010/builders.
Thanks to both of you for testing this, much appreciated.
You are welcome.
Can you possibly add me to the cc: of your introductory e-mail announcing new stable releases ? Sometimes it seems to get lost and isn't available on any of the 'common' archives (this one did not make it to lkml, for example, and many of the individual mails didn't make it into the stable mailing list at gmane).
Thanks,
Guenter
At Sat, 08 Mar 2014 09:10:00 -0800,
Quoted 30 lines · Guenter Roeck
Quoted 18 lines · Greg Kroah-Hartman
Quoted 17 lines · Guenter Roeck
Quoted 8 lines · Satoru Takeuchi
At Fri, 7 Mar 2014 17:06:56 -0800,
Quoted 6 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 5 lines
Quoted 2 lines
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
This kernel passed my test.
Same here.
Quoted 9 lines
Quoted 6 lines
Built results:
total: 119 pass: 97 skipped: 18 fail: 4qemu tests all passed.
Details are available at http://server.roeck-us.net:8010/builders.
Thanks to both of you for testing this, much appreciated.
Quoted 7 lines
You are welcome.
Can you possibly add me to the cc: of your introductory e-mail announcing new stable releases ? Sometimes it seems to get lost and isn't available on any of the 'common' archives (this one did not make it to lkml, for example, and many of the individual mails didn't make it into the stable mailing list at gmane).
Me too.
Thanks,
Satoru
Quoted 4 lines
Thanks,
Guenter
Quoted 34 lines · Satoru Takeuchi
At Sat, 08 Mar 2014 09:10:00 -0800,
Quoted 32 lines · Guenter Roeck
Quoted 18 lines · Greg Kroah-Hartman
Quoted 17 lines · Guenter Roeck
Quoted 8 lines · Satoru Takeuchi
At Fri, 7 Mar 2014 17:06:56 -0800,
Quoted 6 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 5 lines
Quoted 2 lines
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
This kernel passed my test.
Same here.
Quoted 9 lines
Quoted 6 lines
Built results:
total: 119 pass: 97 skipped: 18 fail: 4qemu tests all passed.
Details are available at http://server.roeck-us.net:8010/builders.
Thanks to both of you for testing this, much appreciated.
You are welcome.
Quoted 8 lines
Quoted 5 lines
Can you possibly add me to the cc: of your introductory e-mail announcing new stable releases ? Sometimes it seems to get lost and isn't available on any of the 'common' archives (this one did not make it to lkml, for example, and many of the individual mails didn't make it into the stable mailing list at gmane).
Me too.
Compile tests and boot tests passed on all my test systems. No dmesg regressions: emerg, crit, alert, err are clean. No regressions in warn.
I have a similar request for cc. The first message seems to get lost and messages don't get threaded correctly. Could you please cc me on the of your introductory e-mail.
thanks,
-- Shuah
Signature · 4 lines
Shuah Khan Senior Linux Kernel Developer - Open Source Group Samsung Research America(Silicon Valley) [email protected] | (970) 672-0658
Greg Kroah-Hartman
maintainerQuoted 44 lines · Shuah Khan
Quoted 34 lines · Satoru Takeuchi
At Sat, 08 Mar 2014 09:10:00 -0800,
Quoted 32 lines · Guenter Roeck
Quoted 18 lines · Greg Kroah-Hartman
Quoted 17 lines · Guenter Roeck
Quoted 8 lines · Satoru Takeuchi
At Fri, 7 Mar 2014 17:06:56 -0800,
Quoted 6 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 5 lines
Quoted 2 lines
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
This kernel passed my test.
Same here.
Quoted 9 lines
Quoted 6 lines
Built results:
total: 119 pass: 97 skipped: 18 fail: 4qemu tests all passed.
Details are available at http://server.roeck-us.net:8010/builders.
Thanks to both of you for testing this, much appreciated.
You are welcome.
Quoted 8 lines
Quoted 5 lines
Can you possibly add me to the cc: of your introductory e-mail announcing new stable releases ? Sometimes it seems to get lost and isn't available on any of the 'common' archives (this one did not make it to lkml, for example, and many of the individual mails didn't make it into the stable mailing list at gmane).
Me too.
Quoted 6 lines
Compile tests and boot tests passed on all my test systems. No dmesg
regressions: emerg, crit, alert, err are clean. No regressions in warn.I have a similar request for cc. The first message seems to get lost and messages don't get threaded correctly. Could you please cc me on the of your introductory e-mail.
Sure, now added, and thanks for testing.
greg k-h
Greg Kroah-Hartman
maintainerQuoted 34 lines · Satoru Takeuchi
At Sat, 08 Mar 2014 09:10:00 -0800,
Quoted 32 lines · Guenter Roeck
Quoted 18 lines · Greg Kroah-Hartman
Quoted 17 lines · Guenter Roeck
Quoted 8 lines · Satoru Takeuchi
At Fri, 7 Mar 2014 17:06:56 -0800,
Quoted 6 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 5 lines
Quoted 2 lines
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
This kernel passed my test.
Same here.
Quoted 9 lines
Quoted 6 lines
Built results:
total: 119 pass: 97 skipped: 18 fail: 4qemu tests all passed.
Details are available at http://server.roeck-us.net:8010/builders.
Thanks to both of you for testing this, much appreciated.
You are welcome.
Quoted 7 lines
Quoted 5 lines
Can you possibly add me to the cc: of your introductory e-mail announcing new stable releases ? Sometimes it seems to get lost and isn't available on any of the 'common' archives (this one did not make it to lkml, for example, and many of the individual mails didn't make it into the stable mailing list at gmane).
Me too.
You are added as well.
Greg Kroah-Hartman
maintainerQuoted 29 lines · Guenter Roeck
Quoted 18 lines · Greg Kroah-Hartman
Quoted 17 lines · Guenter Roeck
Quoted 8 lines · Satoru Takeuchi
At Fri, 7 Mar 2014 17:06:56 -0800,
Quoted 6 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.4.83 release. There are 99 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 5 lines
Quoted 2 lines
Responses should be made by Mon Mar 10 01:05:53 UTC 2014. Anything received after that time might be too late.
This kernel passed my test.
Same here.
Quoted 9 lines
Quoted 6 lines
Built results:
total: 119 pass: 97 skipped: 18 fail: 4qemu tests all passed.
Details are available at http://server.roeck-us.net:8010/builders.
Thanks to both of you for testing this, much appreciated.
Quoted 7 lines
You are welcome.
Can you possibly add me to the cc: of your introductory e-mail announcing new stable releases ? Sometimes it seems to get lost and isn't available on any of the 'common' archives (this one did not make it to lkml, for example, and many of the individual mails didn't make it into the stable mailing list at gmane).
Sure, now added.
Quoted 10 lines · Greg Kroah-Hartman
Quoted 6 lines
Can you possibly add me to the cc: of your introductory e-mail announcing new stable releases ? Sometimes it seems to get lost and isn't available on any of the 'common' archives (this one did not make it to lkml, for example, and many of the individual mails didn't make it into the stable mailing list at gmane).
Sure, now added.
Thanks a lot, appreciate it!
Guenter