From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755211AbdCPQfL (ORCPT ); Thu, 16 Mar 2017 12:35:11 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:34844 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755067AbdCPQeh (ORCPT ); Thu, 16 Mar 2017 12:34:37 -0400 Date: Thu, 16 Mar 2017 16:34:14 +0000 From: Ben Hutchings To: linux-kernel@vger.kernel.org, Andrew Morton , torvalds@linux-foundation.org, Jiri Slaby , stable@vger.kernel.org Cc: lwn@lwn.net Message-ID: <20170316163414.GR4152@decadent.org.uk> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="yKkvi6mMqAM+MlBZ" Content-Disposition: inline X-Mailer: LinuxStableQueue (scripts by bwh) User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: ben@decadent.org.uk Subject: Linux 3.2.87 X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on shadbolt.decadent.org.uk) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --yKkvi6mMqAM+MlBZ Content-Type: multipart/mixed; boundary="Qn4G1eBrv+t66M9q" Content-Disposition: inline --Qn4G1eBrv+t66M9q Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable I'm announcing the release of the 3.2.87 kernel. (This time with a signed mail.) All users of the 3.2 kernel series should upgrade. The updated 3.2.y git tree can be found at: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable= =2Egit linux-3.2.y and can be browsed at the normal kernel.org git web browser: https://git.kernel.org/?p=3Dlinux/kernel/git/stable/linux-stable.git The diff from 3.2.86 is attached to this message. Ben. ------------ Makefile | 2 +- arch/arm/include/asm/cputype.h | 3 + arch/arm/kernel/hw_breakpoint.c | 16 +++ arch/arm/kernel/ptrace.c | 2 +- arch/cris/boot/rescue/Makefile | 8 ++ arch/parisc/include/asm/bitops.h | 8 +- arch/parisc/include/asm/bitsperlong.h | 2 - arch/parisc/include/asm/swab.h | 5 +- arch/powerpc/boot/ps3-head.S | 5 - arch/powerpc/boot/ps3.c | 8 +- arch/powerpc/include/asm/ppc-opcode.h | 6 +- arch/powerpc/kernel/ibmebus.c | 16 ++- arch/powerpc/kernel/ptrace.c | 7 + arch/sparc/kernel/leon_kernel.c | 56 ++++---- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kvm/x86.c | 17 +-- crypto/algapi.c | 1 + drivers/ata/sata_mv.c | 3 + drivers/base/dma-mapping.c | 4 +- drivers/base/regmap/regcache-lzo.c | 8 +- drivers/block/nbd.c | 34 +++-- drivers/crypto/caam/caamalg.c | 4 +- drivers/hid/hid-cypress.c | 3 + drivers/hwmon/ds620.c | 2 +- drivers/i2c/i2c-dev.c | 2 +- drivers/infiniband/core/mad.c | 2 +- drivers/infiniband/core/multicast.c | 7 +- drivers/infiniband/hw/mlx4/main.c | 1 + drivers/input/serio/i8042-x86ia64io.h | 6 + drivers/iommu/amd_iommu.c | 2 +- drivers/md/dm-crypt.c | 7 +- drivers/media/dvb/siano/smsusb.c | 17 ++- drivers/media/rc/ite-cir.c | 2 + drivers/media/video/davinci/vpfe_capture.c | 1 + drivers/mmc/host/mxs-mmc.c | 6 +- drivers/net/can/ti_hecc.c | 16 ++- drivers/net/ethernet/korina.c | 8 +- drivers/net/ethernet/marvell/sky2.c | 13 ++ drivers/net/ethernet/mellanox/mlx4/cq.c | 38 ++--- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 8 +- drivers/net/ethernet/mellanox/mlx4/icm.c | 7 +- drivers/net/ethernet/xilinx/xilinx_emaclite.c | 10 +- drivers/net/macvtap.c | 4 +- drivers/net/tun.c | 20 ++- drivers/net/usb/catc.c | 56 +++++--- drivers/net/usb/rtl8150.c | 34 ++++- drivers/net/xen-netfront.c | 4 +- drivers/pci/hotplug/rpadlpar_core.c | 10 +- drivers/pci/pci.c | 4 + drivers/platform/x86/intel_mid_powerbtn.c | 2 +- drivers/s390/char/vmlogrdr.c | 2 +- drivers/s390/scsi/zfcp_dbf.c | 17 ++- drivers/s390/scsi/zfcp_dbf.h | 41 +++++- drivers/s390/scsi/zfcp_erp.c | 61 +++++++- drivers/s390/scsi/zfcp_ext.h | 4 +- drivers/s390/scsi/zfcp_fsf.c | 8 +- drivers/s390/scsi/zfcp_fsf.h | 3 +- drivers/s390/scsi/zfcp_reqlist.h | 30 +++- drivers/s390/scsi/zfcp_scsi.c | 61 +++++++- drivers/scsi/mvsas/mv_94xx.c | 2 +- drivers/scsi/scsi_sysfs.c | 4 - drivers/scsi/sg.c | 4 + drivers/ssb/pci.c | 1 + drivers/staging/gma500/psb_drv.c | 3 + drivers/staging/hv/netvsc_drv.c | 4 + drivers/staging/iio/adc/ad7606_core.c | 2 +- drivers/staging/vme/bridges/vme_ca91cx42.c | 2 +- drivers/target/iscsi/iscsi_target_tpg.c | 1 - drivers/thermal/thermal_sys.c | 2 +- drivers/tty/n_hdlc.c | 143 +++++++++---------- drivers/tty/sysrq.c | 4 +- drivers/usb/class/cdc-acm.c | 1 + drivers/usb/core/config.c | 10 ++ drivers/usb/core/quirks.c | 4 + drivers/usb/gadget/composite.c | 14 +- drivers/usb/gadget/dummy_hcd.c | 6 +- drivers/usb/gadget/inode.c | 17 ++- drivers/usb/host/uhci-pci.c | 4 + drivers/usb/host/xhci-mem.c | 42 +++++- drivers/usb/host/xhci-ring.c | 6 - drivers/usb/host/xhci.c | 12 -- drivers/usb/musb/musbhsdma.h | 2 +- drivers/usb/serial/ch341.c | 192 ++++++++++++++++------= ---- drivers/usb/serial/cyberjack.c | 3 + drivers/usb/serial/garmin_gps.c | 1 + drivers/usb/serial/io_edgeport.c | 5 + drivers/usb/serial/io_ti.c | 16 ++- drivers/usb/serial/iuu_phoenix.c | 5 + drivers/usb/serial/keyspan_pda.c | 8 +- drivers/usb/serial/kl5kusb105.c | 35 +++-- drivers/usb/serial/kobil_sct.c | 5 + drivers/usb/serial/mos7720.c | 51 +++---- drivers/usb/serial/mos7840.c | 10 +- drivers/usb/serial/omninet.c | 6 + drivers/usb/serial/option.c | 7 + drivers/usb/serial/oti6858.c | 8 ++ drivers/usb/serial/pl2303.c | 9 ++ drivers/usb/serial/pl2303.h | 1 + drivers/usb/serial/spcp8x5.c | 7 + drivers/usb/serial/ti_usb_3410_5052.c | 7 + fs/block_dev.c | 2 +- fs/btrfs/ioctl.c | 6 +- fs/btrfs/tree-log.c | 3 +- fs/ceph/mds_client.c | 4 +- fs/ext4/inode.c | 6 + fs/ext4/mballoc.c | 4 +- fs/ext4/super.c | 64 +++++---- fs/nfs/file.c | 2 +- fs/notify/inode_mark.c | 46 ++---- fs/ocfs2/dlmglue.c | 10 ++ fs/ocfs2/stackglue.c | 6 + fs/ocfs2/stackglue.h | 3 + fs/splice.c | 1 + fs/ubifs/tnc.c | 25 +++- fs/xfs/xfs_dfrag.c | 7 +- include/linux/can/core.h | 7 +- include/linux/cpu.h | 12 +- include/linux/list.h | 11 ++ include/linux/netdevice.h | 9 +- include/net/cipso_ipv4.h | 4 + include/net/sock.h | 17 ++- ipc/shm.c | 9 +- kernel/cpu.c | 13 +- kernel/futex.c | 2 +- kernel/sysctl.c | 1 + lib/vsprintf.c | 2 +- mm/filemap.c | 5 + mm/huge_memory.c | 19 ++- net/bridge/br_ioctl.c | 5 +- net/can/af_can.c | 12 +- net/can/af_can.h | 3 +- net/can/bcm.c | 27 ++-- net/can/gw.c | 2 +- net/can/raw.c | 4 +- net/ceph/messenger.c | 13 ++ net/core/dev.c | 6 +- net/core/drop_monitor.c | 39 ++++-- net/core/sock.c | 15 +- net/dccp/ipv4.c | 26 ++-- net/dccp/ipv6.c | 15 +- net/dccp/proto.c | 4 + net/decnet/dn_route.c | 9 +- net/ipv4/cipso_ipv4.c | 4 + net/ipv4/igmp.c | 55 ++++++-- net/ipv4/ipmr.c | 4 +- net/ipv4/ping.c | 2 + net/ipv4/route.c | 12 ++ net/ipv4/tcp_output.c | 21 +-- net/ipv6/addrconf.c | 4 +- net/ipv6/af_inet6.c | 1 + net/ipv6/ip6_tunnel.c | 47 +++++-- net/ipv6/ip6mr.c | 1 + net/ipv6/mcast.c | 50 ++++--- net/ipv6/raw.c | 7 +- net/irda/irqueue.c | 34 +++-- net/l2tp/l2tp_core.h | 1 + net/l2tp/l2tp_ip.c | 27 +++- net/llc/llc_conn.c | 3 + net/llc/llc_sap.c | 3 + net/mac80211/mesh.c | 2 +- net/packet/af_packet.c | 45 ++++-- net/sched/act_pedit.c | 24 +++- net/sched/cls_api.c | 4 +- net/sched/em_meta.c | 9 +- net/sched/sch_dsmark.c | 3 + net/sched/sch_htb.c | 5 +- net/sctp/socket.c | 19 ++- net/socket.c | 19 ++- net/sunrpc/auth_gss/svcauth_gss.c | 2 +- scripts/kconfig/nconf.gui.c | 15 +- sound/core/seq/seq_memory.c | 9 +- sound/core/seq/seq_queue.c | 33 +++-- sound/usb/card.c | 1 - sound/usb/mixer.c | 3 +- tools/perf/util/trace-event-scripting.c | 6 +- 175 files changed, 1613 insertions(+), 744 deletions(-) Aidan Thornton (2): USB: serial: ch341: add register and USB request definitions USB: serial: ch341: reinitialize chip on reconfiguration Akinobu Mita (1): sysrq: attach sysrq handler correctly for 32-bit kernel Al Viro (2): nfs_write_end(): fix handling of short copies Fix missing sanity check in /dev/sg Alan Stern (7): PCI: Check for PME in targeted sleep state USB: UHCI: report non-PME wakeup signalling for Intel hardware USB: dummy-hcd: fix bug in stop_activity (handle ep0) USB: gadgetfs: fix unbounded memory allocation bug USB: gadgetfs: fix use-after-free bug USB: gadgetfs: fix checks of wTotalLength in config descriptors USB: fix problems with duplicate endpoint addresses Alex Porosanu (1): crypto: caam - fix AEAD givenc descriptors Alexander Popov (1): tty: n_hdlc: get rid of racy n_hdlc.tbuf Amir Vadai (1): net/sched: pedit: make sure that offset is valid Andy Shevchenko (1): platform/x86: intel_mid_powerbtn: Set IRQ_ONESHOT Anoob Soman (2): packet: call fanout_release, while UNREGISTERING a netdev packet: Do not call fanout_release from atomic contexts Anssi Hannula (1): net: xilinx_emaclite: fix receive buffer overflow Anton Blanchard (1): powerpc: Ignore reserved field in DCSR and PVR reads and writes Arnaldo Carvalho de Melo (1): perf scripting: Avoid leaking the scripting_context variable Arnd Bergmann (2): scsi: mvsas: fix command_active typo DaVinci-VPFE-Capture: fix error handling Arvind Yadav (1): ata: sata_mv:- Handle return value of devm_ioremap. Augusto Mecking Caringi (1): vme: Fix wrong pointer utilization in ca91cx42_slave_get Bart Van Assche (2): IB/mad: Fix an array index check IB/multicast: Check ib_find_pkey() return value Ben Hutchings (7): kconfig/nconf: Fix hang when editing symbol with a long prompt rtl8150: Use heap buffers for all register access catc: Combine failure cleanup code in catc_probe() catc: Use heap buffer for memory size test net/sock: Add sock_efree() function Revert "KVM: x86: expose MSR_TSC_AUX to userspace" Linux 3.2.87 Benjamin Block (1): scsi: zfcp: fix use-after-"free" in FC ingress path after TMF Bj=C3=B8rn Mork (1): USB: serial: option: add device ID for HP lt2523 (Novatel E371) Boris Ostrovsky (1): xen-netfront: Delete rx_refill_timer in xennet_disconnect_backend() Chandan Rajendra (2): ext4: fix mballoc breakage with 64k block size ext4: fix stack memory corruption with 64k block size Chris Friesen (1): route: do not cache fib route info on local routes with oif Con Kolivas (1): ALSA: usb-audio: Add QuickCam Communicate Deluxe/S7500 to volume_cont= rol_quirks Dan Carpenter (4): usb: xhci-mem: use passed in GFP flags instead of GFP_KERNEL sparc: leon: Fix a retry loop in leon_init_timers() target/iscsi: Fix double free in lio_target_tiqn_addtpg() ipv6: pointer math error in ip6_tnl_parse_tlv_enc_lim() Daniel Borkmann (1): net, sched: fix soft lockup in tc_classify Daniele Palmas (1): USB: serial: option: add support for Telit LE922A PIDs 0x1040, 0x1041 Darrick J. Wong (1): ext4: reject inodes with negative size Dave Jones (1): ipv6: handle -EFAULT from skb_copy_bits Dave Martin (2): powerpc/ptrace: Preserve previous fprs/vsrs on short regset write ARM: 8643/3: arm/ptrace: Preserve previous registers for short regset= write David S. Miller (2): irda: Fix lockdep annotations in hashbin_delete(). decnet: Do not build routes to devices without decnet private data. Davidlohr Bueso (1): ipc/shm: Fix shmat mmap nil-page protection Douglas Caetano dos Santos (1): tcp: fix wrong checksum calculation on MTU probing Eric Dumazet (18): gro: use min_t() in skb_gro_reset_offset() sysctl: fix proc_doulongvec_ms_jiffies_minmax() netlabel: out of bound access in cipso_v4_validate() l2tp: do not use udp_ioctl() net/llc: avoid BUG_ON() in skb_orphan() packet: fix races in fanout_add() net: fix sk_mem_reclaim_partial() tcp: fix overflow in __tcp_retransmit_skb() net: avoid sk_forward_alloc overflows net: clear sk_err_soft in sk_clone_lock() net: mangle zero checksum in skb_checksum_help() dccp: do not send reset to already closed sockets dccp: fix out of bound access in dccp_v4_err() ipv6: dccp: fix out of bound access in dccp_v6_err() net/dccp: fix use-after-free in dccp_invalid_packet can: Fix kernel panic at security_sock_rcv_skb ipv6: fix ip6_tnl_parse_tlv_enc_lim() tcp: fix 0 divide in __tcp_select_window() Eric Ren (1): ocfs2: fix crash caused by stale lvb with fsdlm plugin Eric Sandeen (1): xfs: fix up xfs_swap_extent_forks inline extent handling Eugenia Emantayev (1): net/mlx4_en: Fix bad WQE issue Eva Rachel Retuya (1): staging: iio: ad7606: fix improper setting of oversampling pins Felipe Balbi (1): usb: gadget: composite: correctly initialize ep->maxpacket Florian Fainelli (2): drivers: base: dma-mapping: Fix typo in dmam_alloc_non_coherent comme= nts net: korina: Fix NAPI versus resources freeing Geoff Levand (1): powerpc/ps3: Fix system hang with GCC 5 builds Gerald Schaefer (1): s390/vmlogrdr: fix IUCV buffer allocation Greg Kroah-Hartman (2): usb: gadgetfs: restrict upper bound on device configuration size HID: hid-cypress: validate length of report Guenter Roeck (2): cris: Only build flash rescue image if CONFIG_ETRAX_AXISFLASHMAP is s= elected hwmon: (ds620) Fix overflows seen when writing temperature limits Hangbin Liu (3): igmp: do not remove igmp souce list info when set link down mld: do not remove mld souce list info when set link down igmp, mld: Fix memory leak in igmpv3/mld_del_delrec() Helge Deller (1): parisc: Don't use BITS_PER_LONG in userspace-exported swab.h header Herbert Xu (3): gro: Enter slow-path if there is no tailroom gro: Disable frag0 optimization on IPv6 ext headers tun: Fix TUN_PKT_STRIP setting Huang Rui (1): iommu/amd: Fix the left value check of cmd buffer Ilya Dryomov (1): libceph: verify authorize reply on connect J. Bruce Fields (1): svcrpc: don't leak contexts on PROC_DESTROY Jack Morgenstein (1): net/mlx4_core: Fix racy CQ (Completion Queue) free Jan Kara (1): fsnotify: Fix possible use-after-free in inode iteration on umount Jeff Layton (1): ceph: fix bad endianness handling in parse_reply_info_extra Jeff Mahoney (1): btrfs: fix btrfs_compat_ioctl failures on non-compat ioctls Jens Axboe (1): nbd: fix use-after-free of rq/bio in the xmit path Jeremy Linton (1): net: sky2: Fix shutdown crash Jiri Pirko (1): list: introduce list_first_entry_or_null Jiri Slaby (2): net: sctp, forbid negative length TTY: n_hdlc, fix lockdep false positive Johan Hovold (32): powerpc/ibmebus: Fix device reference leaks in sysfs interface powerpc/ibmebus: Fix further device reference leaks powerpc/pci/rpadlpar: Fix device reference leaks USB: serial: kl5kusb105: fix open error path USB: serial: cyberjack: fix NULL-deref at open USB: serial: garmin_gps: fix memory leak on failed URB submit USB: serial: io_edgeport: fix NULL-deref at open USB: serial: io_ti: fix NULL-deref at open USB: serial: io_ti: fix another NULL-deref at open USB: serial: iuu_phoenix: fix NULL-deref at open USB: serial: keyspan_pda: verify endpoints at probe USB: serial: kobil_sct: fix NULL-deref in write USB: serial: mos7720: fix NULL-deref at open USB: serial: mos7720: fix use-after-free on probe errors USB: serial: mos7720: fix parport use-after-free on probe errors USB: serial: mos7720: fix parallel probe USB: serial: mos7840: fix NULL-deref at open USB: serial: mos7840: fix misleading interrupt-URB comment USB: serial: omninet: fix NULL-derefs at open and disconnect USB: serial: oti6858: fix NULL-deref at open USB: serial: pl2303: fix NULL-deref at open USB: serial: spcp8x5: fix NULL-deref at open USB: serial: ti_usb_3410_5052: fix NULL-deref at open USB: ch341: forward USB errors to USB serial core USB: ch341: remove redundant close from open error path USB: serial: ch341: fix initial modem-control state USB: serial: ch341: fix open and resume after B0 USB: serial: ch341: fix modem-control and B0 handling USB: serial: ch341: fix open error handling USB: serial: ch341: fix resume after reset USB: serial: ch341: fix baud rate and line-control handling USB: serial: ch341: fix control-message error handling Josef Bacik (1): nbd: only set MSG_MORE when we have more to send Kefeng Wang (1): ipv6: addrconf: Avoid addrconf_disable_change() using RCU read-side l= ock Keno Fischer (1): mm/huge_memory.c: respect FOLL_FORCE/FOLL_COW for thp Kirtika Ruchandani (1): regmap: cache: Remove unused 'blksize' variable Krzysztof Kozlowski (1): thermal: hwmon: Properly report critical temperature in sysfs Krzysztof Opasiak (1): usb: gadget: composite: Test get_alt() presence instead of set_alt() Larry Finger (1): ssb: Fix error routine when fallback SPROM fails Leon Romanovsky (1): net/mlx4: Remove BUG_ON from ICM allocation routine Lukasz Odzioba (1): x86/cpu: Fix bootup crashes by sanitizing the argument of the 'clearc= puid=3D' command-line option Luk=C3=A1=C5=A1 Lalinsk=C3=BD (1): USB: Add quirk for WORLDE easykey.25 MIDI keyboard Maor Gottlieb (1): IB/mlx4: Put non zero value in max_ah device attribute Marcel J.E. Mol (1): USB: serial: pl2303: add ATEN device ID Marcelo Ricardo Leitner (3): sctp: assign assoc_id earlier in __sctp_connect sctp: avoid BUG_ON on sctp_wait_for_sndbuf sctp: deny peeloff operation on asocs with threads sleeping on it Marcos Paulo de Souza (1): Input: i8042 - add Pegatron touchpad to noloop table Mark Rutland (1): ARM: 8634/1: hw_breakpoint: blacklist Scorpion CPUs Mathias Nyman (2): xhci: free xhci virtual devices with leaf nodes first xhci: fix deadlock at host remove by running watchdog correctly Mauro Carvalho Chehab (1): siano: make it work again with CONFIG_VMAP_STACK Maxime Jayat (1): net: socket: fix recvmmsg not returning error from sock_error Michal Hocko (2): hotplug: Make register and unregister notifier API symmetric mm, fs: check for fatal signals in do_generic_file_read() Michal Tesar (1): igmp: Make igmp group member RFC 3376 compliant Miklos Szeredi (1): vfs: fix uninitialized flags in splice_to_pipe() Nathaniel Quillin (1): USB: cdc-acm: add device id for GW Instek AFG-125 NeilBrown (1): block_dev: don't test bdev->bd_contains when it is not stable Nicolas Iooss (1): ite-cir: initialize use_demodulator before using it Nicolas PLANEL (1): USB: ch341: set tty baud speed according to tty struct Nikolay Aleksandrov (1): net: bridge: fix old ioctl unlocked net device walk Oliver Hartkopp (1): can: bcm: fix hrtimer/tasklet termination in bcm op removal Ondrej Kozina (1): dm crypt: mark key as invalid until properly loaded Pan Bian (1): USB: serial: kl5kusb105: abort on open exception path Paolo Abeni (1): ip6_tunnel: disable caching when the traffic class is inherited Patrik Jakobsson (1): drm/gma500: Add compat ioctl Rasmus Villemoes (1): lib/vsprintf.c: improve sanity check in vsnprintf() Reiter Wolfgang (2): drop_monitor: add missing call to genlmsg_end drop_monitor: consider inserted data in genlmsg_end Richard Weinberger (1): ubifs: Fix journal replay wrt. xattr nodes Robbie Ko (1): Btrfs: fix tree search logic when replaying directory entry deletes Salvatore Benedetto (1): crypto: api - Clear CRYPTO_ALG_DEAD bit before registering an alg Shmulik Ladkani (1): net/sched: em_meta: Fix 'meta vlan' to correctly recognize zero VID f= rames Soheil Hassas Yeganeh (1): sock: fix sendmmsg for partial sendmsg Stefan Wahren (1): mmc: mxs-mmc: Fix additional cycles after transmission stop Steffen Maier (3): scsi: zfcp: do not trace pure benign residual HBA responses at defaul= t level scsi: zfcp: fix rport unblock race with LUN recovery scsi: zfcp: fix use-after-free by not tracing WKA port open/close on = failed send Takashi Iwai (3): ALSA: usb-audio: Fix bogus error return in snd_usb_create_stream() ALSA: seq: Don't handle loop timeout at snd_seq_pool_done() ALSA: seq: Fix race at creating a queue Theodore Ts'o (3): ext4: fix in-superblock mount options processing ext4: use more strict checks for inodes_per_block on mount ext4: add sanity checking to count_overhead() Thorsten Horstmann (1): mac80211: Fix adding of mesh vendor IEs Tom Goff (1): ipmr/ip6mr: Initialize the last assert time of mfc entries. Tony Lindgren (1): usb: musb: Fix trying to free already-free IRQ 4 Vlad Tsyrklevich (1): i2c: fix kernel memory disclosure in dev interface WANG Cong (3): ping: fix a null pointer dereference sch_htb: update backlog as well sch_dsmark: update backlog as well Wei Fang (1): scsi: avoid a permanent stop of the scsi device's request queue Willem de Bruijn (2): tun: read vnet_hdr_sz once macvtap: read vnet_hdr_size once Yang Yang (1): futex: Move futex_init() to core_initcall Yegor Yefremov (1): can: ti_hecc: add missing prepare and unprepare of the clock stephen hemminger (1): netvsc: reduce maximum GSO size --Qn4G1eBrv+t66M9q Content-Type: text/x-diff; charset=UTF-8; name="linux-3.2.87.patch" Content-Disposition: attachment; filename="linux-3.2.87.patch" Content-Transfer-Encoding: quoted-printable diff --git a/Makefile b/Makefile index d3f775cb0a5a..74390f97c6e5 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION =3D 3 PATCHLEVEL =3D 2 -SUBLEVEL =3D 86 +SUBLEVEL =3D 87 EXTRAVERSION =3D NAME =3D Saber-toothed Squirrel =20 diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index cb47d28cbe1f..a6f926be910f 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -25,6 +25,9 @@ #define CPUID_EXT_ISAR4 "c2, 4" #define CPUID_EXT_ISAR5 "c2, 5" =20 +/* Qualcomm implemented cores */ +#define ARM_CPU_PART_SCORPION 0x510002d0 + extern unsigned int processor_id; =20 #ifdef CONFIG_CPU_CP15 diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoin= t.c index 2bc1a8e92305..bdafb83cd52e 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -1001,6 +1001,22 @@ static int __init arch_hw_breakpoint_init(void) return 0; } =20 + /* + * Scorpion CPUs (at least those in APQ8060) seem to set DBGPRSR.SPD + * whenever a WFI is issued, even if the core is not powered down, in + * violation of the architecture. When DBGPRSR.SPD is set, accesses to + * breakpoint and watchpoint registers are treated as undefined, so + * this results in boot time and runtime failures when these are + * accessed and we unexpectedly take a trap. + * + * It's not clear if/how this can be worked around, so we blacklist + * Scorpion CPUs to avoid these issues. + */ + if ((read_cpuid_id() & 0xff00fff0) =3D=3D ARM_CPU_PART_SCORPION) { + pr_info("Scorpion CPU detected. Hardware breakpoints and watchpoints dis= abled\n"); + return 0; + } + /* Determine how many BRPs/WRPs are available. */ core_num_brps =3D get_num_brps(); core_num_wrps =3D get_num_wrps(); diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 8b17fb452af8..b73ae6e5824d 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -593,7 +593,7 @@ static int gpr_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { int ret; - struct pt_regs newregs; + struct pt_regs newregs =3D *task_pt_regs(target); =20 ret =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, diff --git a/arch/cris/boot/rescue/Makefile b/arch/cris/boot/rescue/Makefile index 52bd0bd1dd22..d98edbb30a18 100644 --- a/arch/cris/boot/rescue/Makefile +++ b/arch/cris/boot/rescue/Makefile @@ -10,6 +10,9 @@ =20 asflags-y +=3D $(LINUXINCLUDE) ccflags-y +=3D -O2 $(LINUXINCLUDE) + +ifdef CONFIG_ETRAX_AXISFLASHMAP + arch-$(CONFIG_ETRAX_ARCH_V10) =3D v10 arch-$(CONFIG_ETRAX_ARCH_V32) =3D v32 =20 @@ -28,6 +31,11 @@ $(obj)/rescue.bin: $(obj)/rescue.o FORCE $(call if_changed,objcopy) cp -p $(obj)/rescue.bin $(objtree) =20 +else +$(obj)/rescue.bin: + +endif + $(obj)/testrescue.bin: $(obj)/testrescue.o $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin # Pad it to 784 bytes diff --git a/arch/parisc/include/asm/bitops.h b/arch/parisc/include/asm/bit= ops.h index 8c9b631d2a78..8c00e6c06266 100644 --- a/arch/parisc/include/asm/bitops.h +++ b/arch/parisc/include/asm/bitops.h @@ -6,7 +6,7 @@ #endif =20 #include -#include /* for BITS_PER_LONG/SHIFT_PER_LONG */ +#include #include #include =20 @@ -16,6 +16,12 @@ * to include/asm-i386/bitops.h or kerneldoc */ =20 +#if __BITS_PER_LONG =3D=3D 64 +#define SHIFT_PER_LONG 6 +#else +#define SHIFT_PER_LONG 5 +#endif + #define CHOP_SHIFTCOUNT(x) (((unsigned long) (x)) & (BITS_PER_LONG - 1)) =20 =20 diff --git a/arch/parisc/include/asm/bitsperlong.h b/arch/parisc/include/as= m/bitsperlong.h index 75196b415d3f..540c94de4427 100644 --- a/arch/parisc/include/asm/bitsperlong.h +++ b/arch/parisc/include/asm/bitsperlong.h @@ -9,10 +9,8 @@ */ #if (defined(__KERNEL__) && defined(CONFIG_64BIT)) || defined (__LP64__) #define __BITS_PER_LONG 64 -#define SHIFT_PER_LONG 6 #else #define __BITS_PER_LONG 32 -#define SHIFT_PER_LONG 5 #endif =20 #include diff --git a/arch/parisc/include/asm/swab.h b/arch/parisc/include/asm/swab.h index e78403b129ef..928e1bbac98f 100644 --- a/arch/parisc/include/asm/swab.h +++ b/arch/parisc/include/asm/swab.h @@ -1,6 +1,7 @@ #ifndef _PARISC_SWAB_H #define _PARISC_SWAB_H =20 +#include #include #include =20 @@ -38,7 +39,7 @@ static inline __attribute_const__ __u32 __arch_swab32(__u= 32 x) } #define __arch_swab32 __arch_swab32 =20 -#if BITS_PER_LONG > 32 +#if __BITS_PER_LONG > 32 /* ** From "PA-RISC 2.0 Architecture", HP Professional Books. ** See Appendix I page 8 , "Endian Byte Swapping". @@ -61,6 +62,6 @@ static inline __attribute_const__ __u64 __arch_swab64(__u= 64 x) return x; } #define __arch_swab64 __arch_swab64 -#endif /* BITS_PER_LONG > 32 */ +#endif /* __BITS_PER_LONG > 32 */ =20 #endif /* _PARISC_SWAB_H */ diff --git a/arch/powerpc/boot/ps3-head.S b/arch/powerpc/boot/ps3-head.S index b6fcbaf5027b..3dc44b05fb97 100644 --- a/arch/powerpc/boot/ps3-head.S +++ b/arch/powerpc/boot/ps3-head.S @@ -57,11 +57,6 @@ __system_reset_overlay: bctr =20 1: - /* Save the value at addr zero for a null pointer write check later. */ - - li r4, 0 - lwz r3, 0(r4) - /* Primary delays then goes to _zimage_start in wrapper. */ =20 or 31, 31, 31 /* db16cyc */ diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c index 9954d98871d0..029ea3ce1588 100644 --- a/arch/powerpc/boot/ps3.c +++ b/arch/powerpc/boot/ps3.c @@ -119,13 +119,12 @@ void ps3_copy_vectors(void) flush_cache((void *)0x100, 512); } =20 -void platform_init(unsigned long null_check) +void platform_init(void) { const u32 heapsize =3D 0x1000000 - (u32)_end; /* 16MiB */ void *chosen; unsigned long ft_addr; u64 rm_size; - unsigned long val; =20 console_ops.write =3D ps3_console_write; platform_ops.exit =3D ps3_exit; @@ -153,11 +152,6 @@ void platform_init(unsigned long null_check) =20 printf(" flat tree at 0x%lx\n\r", ft_addr); =20 - val =3D *(unsigned long *)0; - - if (val !=3D null_check) - printf("null check failed: %lx !=3D %lx\n\r", val, null_check); - ((kernel_entry_t)0)(ft_addr, 0, NULL); =20 ps3_exit(); diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/a= sm/ppc-opcode.h index e980faae4225..c8d7f2442620 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -31,7 +31,7 @@ #define PPC_INST_MCRXR 0x7c000400 #define PPC_INST_MCRXR_MASK 0xfc0007fe #define PPC_INST_MFSPR_PVR 0x7c1f42a6 -#define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff +#define PPC_INST_MFSPR_PVR_MASK 0xfc1ffffe #define PPC_INST_MSGSND 0x7c00019c #define PPC_INST_NOP 0x60000000 #define PPC_INST_POPCNTB 0x7c0000f4 @@ -42,9 +42,9 @@ #define PPC_INST_RFDI 0x4c00004e #define PPC_INST_RFMCI 0x4c00004c #define PPC_INST_MFSPR_DSCR 0x7c1102a6 -#define PPC_INST_MFSPR_DSCR_MASK 0xfc1fffff +#define PPC_INST_MFSPR_DSCR_MASK 0xfc1ffffe #define PPC_INST_MTSPR_DSCR 0x7c1103a6 -#define PPC_INST_MTSPR_DSCR_MASK 0xfc1fffff +#define PPC_INST_MTSPR_DSCR_MASK 0xfc1ffffe =20 #define PPC_INST_STRING 0x7c00042a #define PPC_INST_STRING_MASK 0xfc0007fe diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index d39ae606ff8d..b8cd924eb9de 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -179,6 +179,7 @@ static int ibmebus_create_device(struct device_node *dn) static int ibmebus_create_devices(const struct of_device_id *matches) { struct device_node *root, *child; + struct device *dev; int ret =3D 0; =20 root =3D of_find_node_by_path("/"); @@ -187,9 +188,12 @@ static int ibmebus_create_devices(const struct of_devi= ce_id *matches) if (!of_match_node(matches, child)) continue; =20 - if (bus_find_device(&ibmebus_bus_type, NULL, child, - ibmebus_match_node)) + dev =3D bus_find_device(&ibmebus_bus_type, NULL, child, + ibmebus_match_node); + if (dev) { + put_device(dev); continue; + } =20 ret =3D ibmebus_create_device(child); if (ret) { @@ -261,6 +265,7 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus, const char *buf, size_t count) { struct device_node *dn =3D NULL; + struct device *dev; char *path; ssize_t rc =3D 0; =20 @@ -268,8 +273,10 @@ static ssize_t ibmebus_store_probe(struct bus_type *bu= s, if (!path) return -ENOMEM; =20 - if (bus_find_device(&ibmebus_bus_type, NULL, path, - ibmebus_match_path)) { + dev =3D bus_find_device(&ibmebus_bus_type, NULL, path, + ibmebus_match_path); + if (dev) { + put_device(dev); printk(KERN_WARNING "%s: %s has already been probed\n", __func__, path); rc =3D -EEXIST; @@ -305,6 +312,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bu= s, if ((dev =3D bus_find_device(&ibmebus_bus_type, NULL, path, ibmebus_match_path))) { of_device_unregister(to_platform_device(dev)); + put_device(dev); =20 kfree(path); return count; diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 5de73dbd15c7..b7ab4b483e65 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -359,6 +359,10 @@ static int fpr_set(struct task_struct *target, const s= truct user_regset *regset, flush_fp_to_thread(target); =20 #ifdef CONFIG_VSX + for (i =3D 0; i < 32 ; i++) + buf[i] =3D target->thread.TS_FPR(i); + memcpy(&buf[32], &target->thread.fpscr, sizeof(double)); + /* copy to local buffer then write that out */ i =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); if (i) @@ -501,6 +505,9 @@ static int vsr_set(struct task_struct *target, const st= ruct user_regset *regset, =20 flush_vsx_to_thread(target); =20 + for (i =3D 0; i < 32 ; i++) + buf[i] =3D target->thread.fpr[i][TS_VSRLOWOFFSET]; + ret =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, 32 * sizeof(double)); for (i =3D 0; i < 32 ; i++) diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kerne= l.c index a19c8a063683..863a035e80d9 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -288,37 +288,37 @@ void __init leon_init_timers(irq_handler_t counter_fn) =20 /* Find GPTIMER Timer Registers base address otherwise bail out. */ nnp =3D rootnp; - do { - np =3D of_find_node_by_name(nnp, "GAISLER_GPTIMER"); - if (!np) { - np =3D of_find_node_by_name(nnp, "01_011"); - if (!np) - goto bad; - } =20 - ampopts =3D 0; - pp =3D of_find_property(np, "ampopts", &len); - if (pp) { - ampopts =3D *(int *)pp->value; - if (ampopts =3D=3D 0) { - /* Skip this instance, resource already - * allocated by other OS */ - nnp =3D np; - continue; - } +retry: + np =3D of_find_node_by_name(nnp, "GAISLER_GPTIMER"); + if (!np) { + np =3D of_find_node_by_name(nnp, "01_011"); + if (!np) + goto bad; + } + + ampopts =3D 0; + pp =3D of_find_property(np, "ampopts", &len); + if (pp) { + ampopts =3D *(int *)pp->value; + if (ampopts =3D=3D 0) { + /* Skip this instance, resource already + * allocated by other OS */ + nnp =3D np; + goto retry; } + } + + /* Select Timer-Instance on Timer Core. Default is zero */ + leon3_gptimer_idx =3D ampopts & 0x7; =20 - /* Select Timer-Instance on Timer Core. Default is zero */ - leon3_gptimer_idx =3D ampopts & 0x7; - - pp =3D of_find_property(np, "reg", &len); - if (pp) - leon3_gptimer_regs =3D *(struct leon3_gptimer_regs_map **) - pp->value; - pp =3D of_find_property(np, "interrupts", &len); - if (pp) - leon3_gptimer_irq =3D *(unsigned int *)pp->value; - } while (0); + pp =3D of_find_property(np, "reg", &len); + if (pp) + leon3_gptimer_regs =3D *(struct leon3_gptimer_regs_map **) + pp->value; + pp =3D of_find_property(np, "interrupts", &len); + if (pp) + leon3_gptimer_irq =3D *(unsigned int *)pp->value; =20 if (!(leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq)) goto bad; diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 0cbdebfa84df..83df01dca3ac 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1012,7 +1012,7 @@ static __init int setup_disablecpuid(char *arg) { int bit; =20 - if (get_option(&arg, &bit) && bit < NCAPINTS*32) + if (get_option(&arg, &bit) && bit >=3D 0 && bit < NCAPINTS * 32) setup_clear_cpu_cap(bit); else return 0; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4408aee8236d..d0284b49317b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -843,8 +843,7 @@ static u32 msrs_to_save[] =3D { #ifdef CONFIG_X86_64 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, #endif - MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA, - MSR_TSC_AUX, + MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA }; =20 static unsigned num_msrs_to_save; @@ -3882,20 +3881,6 @@ static void kvm_init_msr_list(void) for (i =3D j =3D KVM_SAVE_MSRS_BEGIN; i < ARRAY_SIZE(msrs_to_save); i++) { if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0) continue; - - /* - * Even MSRs that are valid in the host may not be exposed - * to the guests in some cases. - */ - switch (msrs_to_save[i]) { - case MSR_TSC_AUX: - if (!kvm_x86_ops->rdtscp_supported()) - continue; - break; - default: - break; - } - if (j < i) msrs_to_save[j] =3D msrs_to_save[i]; j++; diff --git a/crypto/algapi.c b/crypto/algapi.c index 5593afd85455..2f1954885ff9 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -354,6 +354,7 @@ int crypto_register_alg(struct crypto_alg *alg) struct crypto_larval *larval; int err; =20 + alg->cra_flags &=3D ~CRYPTO_ALG_DEAD; err =3D crypto_check_alg(alg); if (err) return err; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 0b8b8b488ee8..d5091f3a3233 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4059,6 +4059,9 @@ static int mv_platform_probe(struct platform_device *= pdev) host->iomap =3D NULL; hpriv->base =3D devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!hpriv->base) + return -ENOMEM; + hpriv->base -=3D SATAHC0_REG_BASE; =20 #if defined(CONFIG_HAVE_CLK) diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index 6f3676f1559f..98a8b763f18d 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -106,13 +106,13 @@ void dmam_free_coherent(struct device *dev, size_t si= ze, void *vaddr, EXPORT_SYMBOL(dmam_free_coherent); =20 /** - * dmam_alloc_non_coherent - Managed dma_alloc_non_coherent() + * dmam_alloc_non_coherent - Managed dma_alloc_noncoherent() * @dev: Device to allocate non_coherent memory for * @size: Size of allocation * @dma_handle: Out argument for allocated DMA handle * @gfp: Allocation flags * - * Managed dma_alloc_non_coherent(). Memory allocated using this + * Managed dma_alloc_noncoherent(). Memory allocated using this * function will be automatically released on driver detach. * * RETURNS: diff --git a/drivers/base/regmap/regcache-lzo.c b/drivers/base/regmap/regca= che-lzo.c index 066aeece3626..4a42f07820c8 100644 --- a/drivers/base/regmap/regcache-lzo.c +++ b/drivers/base/regmap/regcache-lzo.c @@ -229,15 +229,13 @@ static int regcache_lzo_read(struct regmap *map, { struct regcache_lzo_ctx *lzo_block, **lzo_blocks; int ret, blkindex, blkpos; - size_t blksize, tmp_dst_len; + size_t tmp_dst_len; void *tmp_dst; =20 /* index of the compressed lzo block */ blkindex =3D regcache_lzo_get_blkindex(map, reg); /* register index within the decompressed block */ blkpos =3D regcache_lzo_get_blkpos(map, reg); - /* size of the compressed block */ - blksize =3D regcache_lzo_get_blksize(map); lzo_blocks =3D map->cache; lzo_block =3D lzo_blocks[blkindex]; =20 @@ -269,15 +267,13 @@ static int regcache_lzo_write(struct regmap *map, { struct regcache_lzo_ctx *lzo_block, **lzo_blocks; int ret, blkindex, blkpos; - size_t blksize, tmp_dst_len; + size_t tmp_dst_len; void *tmp_dst; =20 /* index of the compressed lzo block */ blkindex =3D regcache_lzo_get_blkindex(map, reg); /* register index within the decompressed block */ blkpos =3D regcache_lzo_get_blkpos(map, reg); - /* size of the compressed block */ - blksize =3D regcache_lzo_get_blksize(map); lzo_blocks =3D map->cache; lzo_block =3D lzo_blocks[blkindex]; =20 diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 788581e782d4..2a80552633dd 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -232,9 +232,10 @@ static inline int sock_send_bvec(struct nbd_device *lo= , struct bio_vec *bvec, /* always call with the tx_lock held */ static int nbd_send_req(struct nbd_device *lo, struct request *req) { - int result, flags; + int result; struct nbd_request request; unsigned long size =3D blk_rq_bytes(req); + struct bio *bio; =20 request.magic =3D htonl(NBD_REQUEST_MAGIC); request.type =3D htonl(nbd_cmd(req)); @@ -255,17 +256,19 @@ static int nbd_send_req(struct nbd_device *lo, struct= request *req) goto error_out; } =20 - if (nbd_cmd(req) =3D=3D NBD_CMD_WRITE) { - struct req_iterator iter; + if (nbd_cmd(req) !=3D NBD_CMD_WRITE) + return 0; + + bio =3D req->bio; + while (bio) { + struct bio *next =3D bio->bi_next; + int i; struct bio_vec *bvec; - /* - * we are really probing at internals to determine - * whether to set MSG_MORE or not... - */ - rq_for_each_segment(bvec, req, iter) { - flags =3D 0; - if (!rq_iter_last(req, iter)) - flags =3D MSG_MORE; + + bio_for_each_segment(bvec, bio, i) { + bool is_last =3D !next && i =3D=3D bio->bi_vcnt - 1; + int flags =3D is_last ? 0 : MSG_MORE; + dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n", lo->disk->disk_name, req, bvec->bv_len); result =3D sock_send_bvec(lo, bvec, flags); @@ -275,7 +278,16 @@ static int nbd_send_req(struct nbd_device *lo, struct = request *req) result); goto error_out; } + /* + * The completion might already have come in, + * so break for the last one instead of letting + * the iterator do it. This prevents use-after-free + * of the bio. + */ + if (is_last) + break; } + bio =3D next; } return 0; =20 diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 4159265b453b..1c1b8be2fec2 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -419,7 +419,9 @@ static int aead_set_sh_desc(struct crypto_aead *aead) =20 /* Will read cryptlen */ append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); - aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2); + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF | + FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH); + append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF); =20 /* Write ICV */ append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB | diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c index 9e43aaca9774..d6cae2632cba 100644 --- a/drivers/hid/hid-cypress.c +++ b/drivers/hid/hid-cypress.c @@ -40,6 +40,9 @@ static __u8 *cp_report_fixup(struct hid_device *hdev, __u= 8 *rdesc, if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX)) return rdesc; =20 + if (*rsize < 4) + return rdesc; + for (i =3D 0; i < *rsize - 4; i++) if (rdesc[i] =3D=3D 0x29 && rdesc[i + 2] =3D=3D 0x19) { __u8 tmp; diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c index 225ae4f36583..06da77b65887 100644 --- a/drivers/hwmon/ds620.c +++ b/drivers/hwmon/ds620.c @@ -166,7 +166,7 @@ static ssize_t set_temp(struct device *dev, struct devi= ce_attribute *da, if (res) return res; =20 - val =3D (val * 10 / 625) * 8; + val =3D (clamp_val(val, -128000, 128000) * 10 / 625) * 8; =20 mutex_lock(&data->update_lock); data->temp[attr->index] =3D val; diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 57a45ce84b2d..fed49794d17d 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -310,7 +310,7 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_clien= t *client, unsigned long arg) { struct i2c_smbus_ioctl_data data_arg; - union i2c_smbus_data temp; + union i2c_smbus_data temp =3D {}; int datasize, res; =20 if (copy_from_user(&data_arg, diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 2fe428bba54c..78d406b3d8f4 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1598,7 +1598,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv, if (!class) goto out; if (convert_mgmt_class(mad->mad_hdr.mgmt_class) >=3D - IB_MGMT_MAX_METHODS) + ARRAY_SIZE(class->method_table)) goto out; method =3D class->method_table[convert_mgmt_class( mad->mad_hdr.mgmt_class)]; diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/= multicast.c index 180d7f436ed5..2f861b59cbc1 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c @@ -516,8 +516,11 @@ static void join_handler(int status, struct ib_sa_mcme= mber_rec *rec, if (status) process_join_error(group, status); else { - ib_find_pkey(group->port->dev->device, group->port->port_num, - be16_to_cpu(rec->pkey), &pkey_index); + + if (ib_find_pkey(group->port->dev->device, + group->port->port_num, be16_to_cpu(rec->pkey), + &pkey_index)) + pkey_index =3D MCAST_INVALID_PKEY_INDEX; =20 spin_lock_irq(&group->port->lock); group->rec =3D *rec; diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4= /main.c index 18836cdf1e10..c693e30e263d 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -164,6 +164,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, props->max_total_mcast_qp_attach =3D props->max_mcast_qp_attach * props->max_mcast_grp; props->max_map_per_fmr =3D (1 << (32 - ilog2(dev->dev->caps.num_mpts))) -= 1; + props->max_ah =3D INT_MAX; =20 out: kfree(in_mad); diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8= 042-x86ia64io.h index c86da501ca7d..90e182441c81 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -211,6 +211,12 @@ static const struct dmi_system_id __initconst i8042_dm= i_noloop_table[] =3D { DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"), }, }, + { + .matches =3D { + DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"), + DMI_MATCH(DMI_PRODUCT_NAME, "C15B"), + }, + }, { } }; =20 diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 43a84e32c893..a80369032bd8 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -641,7 +641,7 @@ again: next_tail =3D (tail + sizeof(*cmd)) % iommu->cmd_buf_size; left =3D (head - next_tail) % iommu->cmd_buf_size; =20 - if (left <=3D 2) { + if (left <=3D 0x20) { struct iommu_cmd sync_cmd; volatile u64 sem =3D 0; int ret; diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 4878d910e5a4..acdad2db8148 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1322,12 +1322,15 @@ static int crypt_set_key(struct crypt_config *cc, c= har *key) if (!cc->key_size && strcmp(key, "-")) goto out; =20 + /* clear the flag since following operations may invalidate previously va= lid key */ + clear_bit(DM_CRYPT_KEY_VALID, &cc->flags); + if (cc->key_size && crypt_decode_key(cc->key, key, cc->key_size) < 0) goto out; =20 - set_bit(DM_CRYPT_KEY_VALID, &cc->flags); - r =3D crypt_setkey_allcpus(cc); + if (!r) + set_bit(DM_CRYPT_KEY_VALID, &cc->flags); =20 out: /* Hex key string not needed after here, so wipe it. */ diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/sms= usb.c index 027550d645bc..379ce05cf7f2 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -181,11 +181,20 @@ static int smsusb_start_streaming(struct smsusb_devic= e_t *dev) static int smsusb_sendrequest(void *context, void *buffer, size_t size) { struct smsusb_device_t *dev =3D (struct smsusb_device_t *) context; - int dummy; + struct SmsMsgHdr_ST *phdr; + int dummy, ret; =20 - smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer); - return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), - buffer, size, &dummy, 1000); + phdr =3D kmalloc(size, GFP_KERNEL); + if (!phdr) + return -ENOMEM; + memcpy(phdr, buffer, size); + + smsendian_handle_message_header((struct SmsMsgHdr_ST *)phdr); + ret =3D usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), + phdr, size, &dummy, 1000); + + kfree(phdr); + return ret; } =20 static char *smsusb1_fw_lkup[] =3D { diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index c06992e1320d..3429b9abf11d 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -263,6 +263,8 @@ static void ite_set_carrier_params(struct ite_dev *dev) =20 if (allowance > ITE_RXDCR_MAX) allowance =3D ITE_RXDCR_MAX; + + use_demodulator =3D true; } } =20 diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/vid= eo/davinci/vpfe_capture.c index 5b38fc93ff28..06e80f0de048 100644 --- a/drivers/media/video/davinci/vpfe_capture.c +++ b/drivers/media/video/davinci/vpfe_capture.c @@ -2002,6 +2002,7 @@ static __init int vpfe_probe(struct platform_device *= pdev) v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 sub device %s register fails\n", sdinfo->name); + ret =3D -ENXIO; goto probe_sd_out; } } diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 0c781acf3df4..12b864e5d205 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -386,6 +386,9 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host) cmd0 =3D BF_SSP(cmd->opcode, CMD0_CMD); cmd1 =3D cmd->arg; =20 + if (cmd->opcode =3D=3D MMC_STOP_TRANSMISSION) + cmd0 |=3D BM_SSP_CMD0_APPEND_8CYC; + if (host->sdio_irq_en) { ctrl0 |=3D BM_SSP_CTRL0_SDIO_IRQ_CHECK; cmd0 |=3D BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN; @@ -487,8 +490,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) host->base + HW_SSP_BLOCK_SIZE); } =20 - if ((cmd->opcode =3D=3D MMC_STOP_TRANSMISSION) || - (cmd->opcode =3D=3D SD_IO_RW_EXTENDED)) + if (cmd->opcode =3D=3D SD_IO_RW_EXTENDED) cmd0 |=3D BM_SSP_CMD0_APPEND_8CYC; =20 cmd1 =3D cmd->arg; diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 1ef9df8de979..a5eeeb189764 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -942,7 +942,12 @@ static int ti_hecc_probe(struct platform_device *pdev) netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll, HECC_DEF_NAPI_WEIGHT); =20 - clk_enable(priv->clk); + err =3D clk_prepare_enable(priv->clk); + if (err) { + dev_err(&pdev->dev, "clk_prepare_enable() failed\n"); + goto probe_exit_clk; + } + err =3D register_candev(ndev); if (err) { dev_err(&pdev->dev, "register_candev() failed\n"); @@ -972,7 +977,7 @@ static int __devexit ti_hecc_remove(struct platform_dev= ice *pdev) struct ti_hecc_priv *priv =3D netdev_priv(ndev); =20 unregister_candev(ndev); - clk_disable(priv->clk); + clk_disable_unprepare(priv->clk); clk_put(priv->clk); res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); iounmap(priv->base); @@ -998,7 +1003,7 @@ static int ti_hecc_suspend(struct platform_device *pde= v, pm_message_t state) hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR); priv->can.state =3D CAN_STATE_SLEEPING; =20 - clk_disable(priv->clk); + clk_disable_unprepare(priv->clk); =20 return 0; } @@ -1007,8 +1012,11 @@ static int ti_hecc_resume(struct platform_device *pd= ev) { struct net_device *dev =3D platform_get_drvdata(pdev); struct ti_hecc_priv *priv =3D netdev_priv(dev); + int err; =20 - clk_enable(priv->clk); + err =3D clk_prepare_enable(priv->clk); + if (err) + return err; =20 hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR); priv->can.state =3D CAN_STATE_ERROR_ACTIVE; diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c index d8430f487b84..fcf65cc0865b 100644 --- a/drivers/net/ethernet/korina.c +++ b/drivers/net/ethernet/korina.c @@ -906,10 +906,10 @@ static void korina_restart_task(struct work_struct *w= ork) DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR, &lp->rx_dma_regs->dmasm); =20 - korina_free_ring(dev); - napi_disable(&lp->napi); =20 + korina_free_ring(dev); + if (korina_init(dev) < 0) { printk(KERN_ERR "%s: cannot restart device\n", dev->name); return; @@ -1070,12 +1070,12 @@ static int korina_close(struct net_device *dev) tmp =3D tmp | DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR; writel(tmp, &lp->rx_dma_regs->dmasm); =20 - korina_free_ring(dev); - napi_disable(&lp->napi); =20 cancel_work_sync(&lp->restart_task); =20 + korina_free_ring(dev); + free_irq(lp->rx_irq, dev); free_irq(lp->tx_irq, dev); free_irq(lp->ovr_irq, dev); diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/mar= vell/sky2.c index 94f9a8ff6fdb..8afe01b8471d 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -5165,6 +5165,19 @@ static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, = sky2_resume); =20 static void sky2_shutdown(struct pci_dev *pdev) { + struct sky2_hw *hw =3D pci_get_drvdata(pdev); + int port; + + for (port =3D 0; port < hw->ports; port++) { + struct net_device *ndev =3D hw->dev[port]; + + rtnl_lock(); + if (netif_running(ndev)) { + dev_close(ndev); + netif_device_detach(ndev); + } + rtnl_unlock(); + } sky2_suspend(&pdev->dev); pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev)); pci_set_power_state(pdev, PCI_D3hot); diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet= /mellanox/mlx4/cq.c index 499a5168892a..753d26b5fee3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/cq.c @@ -78,13 +78,19 @@ void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn) { struct mlx4_cq *cq; =20 + rcu_read_lock(); cq =3D radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree, cqn & (dev->caps.num_cqs - 1)); + rcu_read_unlock(); + if (!cq) { mlx4_warn(dev, "Completion event for bogus CQ %08x\n", cqn); return; } =20 + /* Acessing the CQ outside of rcu_read_lock is safe, because + * the CQ is freed only after interrupt handling is completed. + */ ++cq->arm_sn; =20 cq->comp(cq); @@ -95,23 +101,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int = event_type) struct mlx4_cq_table *cq_table =3D &mlx4_priv(dev)->cq_table; struct mlx4_cq *cq; =20 - spin_lock(&cq_table->lock); - + rcu_read_lock(); cq =3D radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1)); - if (cq) - atomic_inc(&cq->refcount); - - spin_unlock(&cq_table->lock); + rcu_read_unlock(); =20 if (!cq) { - mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn); + mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn); return; } =20 + /* Acessing the CQ outside of rcu_read_lock is safe, because + * the CQ is freed only after interrupt handling is completed. + */ cq->event(cq, event_type); - - if (atomic_dec_and_test(&cq->refcount)) - complete(&cq->free); } =20 static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *ma= ilbox, @@ -216,9 +218,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struc= t mlx4_mtt *mtt, if (err) goto err_put; =20 - spin_lock_irq(&cq_table->lock); + spin_lock(&cq_table->lock); err =3D radix_tree_insert(&cq_table->tree, cq->cqn, cq); - spin_unlock_irq(&cq_table->lock); + spin_unlock(&cq_table->lock); if (err) goto err_cmpt_put; =20 @@ -255,9 +257,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struc= t mlx4_mtt *mtt, return 0; =20 err_radix: - spin_lock_irq(&cq_table->lock); + spin_lock(&cq_table->lock); radix_tree_delete(&cq_table->tree, cq->cqn); - spin_unlock_irq(&cq_table->lock); + spin_unlock(&cq_table->lock); =20 err_cmpt_put: mlx4_table_put(dev, &cq_table->cmpt_table, cq->cqn); @@ -282,11 +284,11 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_c= q *cq) if (err) mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn); =20 - synchronize_irq(priv->eq_table.eq[cq->vector].irq); - - spin_lock_irq(&cq_table->lock); + spin_lock(&cq_table->lock); radix_tree_delete(&cq_table->tree, cq->cqn); - spin_unlock_irq(&cq_table->lock); + spin_unlock(&cq_table->lock); + + synchronize_irq(priv->eq_table.eq[cq->vector].irq); =20 if (atomic_dec_and_test(&cq->refcount)) complete(&cq->free); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ether= net/mellanox/mlx4/en_rx.c index c2df6c358603..1e7cf80fa8eb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -328,8 +328,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *pri= v) ring->cqn =3D priv->rx_cq[ring_ind].mcq.cqn; =20 ring->stride =3D stride; - if (ring->stride <=3D TXBB_SIZE) + if (ring->stride <=3D TXBB_SIZE) { + /* Stamp first unused send wqe */ + __be32 *ptr =3D (__be32 *)ring->buf; + __be32 stamp =3D cpu_to_be32(1 << STAMP_SHIFT); + *ptr =3D stamp; + /* Move pointer to start of rx section */ ring->buf +=3D TXBB_SIZE; + } =20 ring->log_stride =3D ffs(ring->stride) - 1; ring->buf_size =3D ring->size * ring->stride; diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/etherne= t/mellanox/mlx4/icm.c index 02393fdf44c1..510f8eca1c24 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.c +++ b/drivers/net/ethernet/mellanox/mlx4/icm.c @@ -113,8 +113,13 @@ static int mlx4_alloc_icm_coherent(struct device *dev,= struct scatterlist *mem, if (!buf) return -ENOMEM; =20 + if (offset_in_page(buf)) { + dma_free_coherent(dev, PAGE_SIZE << order, + buf, sg_dma_address(mem)); + return -ENOMEM; + } + sg_set_buf(mem, buf, PAGE_SIZE << order); - BUG_ON(mem->offset); sg_dma_len(mem) =3D PAGE_SIZE << order; return 0; } diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/et= hernet/xilinx/xilinx_emaclite.c index 8018d7d045b0..f470a5c86aeb 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -398,7 +398,7 @@ static int xemaclite_send_data(struct net_local *drvdat= a, u8 *data, * * Return: Total number of bytes received */ -static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) +static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data, int ma= xlen) { void __iomem *addr; u16 length, proto_type; @@ -438,7 +438,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdat= a, u8 *data) =20 /* Check if received ethernet frame is a raw ethernet frame * or an IP packet or an ARP packet */ - if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) { + if (proto_type > ETH_DATA_LEN) { =20 if (proto_type =3D=3D ETH_P_IP) { length =3D ((ntohl(in_be32(addr + @@ -446,6 +446,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdat= a, u8 *data) XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) & XEL_RPLR_LENGTH_MASK); + length =3D min_t(u16, length, ETH_DATA_LEN); length +=3D ETH_HLEN + ETH_FCS_LEN; =20 } else if (proto_type =3D=3D ETH_P_ARP) @@ -458,6 +459,9 @@ static u16 xemaclite_recv_data(struct net_local *drvdat= a, u8 *data) /* Use the length in the frame, plus the header and trailer */ length =3D proto_type + ETH_HLEN + ETH_FCS_LEN; =20 + if (WARN_ON(length > maxlen)) + length =3D maxlen; + /* Read from the EmacLite device */ xemaclite_aligned_read((u32 __force *) (addr + XEL_RXBUFF_OFFSET), data, length); @@ -632,7 +636,7 @@ static void xemaclite_rx_handler(struct net_device *dev) =20 skb_reserve(skb, 2); =20 - len =3D xemaclite_recv_data(lp, (u8 *) skb->data); + len =3D xemaclite_recv_data(lp, (u8 *) skb->data, len); =20 if (!len) { dev->stats.rx_errors++; diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 2fcdedefce42..1c3db94e4237 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -687,7 +687,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q= , struct msghdr *m, size_t linear; =20 if (q->flags & IFF_VNET_HDR) { - vnet_hdr_len =3D q->vnet_hdr_sz; + vnet_hdr_len =3D ACCESS_ONCE(q->vnet_hdr_sz); =20 err =3D -EINVAL; if (len < vnet_hdr_len) @@ -817,7 +817,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, =20 if (q->flags & IFF_VNET_HDR) { struct virtio_net_hdr vnet_hdr; - vnet_hdr_len =3D q->vnet_hdr_sz; + vnet_hdr_len =3D ACCESS_ONCE(q->vnet_hdr_sz); if ((len -=3D vnet_hdr_len) < 0) return -EINVAL; =20 diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 2fbbca670457..9c2e91c5a6bc 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -625,9 +625,11 @@ static ssize_t tun_get_user(struct tun_struct *tun, } =20 if (tun->flags & TUN_VNET_HDR) { - if (len < tun->vnet_hdr_sz) + int vnet_hdr_sz =3D ACCESS_ONCE(tun->vnet_hdr_sz); + + if (len < vnet_hdr_sz) return -EINVAL; - len -=3D tun->vnet_hdr_sz; + len -=3D vnet_hdr_sz; =20 if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) return -EFAULT; @@ -638,7 +640,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, =20 if (gso.hdr_len > len) return -EINVAL; - offset +=3D tun->vnet_hdr_sz; + offset +=3D vnet_hdr_sz; } =20 if ((tun->flags & TUN_TYPE_MASK) =3D=3D TUN_TAP_DEV) { @@ -767,12 +769,16 @@ static ssize_t tun_put_user(struct tun_struct *tun, { struct tun_pi pi =3D { 0, skb->protocol }; ssize_t total =3D 0; + int vnet_hdr_sz =3D 0; + + if (tun->flags & TUN_VNET_HDR) + vnet_hdr_sz =3D ACCESS_ONCE(tun->vnet_hdr_sz); =20 if (!(tun->flags & TUN_NO_PI)) { if ((len -=3D sizeof(pi)) < 0) return -EINVAL; =20 - if (len < skb->len) { + if (len < skb->len + vnet_hdr_sz) { /* Packet will be striped */ pi.flags |=3D TUN_PKT_STRIP; } @@ -782,9 +788,9 @@ static ssize_t tun_put_user(struct tun_struct *tun, total +=3D sizeof(pi); } =20 - if (tun->flags & TUN_VNET_HDR) { + if (vnet_hdr_sz) { struct virtio_net_hdr gso =3D { 0 }; /* no info leak */ - if ((len -=3D tun->vnet_hdr_sz) < 0) + if ((len -=3D vnet_hdr_sz) < 0) return -EINVAL; =20 if (skb_is_gso(skb)) { @@ -827,7 +833,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, sizeof(gso)))) return -EFAULT; - total +=3D tun->vnet_hdr_sz; + total +=3D vnet_hdr_sz; } =20 len =3D min_t(int, skb->len, len); diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index a68272c93381..0fbe66c98e70 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -765,7 +765,7 @@ static int catc_probe(struct usb_interface *intf, const= struct usb_device_id *id struct net_device *netdev; struct catc *catc; u8 broadcast[6]; - int i, pktsz; + int pktsz, ret; =20 if (usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 1)) { @@ -800,12 +800,8 @@ static int catc_probe(struct usb_interface *intf, cons= t struct usb_device_id *id if ((!catc->ctrl_urb) || (!catc->tx_urb) ||=20 (!catc->rx_urb) || (!catc->irq_urb)) { err("No free urbs available."); - usb_free_urb(catc->ctrl_urb); - usb_free_urb(catc->tx_urb); - usb_free_urb(catc->rx_urb); - usb_free_urb(catc->irq_urb); - free_netdev(netdev); - return -ENOMEM; + ret =3D -ENOMEM; + goto fail_free; } =20 /* The F5U011 has the same vendor/product as the netmate but a device ver= sion of 0x130 */ @@ -833,15 +829,24 @@ static int catc_probe(struct usb_interface *intf, con= st struct usb_device_id *id catc->irq_buf, 2, catc_irq_done, catc, 1); =20 if (!catc->is_f5u011) { + u32 *buf; + int i; + dbg("Checking memory size\n"); =20 - i =3D 0x12345678; - catc_write_mem(catc, 0x7a80, &i, 4); - i =3D 0x87654321;=09 - catc_write_mem(catc, 0xfa80, &i, 4); - catc_read_mem(catc, 0x7a80, &i, 4); + buf =3D kmalloc(4, GFP_KERNEL); + if (!buf) { + ret =3D -ENOMEM; + goto fail_free; + } + + *buf =3D 0x12345678; + catc_write_mem(catc, 0x7a80, buf, 4); + *buf =3D 0x87654321; + catc_write_mem(catc, 0xfa80, buf, 4); + catc_read_mem(catc, 0x7a80, buf, 4); =20 - switch (i) { + switch (*buf) { case 0x12345678: catc_set_reg(catc, TxBufCount, 8); catc_set_reg(catc, RxBufCount, 32); @@ -856,6 +861,8 @@ static int catc_probe(struct usb_interface *intf, const= struct usb_device_id *id dbg("32k Memory\n"); break; } + + kfree(buf); =20 dbg("Getting MAC from SEEROM."); =20 @@ -902,16 +909,21 @@ static int catc_probe(struct usb_interface *intf, con= st struct usb_device_id *id usb_set_intfdata(intf, catc); =20 SET_NETDEV_DEV(netdev, &intf->dev); - if (register_netdev(netdev) !=3D 0) { - usb_set_intfdata(intf, NULL); - usb_free_urb(catc->ctrl_urb); - usb_free_urb(catc->tx_urb); - usb_free_urb(catc->rx_urb); - usb_free_urb(catc->irq_urb); - free_netdev(netdev); - return -EIO; - } + ret =3D register_netdev(netdev); + if (ret) + goto fail_clear_intfdata; + return 0; + +fail_clear_intfdata: + usb_set_intfdata(intf, NULL); +fail_free: + usb_free_urb(catc->ctrl_urb); + usb_free_urb(catc->tx_urb); + usb_free_urb(catc->rx_urb); + usb_free_urb(catc->irq_urb); + free_netdev(netdev); + return ret; } =20 static void catc_disconnect(struct usb_interface *intf) diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index bf8c84d0adf2..54537d0c0424 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -178,16 +178,36 @@ static const char driver_name [] =3D "rtl8150"; */ static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) { - return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), - RTL8150_REQ_GET_REGS, RTL8150_REQT_READ, - indx, 0, data, size, 500); + void *buf; + int ret; + + buf =3D kmalloc(size, GFP_NOIO); + if (!buf) + return -ENOMEM; + + ret =3D usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), + RTL8150_REQ_GET_REGS, RTL8150_REQT_READ, + indx, 0, buf, size, 500); + if (ret > 0 && ret <=3D size) + memcpy(data, buf, ret); + kfree(buf); + return ret; } =20 -static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) +static int set_registers(rtl8150_t * dev, u16 indx, u16 size, const void *= data) { - return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), - RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE, - indx, 0, data, size, 500); + void *buf; + int ret; + + buf =3D kmemdup(data, size, GFP_NOIO); + if (!buf) + return -ENOMEM; + + ret =3D usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), + RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE, + indx, 0, buf, size, 500); + kfree(buf); + return ret; } =20 static void ctrl_callback(struct urb *urb) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index c64a60e5adc5..47a404695480 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1404,6 +1404,8 @@ static void xennet_disconnect_backend(struct netfront= _info *info) spin_unlock_irq(&info->tx_lock); spin_unlock_bh(&info->rx_lock); =20 + del_timer_sync(&info->rx_refill_timer); + if (info->netdev->irq) unbind_from_irqhandler(info->netdev->irq, info->netdev); info->evtchn =3D info->netdev->irq =3D 0; @@ -1940,8 +1942,6 @@ static int __devexit xennet_remove(struct xenbus_devi= ce *dev) =20 unregister_netdev(info->netdev); =20 - del_timer_sync(&info->rx_refill_timer); - free_percpu(info->stats); =20 free_netdev(info->netdev); diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpad= lpar_core.c index c56a9413e1af..9de3f7cf535e 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -259,8 +259,13 @@ static int dlpar_add_phb(char *drc_name, struct device= _node *dn) =20 static int dlpar_add_vio_slot(char *drc_name, struct device_node *dn) { - if (vio_find_node(dn)) + struct vio_dev *vio_dev; + + vio_dev =3D vio_find_node(dn); + if (vio_dev) { + put_device(&vio_dev->dev); return -EINVAL; + } =20 if (!vio_register_device_node(dn)) { printk(KERN_ERR @@ -336,6 +341,9 @@ static int dlpar_remove_vio_slot(char *drc_name, struct= device_node *dn) return -EINVAL; =20 vio_unregister_device(vio_dev); + + put_device(&vio_dev->dev); + return 0; } =20 diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 4c3a9e9bf289..6b72e4a0b1b8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1763,6 +1763,10 @@ bool pci_dev_run_wake(struct pci_dev *dev) if (!dev->pme_support) return false; =20 + /* PME-capable in principle, but not from the intended sleep state */ + if (!pci_pme_capable(dev, pci_target_state(dev))) + return false; + while (bus->parent) { struct pci_dev *bridge =3D bus->self; =20 diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x= 86/intel_mid_powerbtn.c index f1ae5078b7ec..8c9670229719 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c @@ -72,7 +72,7 @@ static int __devinit mfld_pb_probe(struct platform_device= *pdev) =20 input_set_capability(input, EV_KEY, KEY_POWER); =20 - error =3D request_threaded_irq(irq, NULL, mfld_pb_isr, 0, + error =3D request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_ONESHOT, DRIVER_NAME, input); if (error) { dev_err(&pdev->dev, "Unable to request irq %d for mfld power" diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 524d988d89dd..8d2a3c71a007 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -876,7 +876,7 @@ static int __init vmlogrdr_init(void) goto cleanup; =20 for (i=3D0; i < MAXMINOR; ++i ) { - sys_ser[i].buffer =3D (char *) get_zeroed_page(GFP_KERNEL); + sys_ser[i].buffer =3D (char *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!sys_ser[i].buffer) { rc =3D -ENOMEM; break; diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index c846a63ea672..bf13e73ecabc 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -282,11 +282,12 @@ void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter= *adapter, =20 =20 /** - * zfcp_dbf_rec_run - trace event related to running recovery + * zfcp_dbf_rec_run_lvl - trace event related to running recovery + * @level: trace level to be used for event * @tag: identifier for event * @erp: erp_action running */ -void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp) +void zfcp_dbf_rec_run_lvl(int level, char *tag, struct zfcp_erp_action *er= p) { struct zfcp_dbf *dbf =3D erp->adapter->dbf; struct zfcp_dbf_rec *rec =3D &dbf->rec_buf; @@ -312,11 +313,21 @@ void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_acti= on *erp) else rec->u.run.rec_count =3D atomic_read(&erp->adapter->erp_counter); =20 - debug_event(dbf->rec, 1, rec, sizeof(*rec)); + debug_event(dbf->rec, level, rec, sizeof(*rec)); spin_unlock_irqrestore(&dbf->rec_lock, flags); } =20 /** + * zfcp_dbf_rec_run - trace event related to running recovery + * @tag: identifier for event + * @erp: erp_action running + */ +void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp) +{ + zfcp_dbf_rec_run_lvl(1, tag, erp); +} + +/** * zfcp_dbf_rec_run_wka - trace wka port event with info like running reco= very * @tag: identifier for event * @wka_port: well known address port diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index 440aa619da1d..a8165f142550 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h @@ -2,7 +2,7 @@ * zfcp device driver * debug feature declarations * - * Copyright IBM Corp. 2008, 2015 + * Copyright IBM Corp. 2008, 2016 */ =20 #ifndef ZFCP_DBF_H @@ -283,6 +283,30 @@ struct zfcp_dbf { struct zfcp_dbf_scsi scsi_buf; }; =20 +/** + * zfcp_dbf_hba_fsf_resp_suppress - true if we should not trace by default + * @req: request that has been completed + * + * Returns true if FCP response with only benign residual under count. + */ +static inline +bool zfcp_dbf_hba_fsf_resp_suppress(struct zfcp_fsf_req *req) +{ + struct fsf_qtcb *qtcb =3D req->qtcb; + u32 fsf_stat =3D qtcb->header.fsf_status; + struct fcp_resp *fcp_rsp; + u8 rsp_flags, fr_status; + + if (qtcb->prefix.qtcb_type !=3D FSF_IO_COMMAND) + return false; /* not an FCP response */ + fcp_rsp =3D (struct fcp_resp *)&qtcb->bottom.io.fcp_rsp; + rsp_flags =3D fcp_rsp->fr_flags; + fr_status =3D fcp_rsp->fr_status; + return (fsf_stat =3D=3D FSF_FCP_RSP_AVAILABLE) && + (rsp_flags =3D=3D FCP_RESID_UNDER) && + (fr_status =3D=3D SAM_STAT_GOOD); +} + static inline void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req) { @@ -304,7 +328,9 @@ void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req) zfcp_dbf_hba_fsf_resp("fs_perr", 1, req); =20 } else if (qtcb->header.fsf_status !=3D FSF_GOOD) { - zfcp_dbf_hba_fsf_resp("fs_ferr", 1, req); + zfcp_dbf_hba_fsf_resp("fs_ferr", + zfcp_dbf_hba_fsf_resp_suppress(req) + ? 5 : 1, req); =20 } else if ((req->fsf_command =3D=3D FSF_QTCB_OPEN_PORT_WITH_DID) || (req->fsf_command =3D=3D FSF_QTCB_OPEN_LUN)) { @@ -388,4 +414,15 @@ void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmn= d *scmnd, u8 flag) _zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL); } =20 +/** + * zfcp_dbf_scsi_nullcmnd() - trace NULLify of SCSI command in dev/tgt-res= et. + * @scmnd: SCSI command that was NULLified. + * @fsf_req: request that owned @scmnd. + */ +static inline void zfcp_dbf_scsi_nullcmnd(struct scsi_cmnd *scmnd, + struct zfcp_fsf_req *fsf_req) +{ + _zfcp_dbf_scsi("scfc__1", 3, scmnd, fsf_req); +} + #endif /* ZFCP_DBF_H */ diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 723cbe3985f0..126fa412a059 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -3,7 +3,7 @@ * * Error Recovery Procedures (ERP). * - * Copyright IBM Corp. 2002, 2015 + * Copyright IBM Corp. 2002, 2016 */ =20 #define KMSG_COMPONENT "zfcp" @@ -1212,6 +1212,62 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_= action *erp_action) } } =20 +/** + * zfcp_erp_try_rport_unblock - unblock rport if no more/new recovery + * @port: zfcp_port whose fc_rport we should try to unblock + */ +static void zfcp_erp_try_rport_unblock(struct zfcp_port *port) +{ + unsigned long flags; + struct zfcp_adapter *adapter =3D port->adapter; + int port_status; + struct Scsi_Host *shost =3D adapter->scsi_host; + struct scsi_device *sdev; + + write_lock_irqsave(&adapter->erp_lock, flags); + port_status =3D atomic_read(&port->status); + if ((port_status & ZFCP_STATUS_COMMON_UNBLOCKED) =3D=3D 0 || + (port_status & (ZFCP_STATUS_COMMON_ERP_INUSE | + ZFCP_STATUS_COMMON_ERP_FAILED)) !=3D 0) { + /* new ERP of severity >=3D port triggered elsewhere meanwhile or + * local link down (adapter erp_failed but not clear unblock) + */ + zfcp_dbf_rec_run_lvl(4, "ertru_p", &port->erp_action); + write_unlock_irqrestore(&adapter->erp_lock, flags); + return; + } + spin_lock(shost->host_lock); + __shost_for_each_device(sdev, shost) { + struct zfcp_scsi_dev *zsdev =3D sdev_to_zfcp(sdev); + int lun_status; + + if (zsdev->port !=3D port) + continue; + /* LUN under port of interest */ + lun_status =3D atomic_read(&zsdev->status); + if ((lun_status & ZFCP_STATUS_COMMON_ERP_FAILED) !=3D 0) + continue; /* unblock rport despite failed LUNs */ + /* LUN recovery not given up yet [maybe follow-up pending] */ + if ((lun_status & ZFCP_STATUS_COMMON_UNBLOCKED) =3D=3D 0 || + (lun_status & ZFCP_STATUS_COMMON_ERP_INUSE) !=3D 0) { + /* LUN blocked: + * not yet unblocked [LUN recovery pending] + * or meanwhile blocked [new LUN recovery triggered] + */ + zfcp_dbf_rec_run_lvl(4, "ertru_l", &zsdev->erp_action); + spin_unlock(shost->host_lock); + write_unlock_irqrestore(&adapter->erp_lock, flags); + return; + } + } + /* now port has no child or all children have completed recovery, + * and no ERP of severity >=3D port was meanwhile triggered elsewhere + */ + zfcp_scsi_schedule_rport_register(port); + spin_unlock(shost->host_lock); + write_unlock_irqrestore(&adapter->erp_lock, flags); +} + static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int resul= t) { struct zfcp_adapter *adapter =3D act->adapter; @@ -1222,6 +1278,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_a= ction *act, int result) case ZFCP_ERP_ACTION_REOPEN_LUN: if (!(act->status & ZFCP_STATUS_ERP_NO_REF)) scsi_device_put(sdev); + zfcp_erp_try_rport_unblock(port); break; =20 case ZFCP_ERP_ACTION_REOPEN_PORT: @@ -1232,7 +1289,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_a= ction *act, int result) */ if (act->step !=3D ZFCP_ERP_STEP_UNINITIALIZED) if (result =3D=3D ZFCP_ERP_SUCCEEDED) - zfcp_scsi_schedule_rport_register(port); + zfcp_erp_try_rport_unblock(port); /* fall through */ case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: put_device(&port->dev); diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index b51500accce2..b0e16aed43ac 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -3,7 +3,7 @@ * * External function declarations. * - * Copyright IBM Corp. 2002, 2015 + * Copyright IBM Corp. 2002, 2016 */ =20 #ifndef ZFCP_EXT_H @@ -49,6 +49,8 @@ extern void zfcp_dbf_adapter_unregister(struct zfcp_adapt= er *); extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *, struct zfcp_port *, struct scsi_device *, u8, u8); extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *); +extern void zfcp_dbf_rec_run_lvl(int level, char *tag, + struct zfcp_erp_action *erp); extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64); extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 0cbaebb52402..98bb859cb699 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -1577,7 +1577,7 @@ out: int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) { struct zfcp_qdio *qdio =3D wka_port->adapter->qdio; - struct zfcp_fsf_req *req =3D NULL; + struct zfcp_fsf_req *req; int retval =3D -EIO; =20 spin_lock_irq(&qdio->req_q_lock); @@ -1606,7 +1606,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *w= ka_port) zfcp_fsf_req_free(req); out: spin_unlock_irq(&qdio->req_q_lock); - if (req && !IS_ERR(req)) + if (!retval) zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id); return retval; } @@ -1632,7 +1632,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zf= cp_fsf_req *req) int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) { struct zfcp_qdio *qdio =3D wka_port->adapter->qdio; - struct zfcp_fsf_req *req =3D NULL; + struct zfcp_fsf_req *req; int retval =3D -EIO; =20 spin_lock_irq(&qdio->req_q_lock); @@ -1661,7 +1661,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *= wka_port) zfcp_fsf_req_free(req); out: spin_unlock_irq(&qdio->req_q_lock); - if (req && !IS_ERR(req)) + if (!retval) zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id); return retval; } diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index 8cad41ffb6b8..358b92ece8d0 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h @@ -3,7 +3,7 @@ * * Interface to the FSF support functions. * - * Copyright IBM Corp. 2002, 2015 + * Copyright IBM Corp. 2002, 2016 */ =20 #ifndef FSF_H @@ -86,6 +86,7 @@ #define FSF_APP_TAG_CHECK_FAILURE 0x00000082 #define FSF_REF_TAG_CHECK_FAILURE 0x00000083 #define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD +#define FSF_FCP_RSP_AVAILABLE 0x000000AF #define FSF_UNKNOWN_COMMAND 0x000000E2 #define FSF_UNKNOWN_OP_SUBTYPE 0x000000E3 #define FSF_INVALID_COMMAND_OPTION 0x000000E5 diff --git a/drivers/s390/scsi/zfcp_reqlist.h b/drivers/s390/scsi/zfcp_reql= ist.h index a72d1b730aba..703fce59befe 100644 --- a/drivers/s390/scsi/zfcp_reqlist.h +++ b/drivers/s390/scsi/zfcp_reqlist.h @@ -4,7 +4,7 @@ * Data structure and helper functions for tracking pending FSF * requests. * - * Copyright IBM Corporation 2009 + * Copyright IBM Corp. 2009, 2016 */ =20 #ifndef ZFCP_REQLIST_H @@ -180,4 +180,32 @@ static inline void zfcp_reqlist_move(struct zfcp_reqli= st *rl, spin_unlock_irqrestore(&rl->lock, flags); } =20 +/** + * zfcp_reqlist_apply_for_all() - apply a function to every request. + * @rl: the requestlist that contains the target requests. + * @f: the function to apply to each request; the first parameter of the + * function will be the target-request; the second parameter is the sa= me + * pointer as given with the argument @data. + * @data: freely chosen argument; passed through to @f as second parameter. + * + * Uses :c:macro:`list_for_each_entry` to iterate over the lists in the ha= sh- + * table (not a 'safe' variant, so don't modify the list). + * + * Holds @rl->lock over the entire request-iteration. + */ +static inline void +zfcp_reqlist_apply_for_all(struct zfcp_reqlist *rl, + void (*f)(struct zfcp_fsf_req *, void *), void *data) +{ + struct zfcp_fsf_req *req; + unsigned long flags; + unsigned int i; + + spin_lock_irqsave(&rl->lock, flags); + for (i =3D 0; i < ZFCP_REQ_LIST_BUCKETS; i++) + list_for_each_entry(req, &rl->buckets[i], list) + f(req, data); + spin_unlock_irqrestore(&rl->lock, flags); +} + #endif /* ZFCP_REQLIST_H */ diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 38ee0df633a3..66c37e77ac7c 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -3,7 +3,7 @@ * * Interface to Linux SCSI midlayer. * - * Copyright IBM Corp. 2002, 2015 + * Copyright IBM Corp. 2002, 2016 */ =20 #define KMSG_COMPONENT "zfcp" @@ -109,9 +109,7 @@ int zfcp_scsi_queuecommand(struct Scsi_Host *shost, str= uct scsi_cmnd *scpnt) } =20 if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) { - /* This could be either - * open LUN pending: this is temporary, will result in - * open LUN or ERP_FAILED, so retry command + /* This could be * call to rport_delete pending: mimic retry from * fc_remote_port_chkready until rport is BLOCKED */ @@ -230,6 +228,57 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd= *scpnt) return retval; } =20 +struct zfcp_scsi_req_filter { + u8 tmf_scope; + u32 lun_handle; + u32 port_handle; +}; + +static void zfcp_scsi_forget_cmnd(struct zfcp_fsf_req *old_req, void *data) +{ + struct zfcp_scsi_req_filter *filter =3D + (struct zfcp_scsi_req_filter *)data; + + /* already aborted - prevent side-effects - or not a SCSI command */ + if (old_req->data =3D=3D NULL || old_req->fsf_command !=3D FSF_QTCB_FCP_C= MND) + return; + + /* (tmf_scope =3D=3D FCP_TMF_TGT_RESET || tmf_scope =3D=3D FCP_TMF_LUN_RE= SET) */ + if (old_req->qtcb->header.port_handle !=3D filter->port_handle) + return; + + if (filter->tmf_scope =3D=3D FCP_TMF_LUN_RESET && + old_req->qtcb->header.lun_handle !=3D filter->lun_handle) + return; + + zfcp_dbf_scsi_nullcmnd((struct scsi_cmnd *)old_req->data, old_req); + old_req->data =3D NULL; +} + +static void zfcp_scsi_forget_cmnds(struct zfcp_scsi_dev *zsdev, u8 tm_flag= s) +{ + struct zfcp_adapter *adapter =3D zsdev->port->adapter; + struct zfcp_scsi_req_filter filter =3D { + .tmf_scope =3D FCP_TMF_TGT_RESET, + .port_handle =3D zsdev->port->handle, + }; + unsigned long flags; + + if (tm_flags =3D=3D FCP_TMF_LUN_RESET) { + filter.tmf_scope =3D FCP_TMF_LUN_RESET; + filter.lun_handle =3D zsdev->lun_handle; + } + + /* + * abort_lock secures against other processings - in the abort-function + * and normal cmnd-handler - of (struct zfcp_fsf_req *)->data + */ + write_lock_irqsave(&adapter->abort_lock, flags); + zfcp_reqlist_apply_for_all(adapter->req_list, zfcp_scsi_forget_cmnd, + &filter); + write_unlock_irqrestore(&adapter->abort_lock, flags); +} + static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) { struct zfcp_scsi_dev *zfcp_sdev =3D sdev_to_zfcp(scpnt->device); @@ -262,8 +311,10 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *s= cpnt, u8 tm_flags) if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags); retval =3D FAILED; - } else + } else { zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags); + zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags); + } =20 zfcp_fsf_req_free(fsf_req); return retval; diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index 7e423e5ad5e1..16349aa76956 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c @@ -622,7 +622,7 @@ static void mvs_94xx_command_active(struct mvs_info *mv= i, u32 slot_idx) { u32 tmp; tmp =3D mvs_cr32(mvi, MVS_COMMAND_ACTIVE+(slot_idx >> 3)); - if (tmp && 1 << (slot_idx % 32)) { + if (tmp & 1 << (slot_idx % 32)) { mv_printk("command active %08X, slot [%x].\n", tmp, slot_idx); mvs_cw32(mvi, MVS_COMMAND_ACTIVE + (slot_idx >> 3), 1 << (slot_idx % 32)); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index d76c347bd473..195dd3c9a6a9 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -864,10 +864,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) struct request_queue *rq =3D sdev->request_queue; struct scsi_target *starget =3D sdev->sdev_target; =20 - error =3D scsi_device_set_state(sdev, SDEV_RUNNING); - if (error) - return error; - error =3D scsi_target_add(starget); if (error) return error; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index fb59a49dd01d..43862f25c754 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1710,6 +1710,10 @@ static int sg_start_req(Sg_request *srp, unsigned ch= ar *cmd) iov_count =3D iov_shorten(iov, iov_count, hp->dxfer_len); len =3D hp->dxfer_len; } + if (len =3D=3D 0) { + kfree(iov); + return -EINVAL; + } =20 res =3D blk_rq_map_user_iov(q, rq, md, (struct sg_iovec *)iov, iov_count, diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 34c3bab90b9a..8d4ddd1cdbb8 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -713,6 +713,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, ssb_printk(KERN_WARNING PFX "WARNING: Using" " fallback SPROM failed (err %d)\n", err); + goto out_free; } else { ssb_dprintk(KERN_DEBUG PFX "Using SPROM" " revision %d provided by" diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_= drv.c index 986a04d16ba8..da097b228981 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -1185,6 +1185,9 @@ static struct drm_driver driver =3D { .open =3D drm_open, .release =3D drm_release, .unlocked_ioctl =3D psb_unlocked_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl =3D drm_compat_ioctl, +#endif .mmap =3D drm_gem_mmap, .poll =3D drm_poll, .fasync =3D drm_fasync, diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_dr= v.c index 93b0e91cbf98..c993dfd8671b 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -52,6 +52,9 @@ struct net_device_context { /* Need this many pages to handle worst case fragmented packet */ #define PACKET_PAGES_HIWATER (MAX_SKB_FRAGS + 2) =20 +/* Restrict GSO size to account for NVGRE */ +#define NETVSC_GSO_MAX_SIZE 62768 + static int ring_size =3D 128; module_param(ring_size, int, S_IRUGO); MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); @@ -363,6 +366,7 @@ static int netvsc_probe(struct hv_device *dev, =20 SET_ETHTOOL_OPS(net, ðtool_ops); SET_NETDEV_DEV(net, &dev->device); + netif_set_gso_max_size(net, NETVSC_GSO_MAX_SIZE); =20 ret =3D register_netdev(net); if (ret !=3D 0) { diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/ad= c/ad7606_core.c index 2ee187fd268e..19af66104032 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -185,7 +185,7 @@ static ssize_t ad7606_store_oversampling_ratio(struct d= evice *dev, mutex_lock(&indio_dev->mlock); gpio_set_value(st->pdata->gpio_os0, (ret >> 0) & 1); gpio_set_value(st->pdata->gpio_os1, (ret >> 1) & 1); - gpio_set_value(st->pdata->gpio_os1, (ret >> 2) & 1); + gpio_set_value(st->pdata->gpio_os2, (ret >> 2) & 1); st->oversampling =3D lval; mutex_unlock(&indio_dev->mlock); =20 diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/v= me/bridges/vme_ca91cx42.c index 0e4feac138eb..ee2e2fd1106d 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -466,7 +466,7 @@ static int ca91cx42_slave_get(struct vme_slave_resource= *image, int *enabled, vme_bound =3D ioread32(bridge->base + CA91CX42_VSI_BD[i]); pci_offset =3D ioread32(bridge->base + CA91CX42_VSI_TO[i]); =20 - *pci_base =3D (dma_addr_t)vme_base + pci_offset; + *pci_base =3D (dma_addr_t)*vme_base + pci_offset; *size =3D (unsigned long long)((vme_bound - *vme_base) + granularity); =20 *enabled =3D 0; diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi= /iscsi_target_tpg.c index 309f14cbfc1c..3af32554fda2 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -253,7 +253,6 @@ err_out: iscsi_release_param_list(tpg->param_list); tpg->param_list =3D NULL; } - kfree(tpg); return -ENOMEM; } =20 diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index f6fb2921ba11..d9d2533edd63 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -486,7 +486,7 @@ temp_crit_show(struct device *dev, struct device_attrib= ute *attr, long temperature; int ret; =20 - ret =3D tz->ops->get_trip_temp(tz, 0, &temperature); + ret =3D tz->ops->get_crit_temp(tz, &temperature); if (ret) return ret; =20 diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index cea56033b34c..b2b096beb870 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -115,7 +115,7 @@ #define DEFAULT_TX_BUF_COUNT 3 =20 struct n_hdlc_buf { - struct n_hdlc_buf *link; + struct list_head list_item; int count; char buf[1]; }; @@ -123,8 +123,7 @@ struct n_hdlc_buf { #define N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe) =20 struct n_hdlc_buf_list { - struct n_hdlc_buf *head; - struct n_hdlc_buf *tail; + struct list_head list; int count; spinlock_t spinlock; }; @@ -137,7 +136,6 @@ struct n_hdlc_buf_list { * @backup_tty - TTY to use if tty gets closed * @tbusy - reentrancy flag for tx wakeup code * @woke_up - FIXME: describe this field - * @tbuf - currently transmitting tx buffer * @tx_buf_list - list of pending transmit frame buffers * @rx_buf_list - list of received frame buffers * @tx_free_buf_list - list unused transmit frame buffers @@ -150,7 +148,6 @@ struct n_hdlc { struct tty_struct *backup_tty; int tbusy; int woke_up; - struct n_hdlc_buf *tbuf; struct n_hdlc_buf_list tx_buf_list; struct n_hdlc_buf_list rx_buf_list; struct n_hdlc_buf_list tx_free_buf_list; @@ -160,7 +157,8 @@ struct n_hdlc { /* * HDLC buffer list manipulation functions */ -static void n_hdlc_buf_list_init(struct n_hdlc_buf_list *list); +static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list, + struct n_hdlc_buf *buf); static void n_hdlc_buf_put(struct n_hdlc_buf_list *list, struct n_hdlc_buf *buf); static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list); @@ -210,16 +208,9 @@ static void flush_tx_queue(struct tty_struct *tty) { struct n_hdlc *n_hdlc =3D tty2n_hdlc(tty); struct n_hdlc_buf *buf; - unsigned long flags; =20 while ((buf =3D n_hdlc_buf_get(&n_hdlc->tx_buf_list))) n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, buf); - spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); - if (n_hdlc->tbuf) { - n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, n_hdlc->tbuf); - n_hdlc->tbuf =3D NULL; - } - spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); } =20 static struct tty_ldisc_ops n_hdlc_ldisc =3D { @@ -285,7 +276,6 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc) } else break; } - kfree(n_hdlc->tbuf); kfree(n_hdlc); =09 } /* end of n_hdlc_release() */ @@ -404,13 +394,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, = struct tty_struct *tty) n_hdlc->woke_up =3D 0; spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags); =20 - /* get current transmit buffer or get new transmit */ - /* buffer from list of pending transmit buffers */ - =09 - tbuf =3D n_hdlc->tbuf; - if (!tbuf) - tbuf =3D n_hdlc_buf_get(&n_hdlc->tx_buf_list); - =09 + tbuf =3D n_hdlc_buf_get(&n_hdlc->tx_buf_list); while (tbuf) { if (debuglevel >=3D DEBUG_LEVEL_INFO)=09 printk("%s(%d)sending frame %p, count=3D%d\n", @@ -422,7 +406,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, s= truct tty_struct *tty) =20 /* rollback was possible and has been done */ if (actual =3D=3D -ERESTARTSYS) { - n_hdlc->tbuf =3D tbuf; + n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf); break; } /* if transmit error, throw frame away by */ @@ -437,10 +421,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, = struct tty_struct *tty) =09 /* free current transmit buffer */ n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf); - =09 - /* this tx buffer is done */ - n_hdlc->tbuf =3D NULL; - =09 + /* wait up sleeping writers */ wake_up_interruptible(&tty->write_wait); =09 @@ -450,10 +431,12 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc,= struct tty_struct *tty) if (debuglevel >=3D DEBUG_LEVEL_INFO)=09 printk("%s(%d)frame %p pending\n", __FILE__,__LINE__,tbuf); - =09 - /* buffer not accepted by driver */ - /* set this buffer as pending buffer */ - n_hdlc->tbuf =3D tbuf; + + /* + * the buffer was not accepted by driver, + * return it back into tx queue + */ + n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf); break; } } @@ -751,7 +734,8 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, str= uct file *file, int error =3D 0; int count; unsigned long flags; -=09 + struct n_hdlc_buf *buf =3D NULL; + if (debuglevel >=3D DEBUG_LEVEL_INFO)=09 printk("%s(%d)n_hdlc_tty_ioctl() called %d\n", __FILE__,__LINE__,cmd); @@ -765,8 +749,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, st= ruct file *file, /* report count of read data available */ /* in next available frame (if any) */ spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags); - if (n_hdlc->rx_buf_list.head) - count =3D n_hdlc->rx_buf_list.head->count; + buf =3D list_first_entry_or_null(&n_hdlc->rx_buf_list.list, + struct n_hdlc_buf, list_item); + if (buf) + count =3D buf->count; else count =3D 0; spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags); @@ -778,8 +764,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, st= ruct file *file, count =3D tty_chars_in_buffer(tty); /* add size of next output frame in queue */ spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags); - if (n_hdlc->tx_buf_list.head) - count +=3D n_hdlc->tx_buf_list.head->count; + buf =3D list_first_entry_or_null(&n_hdlc->tx_buf_list.list, + struct n_hdlc_buf, list_item); + if (buf) + count +=3D buf->count; spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags); error =3D put_user(count, (int __user *)arg); break; @@ -827,14 +815,14 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct= *tty, struct file *filp, poll_wait(filp, &tty->write_wait, wait); =20 /* set bits for operations that won't block */ - if (n_hdlc->rx_buf_list.head) + if (!list_empty(&n_hdlc->rx_buf_list.list)) mask |=3D POLLIN | POLLRDNORM; /* readable */ if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) mask |=3D POLLHUP; if (tty_hung_up_p(filp)) mask |=3D POLLHUP; if (!tty_is_writelocked(tty) && - n_hdlc->tx_free_buf_list.head) + !list_empty(&n_hdlc->tx_free_buf_list.list)) mask |=3D POLLOUT | POLLWRNORM; /* writable */ } return mask; @@ -856,11 +844,16 @@ static struct n_hdlc *n_hdlc_alloc(void) =20 memset(n_hdlc, 0, sizeof(*n_hdlc)); =20 - n_hdlc_buf_list_init(&n_hdlc->rx_free_buf_list); - n_hdlc_buf_list_init(&n_hdlc->tx_free_buf_list); - n_hdlc_buf_list_init(&n_hdlc->rx_buf_list); - n_hdlc_buf_list_init(&n_hdlc->tx_buf_list); -=09 + spin_lock_init(&n_hdlc->rx_free_buf_list.spinlock); + spin_lock_init(&n_hdlc->tx_free_buf_list.spinlock); + spin_lock_init(&n_hdlc->rx_buf_list.spinlock); + spin_lock_init(&n_hdlc->tx_buf_list.spinlock); + + INIT_LIST_HEAD(&n_hdlc->rx_free_buf_list.list); + INIT_LIST_HEAD(&n_hdlc->tx_free_buf_list.list); + INIT_LIST_HEAD(&n_hdlc->rx_buf_list.list); + INIT_LIST_HEAD(&n_hdlc->tx_buf_list.list); + /* allocate free rx buffer list */ for(i=3D0;ispinlock); -} /* end of n_hdlc_buf_list_init() */ + unsigned long flags; + + spin_lock_irqsave(&buf_list->spinlock, flags); + + list_add(&buf->list_item, &buf_list->list); + buf_list->count++; + + spin_unlock_irqrestore(&buf_list->spinlock, flags); +} =20 /** * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list - * @list - pointer to buffer list + * @buf_list - pointer to buffer list * @buf - pointer to buffer */ -static void n_hdlc_buf_put(struct n_hdlc_buf_list *list, +static void n_hdlc_buf_put(struct n_hdlc_buf_list *buf_list, struct n_hdlc_buf *buf) { unsigned long flags; - spin_lock_irqsave(&list->spinlock,flags); -=09 - buf->link=3DNULL; - if (list->tail) - list->tail->link =3D buf; - else - list->head =3D buf; - list->tail =3D buf; - (list->count)++; -=09 - spin_unlock_irqrestore(&list->spinlock,flags); -=09 + + spin_lock_irqsave(&buf_list->spinlock, flags); + + list_add_tail(&buf->list_item, &buf_list->list); + buf_list->count++; + + spin_unlock_irqrestore(&buf_list->spinlock, flags); } /* end of n_hdlc_buf_put() */ =20 /** * n_hdlc_buf_get - remove and return an HDLC buffer from list - * @list - pointer to HDLC buffer list + * @buf_list - pointer to HDLC buffer list *=20 * Remove and return an HDLC buffer from the head of the specified HDLC bu= ffer * list. * Returns a pointer to HDLC buffer if available, otherwise %NULL. */ -static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list) +static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *buf_list) { unsigned long flags; struct n_hdlc_buf *buf; - spin_lock_irqsave(&list->spinlock,flags); -=09 - buf =3D list->head; + + spin_lock_irqsave(&buf_list->spinlock, flags); + + buf =3D list_first_entry_or_null(&buf_list->list, + struct n_hdlc_buf, list_item); if (buf) { - list->head =3D buf->link; - (list->count)--; + list_del(&buf->list_item); + buf_list->count--; } - if (!list->head) - list->tail =3D NULL; -=09 - spin_unlock_irqrestore(&list->spinlock,flags); + + spin_unlock_irqrestore(&buf_list->spinlock, flags); return buf; -=09 } /* end of n_hdlc_buf_get() */ =20 static char hdlc_banner[] __initdata =3D diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 43db715f1502..53d43c06ab8d 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -763,8 +763,8 @@ static const struct input_device_id sysrq_ids[] =3D { { .flags =3D INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit =3D { BIT_MASK(EV_KEY) }, - .keybit =3D { BIT_MASK(KEY_LEFTALT) }, + .evbit =3D { [BIT_WORD(EV_KEY)] =3D BIT_MASK(EV_KEY) }, + .keybit =3D { [BIT_WORD(KEY_LEFTALT)] =3D BIT_MASK(KEY_LEFTALT) }, }, { }, }; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index a1b384ecabba..93249aa4bb15 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1541,6 +1541,7 @@ static const struct usb_device_id acm_ids[] =3D { .driver_info =3D NO_UNION_NORMAL, /* has no union descriptor */ }, { USB_DEVICE(0x2184, 0x001c) }, /* GW Instek AFG-2225 */ + { USB_DEVICE(0x2184, 0x0036) }, /* GW Instek AFG-125 */ { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ }, /* Motorola H24 HSPA module: */ diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 5a28a14ffa1b..43f0c13b0e81 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -207,6 +207,16 @@ static int usb_parse_endpoint(struct device *ddev, int= cfgno, int inum, if (ifp->desc.bNumEndpoints >=3D num_ep) goto skip_to_next_endpoint_or_interface_descriptor; =20 + /* Check for duplicate endpoint addresses */ + for (i =3D 0; i < ifp->desc.bNumEndpoints; ++i) { + if (ifp->endpoint[i].desc.bEndpointAddress =3D=3D + d->bEndpointAddress) { + dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate en= dpoint with address 0x%X, skipping\n", + cfgno, inum, asnum, d->bEndpointAddress); + goto skip_to_next_endpoint_or_interface_descriptor; + } + } + endpoint =3D &ifp->endpoint[ifp->desc.bNumEndpoints]; ++ifp->desc.bNumEndpoints; =20 diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 1353326f26f2..86cd0782500d 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -36,6 +36,10 @@ static const struct usb_device_id usb_quirk_list[] =3D { /* CBM - Flash disk */ { USB_DEVICE(0x0204, 0x6025), .driver_info =3D USB_QUIRK_RESET_RESUME }, =20 + /* WORLDE easy key (easykey.25) MIDI controller */ + { USB_DEVICE(0x0218, 0x0401), .driver_info =3D + USB_QUIRK_CONFIG_INTF_STRINGS }, + /* HP 5300/5370C scanner */ { USB_DEVICE(0x03f0, 0x0701), .driver_info =3D USB_QUIRK_STRING_FETCH_255 }, diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 4484ef1a00eb..ad03c6d0f6cd 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -156,7 +156,7 @@ int config_ep_by_speed(struct usb_gadget *g, =20 ep_found: /* commit results */ - _ep->maxpacket =3D usb_endpoint_maxp(chosen_desc); + _ep->maxpacket =3D usb_endpoint_maxp(chosen_desc) & 0x7ff; _ep->desc =3D chosen_desc; _ep->comp_desc =3D NULL; _ep->maxburst =3D 0; @@ -1126,9 +1126,7 @@ composite_setup(struct usb_gadget *gadget, const stru= ct usb_ctrlrequest *ctrl) value =3D min(w_length, (u16) 1); break; =20 - /* function drivers must handle get/set altsetting; if there's - * no get() method, we know only altsetting zero works. - */ + /* function drivers must handle get/set altsetting */ case USB_REQ_SET_INTERFACE: if (ctrl->bRequestType !=3D USB_RECIP_INTERFACE) goto unknown; @@ -1137,7 +1135,13 @@ composite_setup(struct usb_gadget *gadget, const str= uct usb_ctrlrequest *ctrl) f =3D cdev->config->interface[intf]; if (!f) break; - if (w_value && !f->set_alt) + + /* + * If there's no get_alt() method, we know only altsetting zero + * works. There is no need to check if set_alt() is not NULL + * as we check this in usb_add_function(). + */ + if (w_value && !f->get_alt) break; value =3D f->set_alt(f, w_index, w_value); if (value =3D=3D USB_GADGET_DELAYED_STATUS) { diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index c7423a7ec8f1..8e0a1bd92a54 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -261,7 +261,7 @@ static void nuke (struct dummy *dum, struct dummy_ep *e= p) static void stop_activity (struct dummy *dum) { - struct dummy_ep *ep; + int i; =20 /* prevent any more requests */ dum->address =3D 0; @@ -269,8 +269,8 @@ stop_activity (struct dummy *dum) /* The timer is left running so that outstanding URBs can fail */ =20 /* nuke any pending requests first, so driver i/o is quiesced */ - list_for_each_entry (ep, &dum->gadget.ep_list, ep.ep_list) - nuke (dum, ep); + for (i =3D 0; i < DUMMY_ENDPOINTS; ++i) + nuke(dum, &dum->ep[i]); =20 /* driver now does any non-usb quiescing necessary */ } diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index ce7253bfaa95..287c6ab505d6 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1196,7 +1196,7 @@ ep0_write (struct file *fd, const char __user *buf, s= ize_t len, loff_t *ptr) /* data and/or status stage for control request */ } else if (dev->state =3D=3D STATE_DEV_SETUP) { =20 - /* IN DATA+STATUS caller makes len <=3D wLength */ + len =3D min_t(size_t, len, dev->setup_wLength); if (dev->setup_in) { retval =3D setup_req (dev->gadget->ep0, dev->req, len); if (retval =3D=3D 0) { @@ -1841,10 +1841,12 @@ static struct usb_gadget_driver probe_driver =3D { * such as configuration notifications. */ =20 -static int is_valid_config (struct usb_config_descriptor *config) +static int is_valid_config(struct usb_config_descriptor *config, + unsigned int total) { return config->bDescriptorType =3D=3D USB_DT_CONFIG && config->bLength =3D=3D USB_DT_CONFIG_SIZE + && total >=3D USB_DT_CONFIG_SIZE && config->bConfigurationValue !=3D 0 && (config->bmAttributes & USB_CONFIG_ATT_ONE) !=3D 0 && (config->bmAttributes & USB_CONFIG_ATT_WAKEUP) =3D=3D 0; @@ -1861,7 +1863,8 @@ dev_config (struct file *fd, const char __user *buf, = size_t len, loff_t *ptr) u32 tag; char *kbuf; =20 - if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) + if ((len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) || + (len > PAGE_SIZE * 4)) return -EINVAL; =20 /* we might need to change message format someday */ @@ -1885,7 +1888,8 @@ dev_config (struct file *fd, const char __user *buf, = size_t len, loff_t *ptr) /* full or low speed config */ dev->config =3D (void *) kbuf; total =3D le16_to_cpu(dev->config->wTotalLength); - if (!is_valid_config (dev->config) || total >=3D length) + if (!is_valid_config(dev->config, total) || + total > length - USB_DT_DEVICE_SIZE) goto fail; kbuf +=3D total; length -=3D total; @@ -1894,10 +1898,13 @@ dev_config (struct file *fd, const char __user *buf= , size_t len, loff_t *ptr) if (kbuf [1] =3D=3D USB_DT_CONFIG) { dev->hs_config =3D (void *) kbuf; total =3D le16_to_cpu(dev->hs_config->wTotalLength); - if (!is_valid_config (dev->hs_config) || total >=3D length) + if (!is_valid_config(dev->hs_config, total) || + total > length - USB_DT_DEVICE_SIZE) goto fail; kbuf +=3D total; length -=3D total; + } else { + dev->hs_config =3D NULL; } =20 /* could support multiple configs, using another encoding! */ diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index 0f228c46eeda..ad458ef4b7e9 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c @@ -129,6 +129,10 @@ static int uhci_pci_init(struct usb_hcd *hcd) if (to_pci_dev(uhci_dev(uhci))->vendor =3D=3D PCI_VENDOR_ID_HP) uhci->wait_for_hp =3D 1; =20 + /* Intel controllers use non-PME wakeup signalling */ + if (to_pci_dev(uhci_dev(uhci))->vendor =3D=3D PCI_VENDOR_ID_INTEL) + device_set_run_wake(uhci_dev(uhci), 1); + /* Set up pointers to PCI-specific functions */ uhci->reset_hc =3D uhci_pci_reset_hc; uhci->check_and_reset_hc =3D uhci_pci_check_and_reset_hc; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index e3f70d3fb44c..9a291529338c 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -827,6 +827,40 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int = slot_id) xhci->devs[slot_id] =3D NULL; } =20 +/* + * Free a virt_device structure. + * If the virt_device added a tt_info (a hub) and has children pointing to + * that tt_info, then free the child first. Recursive. + * We can't rely on udev at this point to find child-parent relationships. + */ +void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_id) +{ + struct xhci_virt_device *vdev; + struct list_head *tt_list_head; + struct xhci_tt_bw_info *tt_info, *next; + int i; + + vdev =3D xhci->devs[slot_id]; + if (!vdev) + return; + + tt_list_head =3D &(xhci->rh_bw[vdev->real_port - 1].tts); + list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) { + /* is this a hub device that added a tt_info to the tts list */ + if (tt_info->slot_id =3D=3D slot_id) { + /* are any devices using this tt_info? */ + for (i =3D 1; i < HCS_MAX_SLOTS(xhci->hcs_params1); i++) { + vdev =3D xhci->devs[i]; + if (vdev && (vdev->tt_info =3D=3D tt_info)) + xhci_free_virt_devices_depth_first( + xhci, i); + } + } + } + /* we are now at a leaf device */ + xhci_free_virt_device(xhci, slot_id); +} + int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags) { @@ -1732,8 +1766,8 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) } } =20 - for (i =3D 1; i < MAX_HC_SLOTS; ++i) - xhci_free_virt_device(xhci, i); + for (i =3D HCS_MAX_SLOTS(xhci->hcs_params1); i > 0; i--) + xhci_free_virt_devices_depth_first(xhci, i); =20 if (xhci->segment_pool) dma_pool_destroy(xhci->segment_pool); @@ -2234,7 +2268,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) * "physically contiguous and 64-byte (cache line) aligned". */ xhci->dcbaa =3D dma_alloc_coherent(dev, sizeof(*xhci->dcbaa), &dma, - GFP_KERNEL); + flags); if (!xhci->dcbaa) goto fail; memset(xhci->dcbaa, 0, sizeof *(xhci->dcbaa)); @@ -2315,7 +2349,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) =20 xhci->erst.entries =3D dma_alloc_coherent(dev, sizeof(struct xhci_erst_entry) * ERST_NUM_SEGS, &dma, - GFP_KERNEL); + flags); if (!xhci->erst.entries) goto fail; xhci_dbg(xhci, "// Allocated event ring segment table at 0x%llx\n", diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 5fdb85fba447..35e1b8461bff 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -969,12 +969,6 @@ void xhci_stop_endpoint_command_watchdog(unsigned long= arg) spin_lock_irqsave(&xhci->lock, flags); =20 ep->stop_cmds_pending--; - if (xhci->xhc_state & XHCI_STATE_DYING) { - xhci_dbg(xhci, "Stop EP timer ran, but another timer marked " - "xHCI as DYING, exiting.\n"); - spin_unlock_irqrestore(&xhci->lock, flags); - return; - } if (!(ep->stop_cmds_pending =3D=3D 0 && (ep->ep_state & EP_HALT_PENDING))= ) { xhci_dbg(xhci, "Stop EP timer ran, but no command pending, " "exiting.\n"); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index cfd5d3a6d34d..a834373411f2 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1549,18 +1549,6 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb= *urb, int status) xhci_urb_free_priv(xhci, urb_priv); return ret; } - if ((xhci->xhc_state & XHCI_STATE_DYING) || - (xhci->xhc_state & XHCI_STATE_HALTED)) { - xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " - "non-responsive xHCI host.\n", - urb->ep->desc.bEndpointAddress, urb); - /* Let the stop endpoint command watchdog timer (which set this - * state) finish cleaning up the endpoint TD lists. We must - * have caught it in the middle of dropping a lock and giving - * back an URB. - */ - goto done; - } =20 xhci_dbg(xhci, "Cancel URB %p\n", urb); xhci_dbg(xhci, "Event ring:\n"); diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h index 320fd4afb93f..71f8ef005c1b 100644 --- a/drivers/usb/musb/musbhsdma.h +++ b/drivers/usb/musb/musbhsdma.h @@ -161,5 +161,5 @@ struct musb_dma_controller { void __iomem *base; u8 channel_count; u8 used_channels; - u8 irq; + int irq; }; diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index c4d95b0d98d5..d50a6a696a8d 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -62,13 +62,26 @@ * the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato. */ =20 +#define CH341_REQ_READ_VERSION 0x5F #define CH341_REQ_WRITE_REG 0x9A #define CH341_REQ_READ_REG 0x95 -#define CH341_REG_BREAK1 0x05 -#define CH341_REG_BREAK2 0x18 -#define CH341_NBREAK_BITS_REG1 0x01 -#define CH341_NBREAK_BITS_REG2 0x40 - +#define CH341_REQ_SERIAL_INIT 0xA1 +#define CH341_REQ_MODEM_CTRL 0xA4 + +#define CH341_REG_BREAK 0x05 +#define CH341_REG_LCR 0x18 +#define CH341_NBREAK_BITS 0x01 + +#define CH341_LCR_ENABLE_RX 0x80 +#define CH341_LCR_ENABLE_TX 0x40 +#define CH341_LCR_MARK_SPACE 0x20 +#define CH341_LCR_PAR_EVEN 0x10 +#define CH341_LCR_ENABLE_PAR 0x08 +#define CH341_LCR_STOP_BITS_2 0x04 +#define CH341_LCR_CS8 0x03 +#define CH341_LCR_CS7 0x02 +#define CH341_LCR_CS6 0x01 +#define CH341_LCR_CS5 0x00 =20 static int debug; =20 @@ -88,6 +101,10 @@ struct ch341_private { u8 multi_status_change; /* status changed multiple since last call */ }; =20 +static void ch341_set_termios(struct tty_struct *tty, + struct usb_serial_port *port, + struct ktermios *old_termios); + static int ch341_control_out(struct usb_device *dev, u8 request, u16 value, u16 index) { @@ -98,6 +115,8 @@ static int ch341_control_out(struct usb_device *dev, u8 = request, r =3D usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, value, index, NULL, 0, DEFAULT_TIMEOUT); + if (r < 0) + dev_err(&dev->dev, "failed to send control message: %d\n", r); =20 return r; } @@ -113,13 +132,26 @@ static int ch341_control_in(struct usb_device *dev, r =3D usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, value, index, buf, bufsize, DEFAULT_TIMEOUT); - return r; + if (r < bufsize) { + if (r >=3D 0) { + dev_err(&dev->dev, + "short control message received (%d < %u)\n", + r, bufsize); + r =3D -EIO; + } + + dev_err(&dev->dev, "failed to receive control message: %d\n", + r); + return r; + } + + return 0; } =20 -static int ch341_set_baudrate(struct usb_device *dev, - struct ch341_private *priv) +static int ch341_set_baudrate_lcr(struct usb_device *dev, + struct ch341_private *priv, u8 lcr) { - short a, b; + short a; int r; unsigned long factor; short divisor; @@ -141,11 +173,20 @@ static int ch341_set_baudrate(struct usb_device *dev, =20 factor =3D 0x10000 - factor; a =3D (factor & 0xff00) | divisor; - b =3D factor & 0xff; =20 - r =3D ch341_control_out(dev, 0x9a, 0x1312, a); - if (!r) - r =3D ch341_control_out(dev, 0x9a, 0x0f2c, b); + /* + * CH341A buffers data until a full endpoint-size packet (32 bytes) + * has been received unless bit 7 is set. + */ + a |=3D BIT(7); + + r =3D ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, a); + if (r) + return r; + + r =3D ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, lcr); + if (r) + return r; =20 return r; } @@ -153,14 +194,14 @@ static int ch341_set_baudrate(struct usb_device *dev, static int ch341_set_handshake(struct usb_device *dev, u8 control) { dbg("ch341_set_handshake(0x%02x)", control); - return ch341_control_out(dev, 0xa4, ~control, 0); + return ch341_control_out(dev, CH341_REQ_MODEM_CTRL, ~control, 0); } =20 static int ch341_get_status(struct usb_device *dev, struct ch341_private *= priv) { + const unsigned int size =3D 2; char *buffer; int r; - const unsigned size =3D 8; unsigned long flags; =20 dbg("ch341_get_status()"); @@ -169,19 +210,14 @@ static int ch341_get_status(struct usb_device *dev, s= truct ch341_private *priv) if (!buffer) return -ENOMEM; =20 - r =3D ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size); + r =3D ch341_control_in(dev, CH341_REQ_READ_REG, 0x0706, 0, buffer, size); if (r < 0) goto out; =20 - /* setup the private status if available */ - if (r =3D=3D 2) { - r =3D 0; - spin_lock_irqsave(&priv->lock, flags); - priv->line_status =3D (~(*buffer)) & CH341_BITS_MODEM_STAT; - priv->multi_status_change =3D 0; - spin_unlock_irqrestore(&priv->lock, flags); - } else - r =3D -EPROTO; + spin_lock_irqsave(&priv->lock, flags); + priv->line_status =3D (~(*buffer)) & CH341_BITS_MODEM_STAT; + priv->multi_status_change =3D 0; + spin_unlock_irqrestore(&priv->lock, flags); =20 out: kfree(buffer); return r; @@ -191,9 +227,9 @@ out: kfree(buffer); =20 static int ch341_configure(struct usb_device *dev, struct ch341_private *p= riv) { + const unsigned int size =3D 2; char *buffer; int r; - const unsigned size =3D 8; =20 dbg("ch341_configure()"); =20 @@ -202,24 +238,20 @@ static int ch341_configure(struct usb_device *dev, st= ruct ch341_private *priv) return -ENOMEM; =20 /* expect two bytes 0x27 0x00 */ - r =3D ch341_control_in(dev, 0x5f, 0, 0, buffer, size); + r =3D ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size); if (r < 0) goto out; =20 - r =3D ch341_control_out(dev, 0xa1, 0, 0); - if (r < 0) - goto out; - - r =3D ch341_set_baudrate(dev, priv); + r =3D ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0); if (r < 0) goto out; =20 /* expect two bytes 0x56 0x00 */ - r =3D ch341_control_in(dev, 0x95, 0x2518, 0, buffer, size); + r =3D ch341_control_in(dev, CH341_REQ_READ_REG, 0x2518, 0, buffer, size); if (r < 0) goto out; =20 - r =3D ch341_control_out(dev, 0x9a, 0x2518, 0x0050); + r =3D ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, 0x0050); if (r < 0) goto out; =20 @@ -228,11 +260,7 @@ static int ch341_configure(struct usb_device *dev, str= uct ch341_private *priv) if (r < 0) goto out; =20 - r =3D ch341_control_out(dev, 0xa1, 0x501f, 0xd90a); - if (r < 0) - goto out; - - r =3D ch341_set_baudrate(dev, priv); + r =3D ch341_set_baudrate_lcr(dev, priv, 0); if (r < 0) goto out; =20 @@ -262,7 +290,6 @@ static int ch341_attach(struct usb_serial *serial) =20 spin_lock_init(&priv->lock); priv->baud_rate =3D DEFAULT_BAUD_RATE; - priv->line_control =3D CH341_BIT_RTS | CH341_BIT_DTR; =20 r =3D ch341_configure(serial->dev, priv); if (r < 0) @@ -318,19 +345,12 @@ static int ch341_open(struct tty_struct *tty, struct = usb_serial_port *port) =20 dbg("ch341_open()"); =20 - priv->baud_rate =3D DEFAULT_BAUD_RATE; - r =3D ch341_configure(serial->dev, priv); if (r) - goto out; + return r; =20 - r =3D ch341_set_handshake(serial->dev, priv->line_control); - if (r) - goto out; - - r =3D ch341_set_baudrate(serial->dev, priv); - if (r) - goto out; + if (tty) + ch341_set_termios(tty, port, NULL); =20 dbg("%s - submitting interrupt urb", __func__); port->interrupt_in_urb->dev =3D serial->dev; @@ -338,13 +358,19 @@ static int ch341_open(struct tty_struct *tty, struct = usb_serial_port *port) if (r) { dev_err(&port->dev, "%s - failed submitting interrupt urb," " error %d\n", __func__, r); - ch341_close(port); - return -EPROTO; + return r; } =20 r =3D usb_serial_generic_open(tty, port); + if (r) + goto err_kill_interrupt_urb; + + return 0; + +err_kill_interrupt_urb: + usb_kill_urb(port->interrupt_in_urb); =20 -out: return r; + return r; } =20 /* Old_termios contains the original termios settings and @@ -356,25 +382,35 @@ static void ch341_set_termios(struct tty_struct *tty, struct ch341_private *priv =3D usb_get_serial_port_data(port); unsigned baud_rate; unsigned long flags; + unsigned char ctrl; + int r; + + /* redundant changes may cause the chip to lose bytes */ + if (old_termios && !tty_termios_hw_change(tty->termios, old_termios)) + return; =20 dbg("ch341_set_termios()"); =20 baud_rate =3D tty_get_baud_rate(tty); =20 - priv->baud_rate =3D baud_rate; + ctrl =3D CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8; =20 if (baud_rate) { - spin_lock_irqsave(&priv->lock, flags); - priv->line_control |=3D (CH341_BIT_DTR | CH341_BIT_RTS); - spin_unlock_irqrestore(&priv->lock, flags); - ch341_set_baudrate(port->serial->dev, priv); - } else { - spin_lock_irqsave(&priv->lock, flags); - priv->line_control &=3D ~(CH341_BIT_DTR | CH341_BIT_RTS); - spin_unlock_irqrestore(&priv->lock, flags); + priv->baud_rate =3D baud_rate; + + r =3D ch341_set_baudrate_lcr(port->serial->dev, priv, ctrl); + if (r < 0 && old_termios) { + priv->baud_rate =3D tty_termios_baud_rate(old_termios); + tty_termios_copy_hw(tty->termios, old_termios); + } } =20 - ch341_set_handshake(port->serial->dev, priv->line_control); + spin_lock_irqsave(&priv->lock, flags); + if (C_BAUD(tty) =3D=3D B0) + priv->line_control &=3D ~(CH341_BIT_DTR | CH341_BIT_RTS); + else if (old_termios && (old_termios->c_cflag & CBAUD) =3D=3D B0) + priv->line_control |=3D (CH341_BIT_DTR | CH341_BIT_RTS); + spin_unlock_irqrestore(&priv->lock, flags); =20 /* Unimplemented: * (cflag & CSIZE) : data bits [5, 8] @@ -386,7 +422,7 @@ static void ch341_set_termios(struct tty_struct *tty, static void ch341_break_ctl(struct tty_struct *tty, int break_state) { const uint16_t ch341_break_reg =3D - CH341_REG_BREAK1 | ((uint16_t) CH341_REG_BREAK2 << 8); + ((uint16_t) CH341_REG_LCR << 8) | CH341_REG_BREAK; struct usb_serial_port *port =3D tty->driver_data; int r; uint16_t reg_contents; @@ -411,12 +447,12 @@ static void ch341_break_ctl(struct tty_struct *tty, i= nt break_state) __func__, break_reg[0], break_reg[1]); if (break_state !=3D 0) { dbg("%s - Enter break state requested", __func__); - break_reg[0] &=3D ~CH341_NBREAK_BITS_REG1; - break_reg[1] &=3D ~CH341_NBREAK_BITS_REG2; + break_reg[0] &=3D ~CH341_NBREAK_BITS; + break_reg[1] &=3D ~CH341_LCR_ENABLE_TX; } else { dbg("%s - Leave break state requested", __func__); - break_reg[0] |=3D CH341_NBREAK_BITS_REG1; - break_reg[1] |=3D CH341_NBREAK_BITS_REG2; + break_reg[0] |=3D CH341_NBREAK_BITS; + break_reg[1] |=3D CH341_LCR_ENABLE_TX; } dbg("%s - New ch341 break register contents - reg1: %x, reg2: %x", __func__, break_reg[0], break_reg[1]); @@ -605,18 +641,24 @@ static int ch341_tiocmget(struct tty_struct *tty) static int ch341_reset_resume(struct usb_interface *intf) { struct usb_device *dev =3D interface_to_usbdev(intf); - struct usb_serial *serial =3D NULL; - struct ch341_private *priv; - - serial =3D usb_get_intfdata(intf); - priv =3D usb_get_serial_port_data(serial->port[0]); + struct usb_serial *serial =3D usb_get_intfdata(intf); + struct usb_serial_port *port =3D serial->port[0]; + struct ch341_private *priv =3D usb_get_serial_port_data(port); + int ret; =20 /*reconfigure ch341 serial port after bus-reset*/ ch341_configure(dev, priv); =20 - usb_serial_resume(intf); + if (port->port.flags & ASYNC_INITIALIZED) { + ret =3D usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); + if (ret) { + dev_err(&port->dev, "failed to submit interrupt urb: %d\n", + ret); + return ret; + } + } =20 - return 0; + return usb_serial_generic_resume(serial); } =20 static struct usb_driver ch341_driver =3D { diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index f744ab7a3b19..2cf85872e938 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -122,6 +122,9 @@ static int cyberjack_startup(struct usb_serial *serial) =20 dbg("%s", __func__); =20 + if (serial->num_bulk_out < serial->num_ports) + return -ENODEV; + /* allocate the private data structure */ priv =3D kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); if (!priv) diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gp= s.c index e664bac23755..0c1c8ca85e1f 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1075,6 +1075,7 @@ static int garmin_write_bulk(struct usb_serial_port *= port, "%s - usb_submit_urb(write bulk) failed with status =3D %d\n", __func__, status); count =3D status; + kfree(buffer); } =20 /* we are done with this urb, so let the host driver diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgep= ort.c index 0af0b41ba9bc..5a76b1c493f2 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -2936,6 +2936,11 @@ static int edge_startup(struct usb_serial *serial) EDGE_COMPATIBILITY_MASK1, EDGE_COMPATIBILITY_MASK2 }; =20 + if (serial->num_bulk_in < 1 || serial->num_interrupt_in < 1) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + dev =3D serial->dev; =20 /* create our private serial structure */ diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 438138fc346a..48749733b117 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1500,7 +1500,7 @@ stayinbootmode: dbg("%s - STAYING IN BOOT MODE", __func__); serial->product_info.TiMode =3D TI_MODE_BOOT; =20 - return 0; + return 1; } =20 =20 @@ -2642,6 +2642,13 @@ static int edge_startup(struct usb_serial *serial) =20 dev =3D serial->dev; =20 + /* Make sure we have the required endpoints when in download mode. */ + if (serial->interface->cur_altsetting->desc.bNumEndpoints > 1) { + if (serial->num_bulk_in < serial->num_ports || + serial->num_bulk_out < serial->num_ports) + return -ENODEV; + } + /* create our private serial structure */ edge_serial =3D kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); if (edge_serial =3D=3D NULL) { @@ -2653,11 +2660,14 @@ static int edge_startup(struct usb_serial *serial) usb_set_serial_data(serial, edge_serial); =20 status =3D download_fw(edge_serial); - if (status) { + if (status < 0) { kfree(edge_serial); return status; } =20 + if (status > 0) + return 1; /* bind but do not register any ports */ + /* set up our port private structures */ for (i =3D 0; i < serial->num_ports; ++i) { edge_port =3D kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); @@ -2708,6 +2718,8 @@ static void edge_release(struct usb_serial *serial) =20 for (i =3D 0; i < serial->num_ports; ++i) { edge_port =3D usb_get_serial_port_data(serial->port[i]); + if (!edge_port) + continue; kfifo_free(&edge_port->write_fifo); kfree(edge_port); } diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoe= nix.c index cf2668eb9cd3..418a4e33a68b 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -112,7 +112,12 @@ static int iuu_alloc_buf(struct iuu_private *priv) =20 static int iuu_startup(struct usb_serial *serial) { + unsigned char num_ports =3D serial->num_ports; struct iuu_private *priv; + + if (serial->num_bulk_in < num_ports || serial->num_bulk_out < num_ports) + return -ENODEV; + priv =3D kzalloc(sizeof(struct iuu_private), GFP_KERNEL); dbg("%s- priv allocation success", __func__); if (!priv) diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_= pda.c index 661a1a227092..65a090660e73 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -806,9 +806,15 @@ MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); =20 static int keyspan_pda_startup(struct usb_serial *serial) { - + unsigned char num_ports =3D serial->num_ports; struct keyspan_pda_private *priv; =20 + if (serial->num_bulk_out < num_ports || + serial->num_interrupt_in < num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + /* allocate the private data structures for all ports. Well, for all one ports. */ =20 diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb10= 5.c index 2cf92f1d2847..59cece12037d 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -338,7 +338,7 @@ static int klsi_105_open(struct tty_struct *tty, struc= t usb_serial_port *port) rc =3D usb_serial_generic_open(tty, port); if (rc) { retval =3D rc; - goto exit; + goto err_free_cfg; } =20 rc =3D usb_control_msg(port->serial->dev, @@ -353,21 +353,38 @@ static int klsi_105_open(struct tty_struct *tty, str= uct usb_serial_port *port) if (rc < 0) { dev_err(&port->dev, "Enabling read failed (error =3D %d)\n", rc); retval =3D rc; + goto err_generic_close; } else dbg("%s - enabled reading", __func__); =20 rc =3D klsi_105_get_line_state(port, &line_state); - if (rc >=3D 0) { - spin_lock_irqsave(&priv->lock, flags); - priv->line_state =3D line_state; - spin_unlock_irqrestore(&priv->lock, flags); - dbg("%s - read line state 0x%lx", __func__, line_state); - retval =3D 0; - } else + if (rc < 0) { retval =3D rc; + goto err_disable_read; + } + + spin_lock_irqsave(&priv->lock, flags); + priv->line_state =3D line_state; + spin_unlock_irqrestore(&priv->lock, flags); + dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__, + line_state); =20 -exit: + return 0; + +err_disable_read: + usb_control_msg(port->serial->dev, + usb_sndctrlpipe(port->serial->dev, 0), + KL5KUSB105A_SIO_CONFIGURE, + USB_TYPE_VENDOR | USB_DIR_OUT, + KL5KUSB105A_SIO_CONFIGURE_READ_OFF, + 0, /* index */ + NULL, 0, + KLSI_TIMEOUT); +err_generic_close: + usb_serial_generic_close(port); +err_free_cfg: kfree(cfg); + return retval; } =20 diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 16a6420828b9..cf5f53083c6b 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -150,6 +150,11 @@ static int kobil_startup(struct usb_serial *serial) struct usb_host_interface *altsetting; struct usb_host_endpoint *endpoint; =20 + if (serial->num_interrupt_out < serial->num_ports) { + dev_err(&serial->interface->dev, "missing interrupt-out endpoint\n"); + return -ENODEV; + } + priv =3D kmalloc(sizeof(struct kobil_private), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index e3609b84b7a8..ed46a765600b 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -73,8 +73,6 @@ struct moschip_port { =20 static int debug; =20 -static struct usb_serial_driver moschip7720_2port_driver; - #define USB_VENDOR_ID_MOSCHIP 0x9710 #define MOSCHIP_DEVICE_ID_7720 0x7720 #define MOSCHIP_DEVICE_ID_7715 0x7715 @@ -1001,25 +999,6 @@ static void mos7720_bulk_out_data_callback(struct urb= *urb) tty_kref_put(tty); } =20 -/* - * mos77xx_probe - * this function installs the appropriate read interrupt endpoint callback - * depending on whether the device is a 7720 or 7715, thus avoiding costly - * run-time checks in the high-frequency callback routine itself. - */ -static int mos77xx_probe(struct usb_serial *serial, - const struct usb_device_id *id) -{ - if (id->idProduct =3D=3D MOSCHIP_DEVICE_ID_7715) - moschip7720_2port_driver.read_int_callback =3D - mos7715_interrupt_callback; - else - moschip7720_2port_driver.read_int_callback =3D - mos7720_interrupt_callback; - - return 0; -} - static int mos77xx_calc_num_ports(struct usb_serial *serial) { u16 product =3D le16_to_cpu(serial->dev->descriptor.idProduct); @@ -2079,6 +2058,11 @@ static int mos7720_startup(struct usb_serial *serial) return -ENODEV; } =20 + if (serial->num_bulk_in < 2 || serial->num_bulk_out < 2) { + dev_err(&serial->interface->dev, "missing bulk endpoints\n"); + return -ENODEV; + } + product =3D le16_to_cpu(serial->dev->descriptor.idProduct); dev =3D serial->dev; =20 @@ -2103,6 +2087,12 @@ static int mos7720_startup(struct usb_serial *serial) tmp->interrupt_in_endpointAddress; serial->port[1]->interrupt_in_urb =3D NULL; serial->port[1]->interrupt_in_buffer =3D NULL; + + if (serial->port[0]->interrupt_in_urb) { + struct urb *urb =3D serial->port[0]->interrupt_in_urb; + + urb->complete =3D mos7715_interrupt_callback; + } } =20 =20 @@ -2132,13 +2122,6 @@ static int mos7720_startup(struct usb_serial *serial) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000); =20 - /* start the interrupt urb */ - ret_val =3D usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); - if (ret_val) - dev_err(&dev->dev, - "%s - Error %d submitting control urb\n", - __func__, ret_val); - #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT if (product =3D=3D MOSCHIP_DEVICE_ID_7715) { ret_val =3D mos7715_parport_init(serial); @@ -2146,6 +2129,13 @@ static int mos7720_startup(struct usb_serial *serial) return ret_val; } #endif + /* start the interrupt urb */ + ret_val =3D usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); + if (ret_val) { + dev_err(&dev->dev, "failed to submit interrupt urb: %d\n", + ret_val); + } + /* LSR For Port 1 */ read_mos_reg(serial, 0, LSR, &data); dbg("LSR:%x", data); @@ -2157,6 +2147,8 @@ static void mos7720_release(struct usb_serial *serial) { int i; =20 + usb_kill_urb(serial->port[0]->interrupt_in_urb); + #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT /* close the parallel port */ =20 @@ -2221,7 +2213,6 @@ static struct usb_serial_driver moschip7720_2port_dri= ver =3D { .close =3D mos7720_close, .throttle =3D mos7720_throttle, .unthrottle =3D mos7720_unthrottle, - .probe =3D mos77xx_probe, .attach =3D mos7720_startup, .release =3D mos7720_release, .ioctl =3D mos7720_ioctl, @@ -2234,7 +2225,7 @@ static struct usb_serial_driver moschip7720_2port_dri= ver =3D { .chars_in_buffer =3D mos7720_chars_in_buffer, .break_ctl =3D mos7720_break, .read_bulk_callback =3D mos7720_bulk_in_callback, - .read_int_callback =3D NULL /* dynamically assigned in probe() */ + .read_int_callback =3D mos7720_interrupt_callback, }; =20 static int __init moschip7720_init(void) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 59fdb84d016f..643898943a15 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1071,9 +1071,7 @@ static int mos7840_open(struct tty_struct *tty, struc= t usb_serial_port *port) serial, serial->port[0]->interrupt_in_urb->interval); =20 - /* start interrupt read for mos7840 * - * will continue as long as mos7840 is connected */ - + /* start interrupt read for mos7840 */ response =3D usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); @@ -2386,6 +2384,12 @@ static int mos7840_startup(struct usb_serial *serial) return -1; } =20 + if (serial->num_bulk_in < serial->num_ports || + serial->num_bulk_out < serial->num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + dev =3D serial->dev; =20 dbg("%s", "Entering..."); diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 0a8c1e64b247..5c7abfb9aea7 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -152,6 +152,12 @@ static int omninet_attach(struct usb_serial *serial) struct omninet_data *od; struct usb_serial_port *port =3D serial->port[0]; =20 + /* The second bulk-out endpoint is used for writing. */ + if (serial->num_bulk_out < 2) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + od =3D kmalloc(sizeof(struct omninet_data), GFP_KERNEL); if (!od) { dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 10e79b76e8d1..e421eb8fbb9d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -269,6 +269,8 @@ static void option_instat_callback(struct urb *urb); #define TELIT_PRODUCT_CC864_SINGLE 0x1006 #define TELIT_PRODUCT_DE910_DUAL 0x1010 #define TELIT_PRODUCT_UE910_V2 0x1012 +#define TELIT_PRODUCT_LE922_USBCFG1 0x1040 +#define TELIT_PRODUCT_LE922_USBCFG2 0x1041 #define TELIT_PRODUCT_LE922_USBCFG0 0x1042 #define TELIT_PRODUCT_LE922_USBCFG3 0x1043 #define TELIT_PRODUCT_LE920 0x1200 @@ -1196,6 +1198,10 @@ static const struct usb_device_id option_ids[] =3D { { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), .driver_info =3D (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1), + .driver_info =3D (kernel_ulong_t)&telit_le910_blacklist }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG2), + .driver_info =3D (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3), .driver_info =3D (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), @@ -1957,6 +1963,7 @@ static const struct usb_device_id option_ids[] =3D { { USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WM= D200, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_68= 02, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WM= D300, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x421d, 0xff, 0xff, 0xff) }, /* H= P lt2523 (Novatel E371) */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 8ceaa89fe3c9..dffbe618f9f5 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -347,9 +347,17 @@ static void send_data(struct work_struct *work) static int oti6858_startup(struct usb_serial *serial) { struct usb_serial_port *port =3D serial->port[0]; + unsigned char num_ports =3D serial->num_ports; struct oti6858_private *priv; int i; =20 + if (serial->num_bulk_in < num_ports || + serial->num_bulk_out < num_ports || + serial->num_interrupt_in < num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + for (i =3D 0; i < serial->num_ports; ++i) { priv =3D kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); if (!priv) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index a440387fd3f7..5910dacee8cc 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -55,6 +55,7 @@ static const struct usb_device_id id_table[] =3D { { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, + { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID2) }, { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) }, { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) }, { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID_UCSGT) }, @@ -185,10 +186,18 @@ static int pl2303_vendor_write(__u16 value, __u16 ind= ex, static int pl2303_startup(struct usb_serial *serial) { struct pl2303_private *priv; + unsigned char num_ports =3D serial->num_ports; enum pl2303_type type =3D type_0; unsigned char *buf; int i; =20 + if (serial->num_bulk_in < num_ports || + serial->num_bulk_out < num_ports || + serial->num_interrupt_in < num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + buf =3D kmalloc(10, GFP_KERNEL); if (buf =3D=3D NULL) return -ENOMEM; diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index e3b7af8adfb7..09d9be88209e 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -27,6 +27,7 @@ #define ATEN_VENDOR_ID 0x0557 #define ATEN_VENDOR_ID2 0x0547 #define ATEN_PRODUCT_ID 0x2008 +#define ATEN_PRODUCT_ID2 0x2118 =20 #define IODATA_VENDOR_ID 0x04bb #define IODATA_PRODUCT_ID 0x0a03 diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 2f67b99282cc..760ee96c3349 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -176,6 +176,13 @@ static int spcp8x5_startup(struct usb_serial *serial) int i; enum spcp8x5_type type =3D SPCP825_007_TYPE; u16 product =3D le16_to_cpu(serial->dev->descriptor.idProduct); + unsigned char num_ports =3D serial->num_ports; + + if (serial->num_bulk_in < num_ports || + serial->num_bulk_out < num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } =20 if (product =3D=3D 0x0201) type =3D SPCP825_007_TYPE; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_= usb_3410_5052.c index ad0445a68a02..6bf24d10324c 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -438,6 +438,13 @@ static int ti_startup(struct usb_serial *serial) goto free_tdev; } =20 + if (serial->num_bulk_in < serial->num_ports || + serial->num_bulk_out < serial->num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + status =3D -ENODEV; + goto free_tdev; + } + /* set up port structures */ for (i =3D 0; i < serial->num_ports; ++i) { tport =3D kzalloc(sizeof(struct ti_port), GFP_KERNEL); diff --git a/fs/block_dev.c b/fs/block_dev.c index c10326753915..a693d0cb21ee 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -687,7 +687,7 @@ static bool bd_may_claim(struct block_device *bdev, str= uct block_device *whole, return true; /* already a holder */ else if (bdev->bd_holder !=3D NULL) return false; /* held by someone else */ - else if (bdev->bd_contains =3D=3D bdev) + else if (whole =3D=3D bdev) return true; /* is a whole device which isn't held */ =20 else if (whole->bd_holder =3D=3D bd_may_claim) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 360072f42afe..231fbe1db357 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3276,6 +3276,10 @@ long btrfs_ioctl(struct file *file, unsigned int #ifdef CONFIG_COMPAT long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long= arg) { + /* + * These all access 32-bit values anyway so no further + * handling is necessary. + */ switch (cmd) { case FS_IOC32_GETFLAGS: cmd =3D FS_IOC_GETFLAGS; @@ -3286,8 +3290,6 @@ long btrfs_compat_ioctl(struct file *file, unsigned i= nt cmd, unsigned long arg) case FS_IOC32_GETVERSION: cmd =3D FS_IOC_GETVERSION; break; - default: - return -ENOIOCTLCMD; } =20 return btrfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index c658e7b88d58..6479b853c09a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1415,12 +1415,11 @@ static noinline int find_dir_range(struct btrfs_roo= t *root, next: /* check the next slot in the tree to see if it is a valid item */ nritems =3D btrfs_header_nritems(path->nodes[0]); + path->slots[0]++; if (path->slots[0] >=3D nritems) { ret =3D btrfs_next_leaf(root, path); if (ret) goto out; - } else { - path->slots[0]++; } =20 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index b24e2d332767..0432281fb74b 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -238,7 +238,9 @@ static int parse_reply_info_extra(void **p, void *end, struct ceph_mds_reply_info_parsed *info, int features) { - if (info->head->op =3D=3D CEPH_MDS_OP_GETFILELOCK) + u32 op =3D le32_to_cpu(info->head->op); + + if (op =3D=3D CEPH_MDS_OP_GETFILELOCK) return parse_reply_info_filelock(p, end, info, features); else return parse_reply_info_dir(p, end, info, features); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 093a741d965c..274c91b5e9f6 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3829,6 +3829,7 @@ struct inode *ext4_iget(struct super_block *sb, unsig= ned long ino) struct inode *inode; journal_t *journal =3D EXT4_SB(sb)->s_journal; long ret; + loff_t size; int block; =20 inode =3D iget_locked(sb, ino); @@ -3880,6 +3881,11 @@ struct inode *ext4_iget(struct super_block *sb, unsi= gned long ino) ei->i_file_acl |=3D ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; inode->i_size =3D ext4_isize(raw_inode); + if ((size =3D i_size_read(inode)) < 0) { + EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size); + ret =3D -EIO; + goto bad_inode; + } ei->i_disksize =3D inode->i_size; #ifdef CONFIG_QUOTA ei->i_reserved_quota =3D 0; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 242fe11aea20..ebc50aa7347c 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -652,7 +652,7 @@ static void ext4_mb_mark_free_simple(struct super_block= *sb, ext4_grpblk_t min; ext4_grpblk_t max; ext4_grpblk_t chunk; - unsigned short border; + unsigned int border; =20 BUG_ON(len > EXT4_CLUSTERS_PER_GROUP(sb)); =20 @@ -2134,7 +2134,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *s= eq, void *v) struct ext4_buddy e4b; struct sg { struct ext4_group_info info; - ext4_grpblk_t counters[16]; + ext4_grpblk_t counters[EXT4_MAX_BLOCK_LOG_SIZE + 2]; } sg; =20 group--; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e3ccddb6b425..422ed7946c20 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3180,10 +3180,15 @@ static int count_overhead(struct super_block *sb, e= xt4_group_t grp, ext4_set_bit(s++, buf); count++; } - for (j =3D ext4_bg_num_gdb(sb, grp); j > 0; j--) { - ext4_set_bit(EXT4_B2C(sbi, s++), buf); - count++; + j =3D ext4_bg_num_gdb(sb, grp); + if (s + j > EXT4_BLOCKS_PER_GROUP(sb)) { + ext4_error(sb, "Invalid number of block group " + "descriptor blocks: %d", j); + j =3D EXT4_BLOCKS_PER_GROUP(sb) - s; } + count +=3D j; + for (; j > 0; j--) + ext4_set_bit(EXT4_B2C(sbi, s++), buf); } if (!count) return 0; @@ -3240,7 +3245,7 @@ static int ext4_fill_super(struct super_block *sb, vo= id *data, int silent) char *orig_data =3D kstrdup(data, GFP_KERNEL); struct buffer_head *bh; struct ext4_super_block *es =3D NULL; - struct ext4_sb_info *sbi; + struct ext4_sb_info *sbi =3D kzalloc(sizeof(*sbi), GFP_KERNEL); ext4_fsblk_t block; ext4_fsblk_t sb_block =3D get_sb_block(&data); ext4_fsblk_t logical_sb_block; @@ -3260,16 +3265,14 @@ static int ext4_fill_super(struct super_block *sb, = void *data, int silent) unsigned int journal_ioprio =3D DEFAULT_JOURNAL_IOPRIO; ext4_group_t first_not_zeroed; =20 - sbi =3D kzalloc(sizeof(*sbi), GFP_KERNEL); - if (!sbi) - goto out_free_orig; + if ((data && !orig_data) || !sbi) + goto out_free_base; =20 sbi->s_blockgroup_lock =3D kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); - if (!sbi->s_blockgroup_lock) { - kfree(sbi); - goto out_free_orig; - } + if (!sbi->s_blockgroup_lock) + goto out_free_base; + sb->s_fs_info =3D sbi; sbi->s_mount_opt =3D 0; sbi->s_resuid =3D EXT4_DEF_RESUID; @@ -3378,11 +3381,19 @@ static int ext4_fill_super(struct super_block *sb, = void *data, int silent) */ sbi->s_li_wait_mult =3D EXT4_DEF_LI_WAIT_MULT; =20 - if (!parse_options((char *) sbi->s_es->s_mount_opts, sb, - &journal_devnum, &journal_ioprio, NULL, 0)) { - ext4_msg(sb, KERN_WARNING, - "failed to parse options in superblock: %s", - sbi->s_es->s_mount_opts); + if (sbi->s_es->s_mount_opts[0]) { + char *s_mount_opts =3D kstrndup(sbi->s_es->s_mount_opts, + sizeof(sbi->s_es->s_mount_opts), + GFP_KERNEL); + if (!s_mount_opts) + goto failed_mount; + if (!parse_options(s_mount_opts, sb, &journal_devnum, + &journal_ioprio, NULL, 0)) { + ext4_msg(sb, KERN_WARNING, + "failed to parse options in superblock: %s", + s_mount_opts); + } + kfree(s_mount_opts); } if (!parse_options((char *) data, sb, &journal_devnum, &journal_ioprio, NULL, 0)) @@ -3535,12 +3546,16 @@ static int ext4_fill_super(struct super_block *sb, = void *data, int silent) =20 sbi->s_blocks_per_group =3D le32_to_cpu(es->s_blocks_per_group); sbi->s_inodes_per_group =3D le32_to_cpu(es->s_inodes_per_group); - if (EXT4_INODE_SIZE(sb) =3D=3D 0 || EXT4_INODES_PER_GROUP(sb) =3D=3D 0) - goto cantfind_ext4; =20 sbi->s_inodes_per_block =3D blocksize / EXT4_INODE_SIZE(sb); if (sbi->s_inodes_per_block =3D=3D 0) goto cantfind_ext4; + if (sbi->s_inodes_per_group < sbi->s_inodes_per_block || + sbi->s_inodes_per_group > blocksize * 8) { + ext4_msg(sb, KERN_ERR, "invalid inodes per group: %lu\n", + sbi->s_blocks_per_group); + goto failed_mount; + } sbi->s_itb_per_group =3D sbi->s_inodes_per_group / sbi->s_inodes_per_block; sbi->s_desc_per_block =3D blocksize / EXT4_DESC_SIZE(sb); @@ -3619,13 +3634,6 @@ static int ext4_fill_super(struct super_block *sb, v= oid *data, int silent) } sbi->s_cluster_ratio =3D clustersize / blocksize; =20 - if (sbi->s_inodes_per_group > blocksize * 8) { - ext4_msg(sb, KERN_ERR, - "#inodes per group too big: %lu", - sbi->s_inodes_per_group); - goto failed_mount; - } - /* * Test whether we have more sectors than will fit in sector_t, * and whether the max offset is addressable by the page cache. @@ -3978,7 +3986,9 @@ no_journal: descr =3D "out journal"; =20 ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. " - "Opts: %s%s%s", descr, sbi->s_es->s_mount_opts, + "Opts: %.*s%s%s", descr, + (int) sizeof(sbi->s_es->s_mount_opts), + sbi->s_es->s_mount_opts, *sbi->s_es->s_mount_opts ? "; " : "", orig_data); =20 if (es->s_error_count) @@ -4036,8 +4046,8 @@ failed_mount: out_fail: sb->s_fs_info =3D NULL; kfree(sbi->s_blockgroup_lock); +out_free_base: kfree(sbi); -out_free_orig: kfree(orig_data); return ret; } diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 961e562c8a7a..8b8d6a54140c 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -397,7 +397,7 @@ static int nfs_write_end(struct file *file, struct addr= ess_space *mapping, */ if (!PageUptodate(page)) { unsigned pglen =3D nfs_page_length(page); - unsigned end =3D offset + len; + unsigned end =3D offset + copied; =20 if (pglen =3D=3D 0) { zero_user_segments(page, 0, offset, diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index df6daccf49ba..4c633ca8a7df 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c @@ -243,12 +243,10 @@ out: */ void fsnotify_unmount_inodes(struct list_head *list) { - struct inode *inode, *next_i, *need_iput =3D NULL; + struct inode *inode, *iput_inode =3D NULL; =20 spin_lock(&inode_sb_list_lock); - list_for_each_entry_safe(inode, next_i, list, i_sb_list) { - struct inode *need_iput_tmp; - + list_for_each_entry(inode, list, i_sb_list) { /* * We cannot __iget() an inode in state I_FREEING, * I_WILL_FREE, or I_NEW which is fine because by that point @@ -271,50 +269,24 @@ void fsnotify_unmount_inodes(struct list_head *list) continue; } =20 - need_iput_tmp =3D need_iput; - need_iput =3D NULL; - - /* In case fsnotify_inode_delete() drops a reference. */ - if (inode !=3D need_iput_tmp) - __iget(inode); - else - need_iput_tmp =3D NULL; + __iget(inode); spin_unlock(&inode->i_lock); - - /* In case the dropping of a reference would nuke next_i. */ - while (&next_i->i_sb_list !=3D list) { - spin_lock(&next_i->i_lock); - if (!(next_i->i_state & (I_FREEING | I_WILL_FREE)) && - atomic_read(&next_i->i_count)) { - __iget(next_i); - need_iput =3D next_i; - spin_unlock(&next_i->i_lock); - break; - } - spin_unlock(&next_i->i_lock); - next_i =3D list_entry(next_i->i_sb_list.next, - struct inode, i_sb_list); - } - - /* - * We can safely drop inode_sb_list_lock here because either - * we actually hold references on both inode and next_i or - * end of list. Also no new inodes will be added since the - * umount has begun. - */ spin_unlock(&inode_sb_list_lock); =20 - if (need_iput_tmp) - iput(need_iput_tmp); + if (iput_inode) + iput(iput_inode); =20 /* for each watch, send FS_UNMOUNT and then remove it */ fsnotify(inode, FS_UNMOUNT, inode, FSNOTIFY_EVENT_INODE, NULL, 0); =20 fsnotify_inode_delete(inode); =20 - iput(inode); + iput_inode =3D inode; =20 spin_lock(&inode_sb_list_lock); } spin_unlock(&inode_sb_list_lock); + + if (iput_inode) + iput(iput_inode); } diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 6465317e47a6..9ab2acca5a84 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -3270,6 +3270,16 @@ static int ocfs2_downconvert_lock(struct ocfs2_super= *osb, mlog(ML_BASTS, "lockres %s, level %d =3D> %d\n", lockres->l_name, lockres->l_level, new_level); =20 + /* + * On DLM_LKF_VALBLK, fsdlm behaves differently with o2cb. It always + * expects DLM_LKF_VALBLK being set if the LKB has LVB, so that + * we can recover correctly from node failure. Otherwise, we may get + * invalid LVB in LKB, but without DLM_SBF_VALNOTVALID=C2=A0being set. + */ + if (!ocfs2_is_o2cb_active() && + lockres->l_ops->flags & LOCK_TYPE_USES_LVB) + lvb =3D 1; + if (lvb) dlm_flags |=3D DLM_LKF_VALBLK; =20 diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c index 39abf89697ed..88610b3cbc04 100644 --- a/fs/ocfs2/stackglue.c +++ b/fs/ocfs2/stackglue.c @@ -48,6 +48,12 @@ static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] =3D= "/sbin/ocfs2_hb_ctl"; */ static struct ocfs2_stack_plugin *active_stack; =20 +inline int ocfs2_is_o2cb_active(void) +{ + return !strcmp(active_stack->sp_name, OCFS2_STACK_PLUGIN_O2CB); +} +EXPORT_SYMBOL_GPL(ocfs2_is_o2cb_active); + static struct ocfs2_stack_plugin *ocfs2_stack_lookup(const char *name) { struct ocfs2_stack_plugin *p; diff --git a/fs/ocfs2/stackglue.h b/fs/ocfs2/stackglue.h index 1ec56fdb8d0d..fa49d8a1dc7b 100644 --- a/fs/ocfs2/stackglue.h +++ b/fs/ocfs2/stackglue.h @@ -289,4 +289,7 @@ void ocfs2_stack_glue_set_max_proto_version(struct ocfs= 2_protocol_version *max_p int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin); void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin); =20 +/* In ocfs2_downconvert_lock(), we need to know which stack we are using */ +int ocfs2_is_o2cb_active(void); + #endif /* STACKGLUE_H */ diff --git a/fs/splice.c b/fs/splice.c index 459128ba084a..4cf2cba02dfd 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -214,6 +214,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe, buf->len =3D spd->partial[page_nr].len; buf->private =3D spd->partial[page_nr].private; buf->ops =3D spd->ops; + buf->flags =3D 0; if (spd->flags & SPLICE_F_GIFT) buf->flags |=3D PIPE_BUF_FLAG_GIFT; =20 diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 066738647685..f996cb52442b 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -34,6 +34,11 @@ #include #include "ubifs.h" =20 +static int try_read_node(const struct ubifs_info *c, void *buf, int type, + int len, int lnum, int offs); +static int fallible_read_node(struct ubifs_info *c, const union ubifs_key = *key, + struct ubifs_zbranch *zbr, void *node); + /* * Returned codes of 'matches_name()' and 'fallible_matches_name()' functi= ons. * @NAME_LESS: name corresponding to the first argument is less than second @@ -420,7 +425,19 @@ static int tnc_read_node_nm(struct ubifs_info *c, stru= ct ubifs_zbranch *zbr, return 0; } =20 - err =3D ubifs_tnc_read_node(c, zbr, node); + if (c->replaying) { + err =3D fallible_read_node(c, &zbr->key, zbr, node); + /* + * When the node was not found, return -ENOENT, 0 otherwise. + * Negative return codes stay as-is. + */ + if (err =3D=3D 0) + err =3D -ENOENT; + else if (err =3D=3D 1) + err =3D 0; + } else { + err =3D ubifs_tnc_read_node(c, zbr, node); + } if (err) return err; =20 @@ -2785,7 +2802,11 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ub= ifs_info *c, if (nm->name) { if (err) { /* Handle collisions */ - err =3D resolve_collision(c, key, &znode, &n, nm); + if (c->replaying) + err =3D fallible_resolve_collision(c, key, &znode, &n, + nm, 0); + else + err =3D resolve_collision(c, key, &znode, &n, nm); dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); if (unlikely(err < 0)) diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 654dc6f05bac..911367741c89 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -210,6 +210,7 @@ xfs_swap_extents( int error =3D 0; int aforkblks =3D 0; int taforkblks =3D 0; + xfs_extnum_t nextents; __uint64_t tmp; =20 tempifp =3D kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); @@ -394,7 +395,8 @@ xfs_swap_extents( * pointer. Otherwise it's already NULL or * pointing to the extent. */ - if (ip->i_d.di_nextents <=3D XFS_INLINE_EXTS) { + nextents =3D ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + if (nextents <=3D XFS_INLINE_EXTS) { ifp->if_u1.if_extents =3D ifp->if_u2.if_inline_ext; } @@ -413,7 +415,8 @@ xfs_swap_extents( * pointer. Otherwise it's already NULL or * pointing to the extent. */ - if (tip->i_d.di_nextents <=3D XFS_INLINE_EXTS) { + nextents =3D tip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t); + if (nextents <=3D XFS_INLINE_EXTS) { tifp->if_u1.if_extents =3D tifp->if_u2.if_inline_ext; } diff --git a/include/linux/can/core.h b/include/linux/can/core.h index 0ccc1cd28b95..e03fddb15846 100644 --- a/include/linux/can/core.h +++ b/include/linux/can/core.h @@ -45,10 +45,9 @@ struct can_proto { extern int can_proto_register(const struct can_proto *cp); extern void can_proto_unregister(const struct can_proto *cp); =20 -extern int can_rx_register(struct net_device *dev, canid_t can_id, - canid_t mask, - void (*func)(struct sk_buff *, void *), - void *data, char *ident); +int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, + void (*func)(struct sk_buff *, void *), + void *data, char *ident, struct sock *sk); =20 extern void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask, diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 9c3e071900c0..21b1e9789a80 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -112,22 +112,16 @@ enum { { .notifier_call =3D fn, .priority =3D pri }; \ register_cpu_notifier(&fn##_nb); \ } -#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */ -#define cpu_notifier(fn, pri) do { (void)(fn); } while (0) -#endif /* #else #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */ -#ifdef CONFIG_HOTPLUG_CPU extern int register_cpu_notifier(struct notifier_block *nb); extern void unregister_cpu_notifier(struct notifier_block *nb); -#else =20 -#ifndef MODULE -extern int register_cpu_notifier(struct notifier_block *nb); -#else +#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */ +#define cpu_notifier(fn, pri) do { (void)(fn); } while (0) + static inline int register_cpu_notifier(struct notifier_block *nb) { return 0; } -#endif =20 static inline void unregister_cpu_notifier(struct notifier_block *nb) { diff --git a/include/linux/list.h b/include/linux/list.h index cc6d2aa6b415..7690738b39e7 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -362,6 +362,17 @@ static inline void list_splice_tail_init(struct list_h= ead *list, list_entry((ptr)->next, type, member) =20 /** + * list_first_entry_or_null - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note that if the list is empty, it returns NULL. + */ +#define list_first_entry_or_null(ptr, type, member) \ + (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL) + +/** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4b04097c748c..ee2821315c43 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1676,14 +1676,19 @@ static inline int skb_gro_header_hard(struct sk_buf= f *skb, unsigned int hlen) return NAPI_GRO_CB(skb)->frag0_len < hlen; } =20 +static inline void skb_gro_frag0_invalidate(struct sk_buff *skb) +{ + NAPI_GRO_CB(skb)->frag0 =3D NULL; + NAPI_GRO_CB(skb)->frag0_len =3D 0; +} + static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int = hlen, unsigned int offset) { if (!pskb_may_pull(skb, hlen)) return NULL; =20 - NAPI_GRO_CB(skb)->frag0 =3D NULL; - NAPI_GRO_CB(skb)->frag0_len =3D 0; + skb_gro_frag0_invalidate(skb); return skb->data + offset; } =20 diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h index a8c2ef6d3b93..9078b31d336f 100644 --- a/include/net/cipso_ipv4.h +++ b/include/net/cipso_ipv4.h @@ -303,6 +303,10 @@ static inline int cipso_v4_validate(const struct sk_bu= ff *skb, } =20 for (opt_iter =3D 6; opt_iter < opt_len;) { + if (opt_iter + 1 =3D=3D opt_len) { + err_offset =3D opt_iter; + goto out; + } tag_len =3D opt[opt_iter + 1]; if ((tag_len =3D=3D 0) || (opt[opt_iter + 1] > (opt_len - opt_iter))) { err_offset =3D opt_iter + 1; diff --git a/include/net/sock.h b/include/net/sock.h index 1444b523264b..ba673a1e787f 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -961,7 +961,7 @@ static inline struct inode *SOCK_INODE(struct socket *s= ocket) * Functions for memory accounting */ extern int __sk_mem_schedule(struct sock *sk, int size, int kind); -extern void __sk_mem_reclaim(struct sock *sk); +void __sk_mem_reclaim(struct sock *sk, int amount); =20 #define SK_MEM_QUANTUM ((int)PAGE_SIZE) #define SK_MEM_QUANTUM_SHIFT ilog2(SK_MEM_QUANTUM) @@ -1000,7 +1000,7 @@ static inline void sk_mem_reclaim(struct sock *sk) if (!sk_has_account(sk)) return; if (sk->sk_forward_alloc >=3D SK_MEM_QUANTUM) - __sk_mem_reclaim(sk); + __sk_mem_reclaim(sk, sk->sk_forward_alloc); } =20 static inline void sk_mem_reclaim_partial(struct sock *sk) @@ -1008,7 +1008,7 @@ static inline void sk_mem_reclaim_partial(struct sock= *sk) if (!sk_has_account(sk)) return; if (sk->sk_forward_alloc > SK_MEM_QUANTUM) - __sk_mem_reclaim(sk); + __sk_mem_reclaim(sk, sk->sk_forward_alloc - 1); } =20 static inline void sk_mem_charge(struct sock *sk, int size) @@ -1023,6 +1023,16 @@ static inline void sk_mem_uncharge(struct sock *sk, = int size) if (!sk_has_account(sk)) return; sk->sk_forward_alloc +=3D size; + + /* Avoid a possible overflow. + * TCP send queues can make this happen, if sk_mem_reclaim() + * is not called and more than 2 GBytes are released at once. + * + * If we reach 2 MBytes, reclaim 1 MBytes right now, there is + * no need to hold that much forward allocation anyway. + */ + if (unlikely(sk->sk_forward_alloc >=3D 1 << 21)) + __sk_mem_reclaim(sk, 1 << 20); } =20 static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) @@ -1117,6 +1127,7 @@ extern struct sk_buff *sock_rmalloc(struct sock *sk, gfp_t priority); extern void sock_wfree(struct sk_buff *skb); extern void sock_rfree(struct sk_buff *skb); +void sock_efree(struct sk_buff *skb); =20 extern int sock_setsockopt(struct socket *sock, int level, int op, char __user *optval, diff --git a/ipc/shm.c b/ipc/shm.c index 16b1f9ec0398..df1d6085396f 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -963,8 +963,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shm= flg, ulong *raddr) goto out; else if ((addr =3D (ulong)shmaddr)) { if (addr & (SHMLBA-1)) { - if (shmflg & SHM_RND) - addr &=3D ~(SHMLBA-1); /* round down */ + /* + * Round down to the nearest multiple of shmlba. + * For sane do_mmap_pgoff() parameters, avoid + * round downs that trigger nil-page and MAP_FIXED. + */ + if ((shmflg & SHM_RND) && addr >=3D SHMLBA) + addr &=3D ~(SHMLBA - 1); else #ifndef __ARCH_FORCE_SHMLBA if (addr & ~PAGE_MASK) diff --git a/kernel/cpu.c b/kernel/cpu.c index 82c91f1b715a..f735a58bf7b4 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -176,12 +176,6 @@ static int cpu_notify(unsigned long val, void *v) return __cpu_notify(val, v, -1, NULL); } =20 -#ifdef CONFIG_HOTPLUG_CPU - -static void cpu_notify_nofail(unsigned long val, void *v) -{ - BUG_ON(cpu_notify(val, v)); -} EXPORT_SYMBOL(register_cpu_notifier); =20 void __ref unregister_cpu_notifier(struct notifier_block *nb) @@ -192,6 +186,13 @@ void __ref unregister_cpu_notifier(struct notifier_blo= ck *nb) } EXPORT_SYMBOL(unregister_cpu_notifier); =20 +#ifdef CONFIG_HOTPLUG_CPU + +static void cpu_notify_nofail(unsigned long val, void *v) +{ + BUG_ON(cpu_notify(val, v)); +} + static inline void check_for_tasks(int cpu) { struct task_struct *p; diff --git a/kernel/futex.c b/kernel/futex.c index 9dc2c7192b2e..d82fdbb65856 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -2904,4 +2904,4 @@ static int __init futex_init(void) =20 return 0; } -__initcall(futex_init); +core_initcall(futex_init); diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 8f3d1453082d..cb0d862b8a2e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -2554,6 +2554,7 @@ static int __do_proc_doulongvec_minmax(void *data, st= ruct ctl_table *table, int break; if (neg) continue; + val =3D convmul * val / convdiv; if ((min && val < *min) || (max && val > *max)) continue; *i =3D val; diff --git a/lib/vsprintf.c b/lib/vsprintf.c index ae02e421b75f..77d1314cd146 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1177,7 +1177,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt= , va_list args) =20 /* Reject out-of-range values early. Large positive sizes are used for unknown buffer sizes. */ - if (WARN_ON_ONCE((int) size < 0)) + if (WARN_ON_ONCE(size > INT_MAX)) return 0; =20 str =3D buf; diff --git a/mm/filemap.c b/mm/filemap.c index f2f52478dd75..d038bb568a8c 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1117,6 +1117,11 @@ static void do_generic_file_read(struct file *filp, = loff_t *ppos, =20 cond_resched(); find_page: + if (fatal_signal_pending(current)) { + error =3D -EINTR; + goto out; + } + page =3D find_get_page(mapping, index); if (!page) { page_cache_sync_readahead(mapping, diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 2fde51669cd9..998efcee7201 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -964,6 +964,18 @@ out: return ret; } =20 +/* + * FOLL_FORCE can write to even unwritable pmd's, but only + * after we've gone through a COW cycle and they are dirty. + */ +static inline bool can_follow_write_pmd(pmd_t pmd, struct page *page, + unsigned int flags) +{ + return pmd_write(pmd) || + ((flags & FOLL_FORCE) && (flags & FOLL_COW) && + page && PageAnon(page)); +} + struct page *follow_trans_huge_pmd(struct mm_struct *mm, unsigned long addr, pmd_t *pmd, @@ -973,11 +985,12 @@ struct page *follow_trans_huge_pmd(struct mm_struct *= mm, =20 assert_spin_locked(&mm->page_table_lock); =20 - if (flags & FOLL_WRITE && !pmd_write(*pmd)) - goto out; - page =3D pmd_page(*pmd); VM_BUG_ON(!PageHead(page)); + + if (flags & FOLL_WRITE && !can_follow_write_pmd(*pmd, page, flags)) + goto out; + if (flags & FOLL_TOUCH) { pmd_t _pmd; /* diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index ea0e15c7ea17..d011c219da7a 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -21,18 +21,19 @@ #include #include "br_private.h" =20 -/* called with RTNL */ static int get_bridge_ifindices(struct net *net, int *indices, int num) { struct net_device *dev; int i =3D 0; =20 - for_each_netdev(net, dev) { + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { if (i >=3D num) break; if (dev->priv_flags & IFF_EBRIDGE) indices[i++] =3D dev->ifindex; } + rcu_read_unlock(); =20 return i; } diff --git a/net/can/af_can.c b/net/can/af_can.c index 7d9dff2227d1..3ddc74960959 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -403,6 +403,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id= , canid_t *mask, * @func: callback function on filter match * @data: returned parameter for callback function * @ident: string for calling module indentification + * @sk: socket pointer (might be NULL) * * Description: * Invokes the callback function with the received sk_buff and the given @@ -426,7 +427,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id= , canid_t *mask, */ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask, void (*func)(struct sk_buff *, void *), void *data, - char *ident) + char *ident, struct sock *sk) { struct receiver *r; struct hlist_head *rl; @@ -454,6 +455,7 @@ int can_rx_register(struct net_device *dev, canid_t can= _id, canid_t mask, r->func =3D func; r->data =3D data; r->ident =3D ident; + r->sk =3D sk; =20 hlist_add_head_rcu(&r->list, rl); d->entries++; @@ -478,8 +480,11 @@ EXPORT_SYMBOL(can_rx_register); static void can_rx_delete_receiver(struct rcu_head *rp) { struct receiver *r =3D container_of(rp, struct receiver, rcu); + struct sock *sk =3D r->sk; =20 kmem_cache_free(rcv_cache, r); + if (sk) + sock_put(sk); } =20 /** @@ -558,8 +563,11 @@ void can_rx_unregister(struct net_device *dev, canid_t= can_id, canid_t mask, spin_unlock(&can_rcvlists_lock); =20 /* schedule the receiver item for deletion */ - if (r) + if (r) { + if (r->sk) + sock_hold(r->sk); call_rcu(&r->rcu, can_rx_delete_receiver); + } } EXPORT_SYMBOL(can_rx_unregister); =20 diff --git a/net/can/af_can.h b/net/can/af_can.h index fd882dbadad3..4bb812597bf6 100644 --- a/net/can/af_can.h +++ b/net/can/af_can.h @@ -50,13 +50,14 @@ =20 struct receiver { struct hlist_node list; - struct rcu_head rcu; canid_t can_id; canid_t mask; unsigned long matches; void (*func)(struct sk_buff *, void *); void *data; char *ident; + struct sock *sk; + struct rcu_head rcu; }; =20 enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_EFF, RX_MAX }; diff --git a/net/can/bcm.c b/net/can/bcm.c index c297974311b3..47171b2b1233 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -702,14 +702,23 @@ static struct bcm_op *bcm_find_op(struct list_head *o= ps, canid_t can_id, =20 static void bcm_remove_op(struct bcm_op *op) { - hrtimer_cancel(&op->timer); - hrtimer_cancel(&op->thrtimer); - - if (op->tsklet.func) - tasklet_kill(&op->tsklet); + if (op->tsklet.func) { + while (test_bit(TASKLET_STATE_SCHED, &op->tsklet.state) || + test_bit(TASKLET_STATE_RUN, &op->tsklet.state) || + hrtimer_active(&op->timer)) { + hrtimer_cancel(&op->timer); + tasklet_kill(&op->tsklet); + } + } =20 - if (op->thrtsklet.func) - tasklet_kill(&op->thrtsklet); + if (op->thrtsklet.func) { + while (test_bit(TASKLET_STATE_SCHED, &op->thrtsklet.state) || + test_bit(TASKLET_STATE_RUN, &op->thrtsklet.state) || + hrtimer_active(&op->thrtimer)) { + hrtimer_cancel(&op->thrtimer); + tasklet_kill(&op->thrtsklet); + } + } =20 if ((op->frames) && (op->frames !=3D &op->sframe)) kfree(op->frames); @@ -1165,7 +1174,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head= , struct msghdr *msg, err =3D can_rx_register(dev, op->can_id, REGMASK(op->can_id), bcm_rx_handler, op, - "bcm"); + "bcm", sk); =20 op->rx_reg_dev =3D dev; dev_put(dev); @@ -1174,7 +1183,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head= , struct msghdr *msg, } else err =3D can_rx_register(NULL, op->can_id, REGMASK(op->can_id), - bcm_rx_handler, op, "bcm"); + bcm_rx_handler, op, "bcm", sk); if (err) { /* this bcm rx op is broken -> remove it */ list_del(&op->list); diff --git a/net/can/gw.c b/net/can/gw.c index f78f8985e082..0ba45149e4e5 100644 --- a/net/can/gw.c +++ b/net/can/gw.c @@ -405,7 +405,7 @@ static inline int cgw_register_filter(struct cgw_job *g= wj) { return can_rx_register(gwj->src.dev, gwj->ccgw.filter.can_id, gwj->ccgw.filter.can_mask, can_can_gw_rcv, - gwj, "gw"); + gwj, "gw", NULL); } =20 static inline void cgw_unregister_filter(struct cgw_job *gwj) diff --git a/net/can/raw.c b/net/can/raw.c index 7320197b8ea7..2f430cb51216 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -158,7 +158,7 @@ static int raw_enable_filters(struct net_device *dev, s= truct sock *sk, for (i =3D 0; i < count; i++) { err =3D can_rx_register(dev, filter[i].can_id, filter[i].can_mask, - raw_rcv, sk, "raw"); + raw_rcv, sk, "raw", sk); if (err) { /* clean up successfully registered filters */ while (--i >=3D 0) @@ -179,7 +179,7 @@ static int raw_enable_errfilter(struct net_device *dev,= struct sock *sk, =20 if (err_mask) err =3D can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG, - raw_rcv, sk, "raw"); + raw_rcv, sk, "raw", sk); =20 return err; } diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index e85a8d24abf3..dbca8a788c5c 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1350,6 +1350,19 @@ static int process_connect(struct ceph_connection *c= on) =20 dout("process_connect on %p tag %d\n", con, (int)con->in_tag); =20 + if (con->auth_reply_buf) { + /* + * Any connection that defines ->get_authorizer() + * should also define ->verify_authorizer_reply(). + * See get_connect_authorizer(). + */ + ret =3D con->ops->verify_authorizer_reply(con, 0); + if (ret < 0) { + con->error_msg =3D "bad authorize reply"; + return ret; + } + } + switch (con->in_reply.tag) { case CEPH_MSGR_TAG_FEATURES: pr_err("%s%lld %s feature set mismatch," diff --git a/net/core/dev.c b/net/core/dev.c index ec299588f45a..164958d192a3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1918,7 +1918,7 @@ int skb_checksum_help(struct sk_buff *skb) goto out; } =20 - *(__sum16 *)(skb->data + offset) =3D csum_fold(csum); + *(__sum16 *)(skb->data + offset) =3D csum_fold(csum) ?: CSUM_MANGLED_0; out_set_summed: skb->ip_summed =3D CHECKSUM_NONE; out: @@ -3627,7 +3627,9 @@ void skb_gro_reset_offset(struct sk_buff *skb) !PageHighMem(skb_frag_page(&skb_shinfo(skb)->frags[0]))) { NAPI_GRO_CB(skb)->frag0 =3D skb_frag_address(&skb_shinfo(skb)->frags[0]); - NAPI_GRO_CB(skb)->frag0_len =3D skb_frag_size(&skb_shinfo(skb)->frags[0]= ); + NAPI_GRO_CB(skb)->frag0_len =3D min_t(unsigned int, + skb_frag_size(&skb_shinfo(skb)->frags[0]), + skb->end - skb->tail); } } EXPORT_SYMBOL(skb_gro_reset_offset); diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 1d9a52929bad..32b2fa449d77 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -77,6 +77,7 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_= dm_data *data) struct nlattr *nla; struct sk_buff *skb; unsigned long flags; + void *msg_header; =20 al =3D sizeof(struct net_dm_alert_msg); al +=3D dm_hit_limit * sizeof(struct net_dm_drop_point); @@ -84,21 +85,41 @@ static struct sk_buff *reset_per_cpu_data(struct per_cp= u_dm_data *data) =20 skb =3D genlmsg_new(al, GFP_KERNEL); =20 - if (skb) { - genlmsg_put(skb, 0, 0, &net_drop_monitor_family, - 0, NET_DM_CMD_ALERT); - nla =3D nla_reserve(skb, NLA_UNSPEC, - sizeof(struct net_dm_alert_msg)); - msg =3D nla_data(nla); - memset(msg, 0, al); - } else { - mod_timer(&data->send_timer, jiffies + HZ / 10); + if (!skb) + goto err; + + msg_header =3D genlmsg_put(skb, 0, 0, &net_drop_monitor_family, + 0, NET_DM_CMD_ALERT); + if (!msg_header) { + nlmsg_free(skb); + skb =3D NULL; + goto err; + } + nla =3D nla_reserve(skb, NLA_UNSPEC, + sizeof(struct net_dm_alert_msg)); + if (!nla) { + nlmsg_free(skb); + skb =3D NULL; + goto err; } + msg =3D nla_data(nla); + memset(msg, 0, al); + goto out; =20 +err: + mod_timer(&data->send_timer, jiffies + HZ / 10); +out: spin_lock_irqsave(&data->lock, flags); swap(data->skb, skb); spin_unlock_irqrestore(&data->lock, flags); =20 + if (skb) { + struct nlmsghdr *nlh =3D (struct nlmsghdr *)skb->data; + struct genlmsghdr *gnlh =3D (struct genlmsghdr *)nlmsg_data(nlh); + + genlmsg_end(skb, genlmsg_data(gnlh)); + } + return skb; } =20 diff --git a/net/core/sock.c b/net/core/sock.c index 07c078e3f570..a1a3a507c4c4 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1259,6 +1259,7 @@ struct sock *sk_clone(const struct sock *sk, const gf= p_t priority) } =20 newsk->sk_err =3D 0; + newsk->sk_err_soft =3D 0; newsk->sk_priority =3D 0; /* * Before updating sk_refcnt, we must commit prior changes to memory @@ -1369,6 +1370,11 @@ void sock_rfree(struct sk_buff *skb) } EXPORT_SYMBOL(sock_rfree); =20 +void sock_efree(struct sk_buff *skb) +{ + sock_put(skb->sk); +} +EXPORT_SYMBOL(sock_efree); =20 int sock_i_uid(struct sock *sk) { @@ -1745,14 +1751,15 @@ EXPORT_SYMBOL(__sk_mem_schedule); /** * __sk_reclaim - reclaim memory_allocated * @sk: socket + * @amount: number of bytes (rounded down to a SK_MEM_QUANTUM multiple) */ -void __sk_mem_reclaim(struct sock *sk) +void __sk_mem_reclaim(struct sock *sk, int amount) { struct proto *prot =3D sk->sk_prot; =20 - atomic_long_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT, - prot->memory_allocated); - sk->sk_forward_alloc &=3D SK_MEM_QUANTUM - 1; + amount >>=3D SK_MEM_QUANTUM_SHIFT; + atomic_long_sub(amount, prot->memory_allocated); + sk->sk_forward_alloc -=3D amount << SK_MEM_QUANTUM_SHIFT; =20 if (prot->memory_pressure && *prot->memory_pressure && (atomic_long_read(prot->memory_allocated) < prot->sysctl_mem[0])) diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index d336501f3451..98607e19533e 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -211,7 +211,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) { const struct iphdr *iph =3D (struct iphdr *)skb->data; const u8 offset =3D iph->ihl << 2; - const struct dccp_hdr *dh =3D (struct dccp_hdr *)(skb->data + offset); + const struct dccp_hdr *dh; struct dccp_sock *dp; struct inet_sock *inet; const int type =3D icmp_hdr(skb)->type; @@ -221,11 +221,13 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) int err; struct net *net =3D dev_net(skb->dev); =20 - if (skb->len < offset + sizeof(*dh) || - skb->len < offset + __dccp_basic_hdr_len(dh)) { - ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS); - return; - } + /* Only need dccph_dport & dccph_sport which are the first + * 4 bytes in dccp header. + * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us. + */ + BUILD_BUG_ON(offsetof(struct dccp_hdr, dccph_sport) + sizeof(dh->dccph_sp= ort) > 8); + BUILD_BUG_ON(offsetof(struct dccp_hdr, dccph_dport) + sizeof(dh->dccph_dp= ort) > 8); + dh =3D (struct dccp_hdr *)(skb->data + offset); =20 sk =3D inet_lookup(net, &dccp_hashinfo, iph->daddr, dh->dccph_dport, @@ -728,6 +730,7 @@ int dccp_invalid_packet(struct sk_buff *skb) { const struct dccp_hdr *dh; unsigned int cscov; + u8 dccph_doff; =20 if (skb->pkt_type !=3D PACKET_HOST) return 1; @@ -749,18 +752,19 @@ int dccp_invalid_packet(struct sk_buff *skb) /* * If P.Data Offset is too small for packet type, drop packet and return */ - if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { - DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff); + dccph_doff =3D dh->dccph_doff; + if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { + DCCP_WARN("P.Data Offset(%u) too small\n", dccph_doff); return 1; } /* * If P.Data Offset is too too large for packet, drop packet and return */ - if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) { - DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff); + if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) { + DCCP_WARN("P.Data Offset(%u) too large\n", dccph_doff); return 1; } - + dh =3D dccp_hdr(skb); /* * If P.type is not Data, Ack, or DataAck and P.X =3D=3D 0 (the packet * has short sequence numbers), drop packet and return diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index b00bc115a2f0..e10d8512d431 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -83,7 +83,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6= _skb_parm *opt, u8 type, u8 code, int offset, __be32 info) { const struct ipv6hdr *hdr =3D (const struct ipv6hdr *)skb->data; - const struct dccp_hdr *dh =3D (struct dccp_hdr *)(skb->data + offset); + const struct dccp_hdr *dh; struct dccp_sock *dp; struct ipv6_pinfo *np; struct sock *sk; @@ -91,12 +91,13 @@ static void dccp_v6_err(struct sk_buff *skb, struct ine= t6_skb_parm *opt, __u64 seq; struct net *net =3D dev_net(skb->dev); =20 - if (skb->len < offset + sizeof(*dh) || - skb->len < offset + __dccp_basic_hdr_len(dh)) { - ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), - ICMP6_MIB_INERRORS); - return; - } + /* Only need dccph_dport & dccph_sport which are the first + * 4 bytes in dccp header. + * Our caller (icmpv6_notify()) already pulled 8 bytes for us. + */ + BUILD_BUG_ON(offsetof(struct dccp_hdr, dccph_sport) + sizeof(dh->dccph_sp= ort) > 8); + BUILD_BUG_ON(offsetof(struct dccp_hdr, dccph_dport) + sizeof(dh->dccph_dp= ort) > 8); + dh =3D (struct dccp_hdr *)(skb->data + offset); =20 sk =3D inet6_lookup(net, &dccp_hashinfo, &hdr->daddr, dh->dccph_dport, diff --git a/net/dccp/proto.c b/net/dccp/proto.c index e742f90a6858..bd3ecdd67121 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -1012,6 +1012,10 @@ void dccp_close(struct sock *sk, long timeout) __kfree_skb(skb); } =20 + /* If socket has been already reset kill it. */ + if (sk->sk_state =3D=3D DCCP_CLOSED) + goto adjudge_to_death; + if (data_was_unread) { /* Unread data was tossed, send an appropriate Reset Code */ DCCP_WARN("ABORT with %u bytes unread\n", data_was_unread); diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 94f4ec036669..bb516bbfb1b7 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -998,10 +998,13 @@ source_ok: if (!fld.daddr) { fld.daddr =3D fld.saddr; =20 - err =3D -EADDRNOTAVAIL; if (dev_out) dev_put(dev_out); + err =3D -EINVAL; dev_out =3D init_net.loopback_dev; + if (!dev_out->dn_ptr) + goto out; + err =3D -EADDRNOTAVAIL; dev_hold(dev_out); if (!fld.daddr) { fld.daddr =3D @@ -1074,6 +1077,8 @@ source_ok: if (dev_out =3D=3D NULL) goto out; dn_db =3D rcu_dereference_raw(dev_out->dn_ptr); + if (!dn_db) + goto e_inval; /* Possible improvement - check all devices for local addr */ if (dn_dev_islocal(dev_out, fld.daddr)) { dev_put(dev_out); @@ -1115,6 +1120,8 @@ select_source: dev_put(dev_out); dev_out =3D init_net.loopback_dev; dev_hold(dev_out); + if (!dev_out->dn_ptr) + goto e_inval; fld.flowidn_oif =3D dev_out->ifindex; if (res.fi) dn_fib_info_put(res.fi); diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index dbec8b5a9d8a..a8c5d2c4e345 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -1649,6 +1649,10 @@ int cipso_v4_validate(const struct sk_buff *skb, uns= igned char **option) goto validate_return_locked; } =20 + if (opt_iter + 1 =3D=3D opt_len) { + err_offset =3D opt_iter; + goto validate_return_locked; + } tag_len =3D tag[1]; if (tag_len > (opt_len - opt_iter)) { err_offset =3D opt_iter + 1; diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 24f69a0cebfa..0a35f0846142 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -140,7 +140,7 @@ time_before(jiffies, (in_dev)->mr_v2_seen))) =20 static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list = *im); -static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); +static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list = *im); static void igmpv3_clear_delrec(struct in_device *in_dev); static int sf_setstate(struct ip_mc_list *pmc); static void sf_markstate(struct ip_mc_list *pmc); @@ -197,9 +197,14 @@ static void igmp_start_timer(struct ip_mc_list *im, in= t max_delay) static void igmp_gq_start_timer(struct in_device *in_dev) { int tv =3D net_random() % in_dev->mr_maxdelay; + unsigned long exp =3D jiffies + tv + 2; + + if (in_dev->mr_gq_running && + time_after_eq(exp, (in_dev->mr_gq_timer).expires)) + return; =20 in_dev->mr_gq_running =3D 1; - if (!mod_timer(&in_dev->mr_gq_timer, jiffies+tv+2)) + if (!mod_timer(&in_dev->mr_gq_timer, exp)) in_dev_hold(in_dev); } =20 @@ -1077,10 +1082,14 @@ static void igmpv3_add_delrec(struct in_device *in_= dev, struct ip_mc_list *im) spin_unlock_bh(&in_dev->mc_tomb_lock); } =20 -static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr) +/* + * restore ip_mc_list deleted records + */ +static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list = *im) { struct ip_mc_list *pmc, *pmc_prev; - struct ip_sf_list *psf, *psf_next; + struct ip_sf_list *psf; + __be32 multiaddr =3D im->multiaddr; =20 spin_lock_bh(&in_dev->mc_tomb_lock); pmc_prev =3D NULL; @@ -1096,16 +1105,27 @@ static void igmpv3_del_delrec(struct in_device *in_= dev, __be32 multiaddr) in_dev->mc_tomb =3D pmc->next; } spin_unlock_bh(&in_dev->mc_tomb_lock); + + spin_lock_bh(&im->lock); if (pmc) { - for (psf=3Dpmc->tomb; psf; psf=3Dpsf_next) { - psf_next =3D psf->sf_next; - kfree(psf); + im->interface =3D pmc->interface; + im->crcount =3D in_dev->mr_qrv ?: IGMP_Unsolicited_Report_Count; + im->sfmode =3D pmc->sfmode; + if (pmc->sfmode =3D=3D MCAST_INCLUDE) { + im->tomb =3D pmc->tomb; + im->sources =3D pmc->sources; + for (psf =3D im->sources; psf; psf =3D psf->sf_next) + psf->sf_crcount =3D im->crcount; } in_dev_put(pmc->interface); kfree(pmc); } + spin_unlock_bh(&im->lock); } =20 +/* + * flush ip_mc_list deleted records + */ static void igmpv3_clear_delrec(struct in_device *in_dev) { struct ip_mc_list *pmc, *nextpmc; @@ -1250,7 +1270,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32= addr) rcu_assign_pointer(in_dev->mc_list, im); =20 #ifdef CONFIG_IP_MULTICAST - igmpv3_del_delrec(in_dev, im->multiaddr); + igmpv3_del_delrec(in_dev, im); #endif igmp_group_added(im); if (!in_dev->dead) @@ -1340,8 +1360,12 @@ void ip_mc_remap(struct in_device *in_dev) =20 ASSERT_RTNL(); =20 - for_each_pmc_rtnl(in_dev, pmc) + for_each_pmc_rtnl(in_dev, pmc) { +#ifdef CONFIG_IP_MULTICAST + igmpv3_del_delrec(in_dev, pmc); +#endif igmp_group_added(pmc); + } } =20 /* Device going down */ @@ -1362,7 +1386,6 @@ void ip_mc_down(struct in_device *in_dev) in_dev->mr_gq_running =3D 0; if (del_timer(&in_dev->mr_gq_timer)) __in_dev_put(in_dev); - igmpv3_clear_delrec(in_dev); #endif =20 ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS); @@ -1397,8 +1420,12 @@ void ip_mc_up(struct in_device *in_dev) =20 ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS); =20 - for_each_pmc_rtnl(in_dev, pmc) + for_each_pmc_rtnl(in_dev, pmc) { +#ifdef CONFIG_IP_MULTICAST + igmpv3_del_delrec(in_dev, pmc); +#endif igmp_group_added(pmc); + } } =20 /* @@ -1413,13 +1440,13 @@ void ip_mc_destroy_dev(struct in_device *in_dev) =20 /* Deactivate timers */ ip_mc_down(in_dev); +#ifdef CONFIG_IP_MULTICAST + igmpv3_clear_delrec(in_dev); +#endif =20 while ((i =3D rtnl_dereference(in_dev->mc_list)) !=3D NULL) { in_dev->mc_list =3D i->next_rcu; in_dev->mc_count--; - - /* We've dropped the groups in ip_mc_down already */ - ip_mc_clear_src(i); ip_ma_put(i); } } diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 6558a9182793..86af7fe49240 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -830,8 +830,10 @@ static struct mfc_cache *ipmr_cache_alloc(void) { struct mfc_cache *c =3D kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); =20 - if (c) + if (c) { + c->mfc_un.res.last_assert =3D jiffies - MFC_ASSERT_THRESH - 1; c->mfc_un.res.minvif =3D MAXVIFS; + } return c; } =20 diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index cf479f2d1e8c..94248624e261 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -452,6 +452,8 @@ static int ping_push_pending_frames(struct sock *sk, st= ruct pingfakehdr *pfh, { struct sk_buff *skb =3D skb_peek(&sk->sk_write_queue); =20 + if (!skb) + return 0; pfh->wcheck =3D csum_partial((char *)&pfh->icmph, sizeof(struct icmphdr), pfh->wcheck); pfh->icmph.checksum =3D csum_fold(pfh->wcheck); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 3026b65f9a84..d3e45fcb7c33 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2604,6 +2604,18 @@ static struct rtable *__mkroute_output(const struct = fib_result *res, */ if (fi && res->prefixlen < 4) fi =3D NULL; + } else if ((type =3D=3D RTN_LOCAL) && (orig_oif !=3D 0) && + (orig_oif !=3D dev_out->ifindex)) { + /* For local routes that require a particular output interface + * we do not want to cache the result. Caching the result + * causes incorrect behaviour when there are multiple source + * addresses on the interface, the end result being that if the + * intended recipient is waiting on that interface for the + * packet he won't receive it because it will be delivered on + * the loopback interface and the IP_PKTINFO ipi_ifindex will + * be set to the loopback interface as well. + */ + fi =3D NULL; } =20 rth =3D rt_dst_alloc(dev_out, diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 918ecd724c1b..1c96e9b25e58 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1680,12 +1680,14 @@ static int tcp_mtu_probe(struct sock *sk) len =3D 0; tcp_for_write_queue_from_safe(skb, next, sk) { copy =3D min_t(int, skb->len, probe_size - len); - if (nskb->ip_summed) + if (nskb->ip_summed) { skb_copy_bits(skb, 0, skb_put(nskb, copy), copy); - else - nskb->csum =3D skb_copy_and_csum_bits(skb, 0, - skb_put(nskb, copy), - copy, nskb->csum); + } else { + __wsum csum =3D skb_copy_and_csum_bits(skb, 0, + skb_put(nskb, copy), + copy, 0); + nskb->csum =3D csum_block_add(nskb->csum, csum, len); + } =20 if (skb->len <=3D copy) { /* We've eaten all the data from this skb. @@ -1921,9 +1923,11 @@ u32 __tcp_select_window(struct sock *sk) int full_space =3D min_t(int, tp->window_clamp, tcp_full_space(sk)); int window; =20 - if (mss > full_space) + if (unlikely(mss > full_space)) { mss =3D full_space; - + if (mss <=3D 0) + return 0; + } if (free_space < (full_space >> 1)) { icsk->icsk_ack.quick =3D 0; =20 @@ -2097,7 +2101,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buf= f *skb) * copying overhead: fragmentation, tunneling, mangling etc. */ if (atomic_read(&sk->sk_wmem_alloc) > - min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf)) + min_t(u32, sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), + sk->sk_sndbuf)) return -EAGAIN; =20 if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) { diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 79eceab4637a..9a851d16beda 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4355,8 +4355,7 @@ static void addrconf_disable_change(struct net *net, = __s32 newf) struct net_device *dev; struct inet6_dev *idev; =20 - rcu_read_lock(); - for_each_netdev_rcu(net, dev) { + for_each_netdev(net, dev) { idev =3D __in6_dev_get(dev); if (idev) { int changed =3D (!idev->cnf.disable_ipv6) ^ (!newf); @@ -4365,7 +4364,6 @@ static void addrconf_disable_change(struct net *net, = __s32 newf) dev_disable_change(idev); } } - rcu_read_unlock(); } =20 static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index d57813783830..86578237ee6c 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -879,6 +879,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff= **head, ops =3D rcu_dereference(inet6_protos[proto]); if (!ops || !ops->gro_receive) { __pskb_pull(skb, skb_gro_offset(skb)); + skb_gro_frag0_invalidate(skb); proto =3D ipv6_gso_pull_exthdrs(skb, proto); skb_gro_pull(skb, -skb_transport_offset(skb)); skb_reset_transport_header(skb); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 741917c3aa5d..08e4edcc52c9 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -372,18 +372,19 @@ ip6_tnl_dev_uninit(struct net_device *dev) static __u16 parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw) { - const struct ipv6hdr *ipv6h =3D (const struct ipv6hdr *) raw; - __u8 nexthdr =3D ipv6h->nexthdr; - __u16 off =3D sizeof (*ipv6h); + const struct ipv6hdr *ipv6h =3D (const struct ipv6hdr *)raw; + unsigned int nhoff =3D raw - skb->data; + unsigned int off =3D nhoff + sizeof(*ipv6h); + u8 next, nexthdr =3D ipv6h->nexthdr; =20 while (ipv6_ext_hdr(nexthdr) && nexthdr !=3D NEXTHDR_NONE) { - __u16 optlen =3D 0; struct ipv6_opt_hdr *hdr; - if (raw + off + sizeof (*hdr) > skb->data && - !pskb_may_pull(skb, raw - skb->data + off + sizeof (*hdr))) + u16 optlen; + + if (!pskb_may_pull(skb, off + sizeof(*hdr))) break; =20 - hdr =3D (struct ipv6_opt_hdr *) (raw + off); + hdr =3D (struct ipv6_opt_hdr *)(skb->data + off); if (nexthdr =3D=3D NEXTHDR_FRAGMENT) { struct frag_hdr *frag_hdr =3D (struct frag_hdr *) hdr; if (frag_hdr->frag_off) @@ -394,20 +395,29 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw) } else { optlen =3D ipv6_optlen(hdr); } + /* cache hdr->nexthdr, since pskb_may_pull() might + * invalidate hdr + */ + next =3D hdr->nexthdr; if (nexthdr =3D=3D NEXTHDR_DEST) { - __u16 i =3D off + 2; + u16 i =3D 2; + + /* Remember : hdr is no longer valid at this point. */ + if (!pskb_may_pull(skb, off + optlen)) + break; + while (1) { struct ipv6_tlv_tnl_enc_lim *tel; =20 /* No more room for encapsulation limit */ - if (i + sizeof (*tel) > off + optlen) + if (i + sizeof(*tel) > optlen) break; =20 - tel =3D (struct ipv6_tlv_tnl_enc_lim *) &raw[i]; + tel =3D (struct ipv6_tlv_tnl_enc_lim *)(skb->data + off + i); /* return index of option if found and valid */ if (tel->type =3D=3D IPV6_TLV_TNL_ENCAP_LIMIT && tel->length =3D=3D 1) - return i; + return i + off - nhoff; /* else jump to next option */ if (tel->type) i +=3D tel->length + 2; @@ -415,7 +425,7 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw) i++; } } - nexthdr =3D hdr->nexthdr; + nexthdr =3D next; off +=3D optlen; } return 0; @@ -894,13 +904,22 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, struct ipv6_tel_txoption opt; struct dst_entry *dst =3D NULL, *ndst =3D NULL; struct net_device *tdev; + bool use_cache =3D false; int mtu; unsigned int max_headroom =3D sizeof(struct ipv6hdr); u8 proto; int err =3D -1; int pkt_len; =20 - if (!fl6->flowi6_mark) + if (!(t->parms.flags & + (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) { + /* enable the cache only only if the routing decision does + * not depend on the current inner header value + */ + use_cache =3D true; + } + + if (use_cache) dst =3D ip6_tnl_dst_check(t); if (!dst) { ndst =3D ip6_route_output(net, NULL, fl6); @@ -959,7 +978,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, skb =3D new_skb; } skb_dst_drop(skb); - if (fl6->flowi6_mark) { + if (!use_cache) { skb_dst_set(skb, dst); ndst =3D NULL; } else { diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 7a3923b3e828..ca306ce1a9f6 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -1022,6 +1022,7 @@ static struct mfc6_cache *ip6mr_cache_alloc(void) struct mfc6_cache *c =3D kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); if (c =3D=3D NULL) return NULL; + c->mfc_un.res.last_assert =3D jiffies - MFC_ASSERT_THRESH - 1; c->mfc_un.res.minvif =3D MAXMIFS; return c; } diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index be5466e3b54f..51a2b9c8f769 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -92,7 +92,7 @@ static void mld_gq_timer_expire(unsigned long data); static void mld_ifc_timer_expire(unsigned long data); static void mld_ifc_event(struct inet6_dev *idev); static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc); -static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *= addr); +static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc); static void mld_clear_delrec(struct inet6_dev *idev); static int sf_setstate(struct ifmcaddr6 *pmc); static void sf_markstate(struct ifmcaddr6 *pmc); @@ -691,9 +691,9 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc) dev_mc_del(dev, buf); } =20 - if (mc->mca_flags & MAF_NOREPORT) - goto done; spin_unlock_bh(&mc->mca_lock); + if (mc->mca_flags & MAF_NOREPORT) + return; =20 if (!mc->idev->dead) igmp6_leave_group(mc); @@ -701,8 +701,6 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc) spin_lock_bh(&mc->mca_lock); if (del_timer(&mc->mca_timer)) atomic_dec(&mc->mca_refcnt); -done: - ip6_mc_clear_src(mc); spin_unlock_bh(&mc->mca_lock); } =20 @@ -747,10 +745,11 @@ static void mld_add_delrec(struct inet6_dev *idev, st= ruct ifmcaddr6 *im) spin_unlock_bh(&idev->mc_lock); } =20 -static void mld_del_delrec(struct inet6_dev *idev, const struct in6_addr *= pmca) +static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im) { struct ifmcaddr6 *pmc, *pmc_prev; - struct ip6_sf_list *psf, *psf_next; + struct ip6_sf_list *psf; + struct in6_addr *pmca =3D &im->mca_addr; =20 spin_lock_bh(&idev->mc_lock); pmc_prev =3D NULL; @@ -767,14 +766,21 @@ static void mld_del_delrec(struct inet6_dev *idev, co= nst struct in6_addr *pmca) } spin_unlock_bh(&idev->mc_lock); =20 + spin_lock_bh(&im->mca_lock); if (pmc) { - for (psf=3Dpmc->mca_tomb; psf; psf=3Dpsf_next) { - psf_next =3D psf->sf_next; - kfree(psf); + im->idev =3D pmc->idev; + im->mca_crcount =3D idev->mc_qrv; + im->mca_sfmode =3D pmc->mca_sfmode; + if (pmc->mca_sfmode =3D=3D MCAST_INCLUDE) { + im->mca_tomb =3D pmc->mca_tomb; + im->mca_sources =3D pmc->mca_sources; + for (psf =3D im->mca_sources; psf; psf =3D psf->sf_next) + psf->sf_crcount =3D im->mca_crcount; } in6_dev_put(pmc->idev); kfree(pmc); } + spin_unlock_bh(&im->mca_lock); } =20 static void mld_clear_delrec(struct inet6_dev *idev) @@ -877,7 +883,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, const struc= t in6_addr *addr) idev->mc_list =3D mc; write_unlock_bh(&idev->lock); =20 - mld_del_delrec(idev, &mc->mca_addr); + mld_del_delrec(idev, mc); igmp6_group_added(mc); ma_put(mc); return 0; @@ -898,6 +904,7 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const str= uct in6_addr *addr) write_unlock_bh(&idev->lock); =20 igmp6_group_dropped(ma); + ip6_mc_clear_src(ma); =20 ma_put(ma); return 0; @@ -2231,18 +2238,20 @@ void ipv6_mc_down(struct inet6_dev *idev) /* Withdraw multicast list */ =20 read_lock_bh(&idev->lock); + + for (i =3D idev->mc_list; i; i=3Di->next) + igmp6_group_dropped(i); + + /* Should stop timer after group drop. or we will + * start timer again in mld_ifc_event() + */ idev->mc_ifc_count =3D 0; if (del_timer(&idev->mc_ifc_timer)) __in6_dev_put(idev); idev->mc_gq_running =3D 0; if (del_timer(&idev->mc_gq_timer)) __in6_dev_put(idev); - - for (i =3D idev->mc_list; i; i=3Di->next) - igmp6_group_dropped(i); read_unlock_bh(&idev->lock); - - mld_clear_delrec(idev); } =20 =20 @@ -2255,8 +2264,10 @@ void ipv6_mc_up(struct inet6_dev *idev) /* Install multicast list, except for all-nodes (already installed) */ =20 read_lock_bh(&idev->lock); - for (i =3D idev->mc_list; i; i=3Di->next) + for (i =3D idev->mc_list; i; i =3D i->next) { + mld_del_delrec(idev, i); igmp6_group_added(i); + } read_unlock_bh(&idev->lock); } =20 @@ -2289,6 +2300,7 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev) =20 /* Deactivate timers */ ipv6_mc_down(idev); + mld_clear_delrec(idev); =20 /* Delete all-nodes address. */ /* We cannot call ipv6_dev_mc_dec() directly, our caller in @@ -2303,11 +2315,9 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev) write_lock_bh(&idev->lock); while ((i =3D idev->mc_list) !=3D NULL) { idev->mc_list =3D i->next; - write_unlock_bh(&idev->lock); =20 - igmp6_group_dropped(i); + write_unlock_bh(&idev->lock); ma_put(i); - write_lock_bh(&idev->lock); } write_unlock_bh(&idev->lock); diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index bebc82108694..ce501a73ebd7 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -576,8 +576,11 @@ static int rawv6_push_pending_frames(struct sock *sk, = struct flowi6 *fl6, } =20 offset +=3D skb_transport_offset(skb); - if (skb_copy_bits(skb, offset, &csum, 2)) - BUG(); + err =3D skb_copy_bits(skb, offset, &csum, 2); + if (err < 0) { + ip6_flush_pending_frames(sk); + goto out; + } =20 /* in case cksum was not initialized */ if (unlikely(csum)) diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c index f06947c4fa82..9f74c9592199 100644 --- a/net/irda/irqueue.c +++ b/net/irda/irqueue.c @@ -385,9 +385,6 @@ EXPORT_SYMBOL(hashbin_new); * for deallocating this structure if it's complex. If not the user can * just supply kfree, which should take care of the job. */ -#ifdef CONFIG_LOCKDEP -static int hashbin_lock_depth =3D 0; -#endif int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func) { irda_queue_t* queue; @@ -398,22 +395,27 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC fre= e_func) IRDA_ASSERT(hashbin->magic =3D=3D HB_MAGIC, return -1;); =20 /* Synchronize */ - if ( hashbin->hb_type & HB_LOCK ) { - spin_lock_irqsave_nested(&hashbin->hb_spinlock, flags, - hashbin_lock_depth++); - } + if (hashbin->hb_type & HB_LOCK) + spin_lock_irqsave(&hashbin->hb_spinlock, flags); =20 /* * Free the entries in the hashbin, TODO: use hashbin_clear when * it has been shown to work */ for (i =3D 0; i < HASHBIN_SIZE; i ++ ) { - queue =3D dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]); - while (queue ) { - if (free_func) - (*free_func)(queue); - queue =3D dequeue_first( - (irda_queue_t**) &hashbin->hb_queue[i]); + while (1) { + queue =3D dequeue_first((irda_queue_t**) &hashbin->hb_queue[i]); + + if (!queue) + break; + + if (free_func) { + if (hashbin->hb_type & HB_LOCK) + spin_unlock_irqrestore(&hashbin->hb_spinlock, flags); + free_func(queue); + if (hashbin->hb_type & HB_LOCK) + spin_lock_irqsave(&hashbin->hb_spinlock, flags); + } } } =20 @@ -422,12 +424,8 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free= _func) hashbin->magic =3D ~HB_MAGIC; =20 /* Release lock */ - if ( hashbin->hb_type & HB_LOCK) { + if (hashbin->hb_type & HB_LOCK) spin_unlock_irqrestore(&hashbin->hb_spinlock, flags); -#ifdef CONFIG_LOCKDEP - hashbin_lock_depth--; -#endif - } =20 /* * Free the hashbin structure diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 439379484bfc..ad6f73d1e34a 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -240,6 +240,7 @@ extern int l2tp_xmit_skb(struct l2tp_session *session, = struct sk_buff *skb, int =20 extern int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2t= p_nl_cmd_ops *ops); extern void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type); +int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg); =20 /* Session reference counts. Incremented when code obtains a reference * to a session. diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 2d9b98ecbd73..eccc008908f4 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -9,6 +9,7 @@ * 2 of the License, or (at your option) any later version. */ =20 +#include #include #include #include @@ -612,6 +613,30 @@ out: return copied; } =20 +int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg) +{ + struct sk_buff *skb; + int amount; + + switch (cmd) { + case SIOCOUTQ: + amount =3D sk_wmem_alloc_get(sk); + break; + case SIOCINQ: + spin_lock_bh(&sk->sk_receive_queue.lock); + skb =3D skb_peek(&sk->sk_receive_queue); + amount =3D skb ? skb->len : 0; + spin_unlock_bh(&sk->sk_receive_queue.lock); + break; + + default: + return -ENOIOCTLCMD; + } + + return put_user(amount, (int __user *)arg); +} +EXPORT_SYMBOL(l2tp_ioctl); + static struct proto l2tp_ip_prot =3D { .name =3D "L2TP/IP", .owner =3D THIS_MODULE, @@ -620,7 +645,7 @@ static struct proto l2tp_ip_prot =3D { .bind =3D l2tp_ip_bind, .connect =3D l2tp_ip_connect, .disconnect =3D l2tp_ip_disconnect, - .ioctl =3D udp_ioctl, + .ioctl =3D l2tp_ioctl, .destroy =3D l2tp_ip_destroy_sock, .setsockopt =3D ip_setsockopt, .getsockopt =3D ip_getsockopt, diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index ba137a6a224d..f3125b92c3e8 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -821,7 +821,10 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_b= uff *skb) * another trick required to cope with how the PROCOM state * machine works. -acme */ + skb_orphan(skb); + sock_hold(sk); skb->sk =3D sk; + skb->destructor =3D sock_efree; } if (!sock_owned_by_user(sk)) llc_conn_rcv(sk, skb); diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 94e7fca75b85..687fe7409e15 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -294,7 +294,10 @@ static void llc_sap_rcv(struct llc_sap *sap, struct sk= _buff *skb, =20 ev->type =3D LLC_SAP_EV_TYPE_PDU; ev->reason =3D 0; + skb_orphan(skb); + sock_hold(sk); skb->sk =3D sk; + skb->destructor =3D sock_efree; llc_sap_state_process(sap, skb); } =20 diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index f85de8ed5859..5fc4249e7f53 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -280,7 +280,7 @@ mesh_add_vendor_ies(struct sk_buff *skb, struct ieee802= 11_sub_if_data *sdata) /* fast-forward to vendor IEs */ offset =3D ieee80211_ie_split_vendor(ifmsh->ie, ifmsh->ie_len, 0); =20 - if (offset) { + if (offset < ifmsh->ie_len) { len =3D ifmsh->ie_len - offset; data =3D ifmsh->ie + offset; if (skb_tailroom(skb) < len) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index dae9476fa4d8..d60ca88c22f8 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1242,6 +1242,8 @@ static void __fanout_link(struct sock *sk, struct pac= ket_sock *po) f->arr[f->num_members] =3D sk; smp_wmb(); f->num_members++; + if (f->num_members =3D=3D 1) + dev_add_pack(&f->prot_hook); spin_unlock(&f->lock); } =20 @@ -1258,6 +1260,8 @@ static void __fanout_unlink(struct sock *sk, struct p= acket_sock *po) BUG_ON(i >=3D f->num_members); f->arr[i] =3D f->arr[f->num_members - 1]; f->num_members--; + if (f->num_members =3D=3D 0) + __dev_remove_pack(&f->prot_hook); spin_unlock(&f->lock); } =20 @@ -1286,13 +1290,16 @@ static int fanout_add(struct sock *sk, u16 id, u16 = type_flags) return -EINVAL; } =20 + mutex_lock(&fanout_mutex); + + err =3D -EINVAL; if (!po->running) - return -EINVAL; + goto out; =20 + err =3D -EALREADY; if (po->fanout) - return -EALREADY; + goto out; =20 - mutex_lock(&fanout_mutex); match =3D NULL; list_for_each_entry(f, &fanout_list, list) { if (f->id =3D=3D id && @@ -1322,7 +1329,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 ty= pe_flags) match->prot_hook.func =3D packet_rcv_fanout; match->prot_hook.af_packet_priv =3D match; match->prot_hook.id_match =3D match_fanout_group; - dev_add_pack(&match->prot_hook); list_add(&match->list, &fanout_list); } err =3D -EINVAL; @@ -1343,24 +1349,29 @@ out: return err; } =20 -static void fanout_release(struct sock *sk) +/* If pkt_sk(sk)->fanout->sk_ref is zero, this function removes + * pkt_sk(sk)->fanout from fanout_list and returns pkt_sk(sk)->fanout. + * It is the responsibility of the caller to call fanout_release_data() and + * free the returned packet_fanout (after synchronize_net()) + */ +static struct packet_fanout *fanout_release(struct sock *sk) { struct packet_sock *po =3D pkt_sk(sk); struct packet_fanout *f; =20 + mutex_lock(&fanout_mutex); f =3D po->fanout; - if (!f) - return; - - po->fanout =3D NULL; + if (f) { + po->fanout =3D NULL; =20 - mutex_lock(&fanout_mutex); - if (atomic_dec_and_test(&f->sk_ref)) { - list_del(&f->list); - dev_remove_pack(&f->prot_hook); - kfree(f); + if (atomic_dec_and_test(&f->sk_ref)) + list_del(&f->list); + else + f =3D NULL; } mutex_unlock(&fanout_mutex); + + return f; } =20 static const struct proto_ops packet_ops; @@ -2383,6 +2394,7 @@ static int packet_release(struct socket *sock) { struct sock *sk =3D sock->sk; struct packet_sock *po; + struct packet_fanout *f; struct net *net; union tpacket_req_u req_u; =20 @@ -2417,9 +2429,12 @@ static int packet_release(struct socket *sock) packet_set_ring(sk, &req_u, 1, 1); } =20 - fanout_release(sk); + f =3D fanout_release(sk); =20 synchronize_net(); + + kfree(f); + /* * Now the socket is dead. No more input will appear. */ diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 10d3aed86560..1a6ecbbd4424 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -120,6 +120,17 @@ static int tcf_pedit_cleanup(struct tc_action *a, int = bind) return 0; } =20 +static bool offset_valid(struct sk_buff *skb, int offset) +{ + if (offset > 0 && offset > skb->len) + return false; + + if (offset < 0 && -offset > skb_headroom(skb)) + return false; + + return true; +} + static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, struct tcf_result *res) { @@ -147,6 +158,11 @@ static int tcf_pedit(struct sk_buff *skb, const struct= tc_action *a, if (tkey->offmask) { char *d, _d; =20 + if (!offset_valid(skb, off + tkey->at)) { + pr_info("tc filter pedit 'at' offset %d out of bounds\n", + off + tkey->at); + goto bad; + } d =3D skb_header_pointer(skb, off + tkey->at, 1, &_d); if (!d) @@ -159,10 +175,10 @@ static int tcf_pedit(struct sk_buff *skb, const struc= t tc_action *a, " offset must be on 32 bit boundaries\n"); goto bad; } - if (offset > 0 && offset > skb->len) { - pr_info("tc filter pedit" - " offset %d can't exceed pkt length %d\n", - offset, skb->len); + + if (!offset_valid(skb, off + offset)) { + pr_info("tc filter pedit offset %d out of bounds\n", + offset); goto bad; } =20 diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index a69d44f1dac5..fecb51097fe5 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -137,9 +137,11 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct = nlmsghdr *n, void *arg) unsigned long cl; unsigned long fh; int err; - int tp_created =3D 0; + int tp_created; =20 replay: + tp_created =3D 0; + t =3D NLMSG_DATA(n); protocol =3D TC_H_MIN(t->tcm_info); prio =3D TC_H_MAJ(t->tcm_info); diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 1363bf14e61b..892f66ac7a89 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -176,11 +176,12 @@ META_COLLECTOR(int_vlan_tag) { unsigned short tag; =20 - tag =3D vlan_tx_tag_get(skb); - if (!tag && __vlan_get_tag(skb, &tag)) - *err =3D -1; - else + if (vlan_tx_tag_present(skb)) + dst->value =3D vlan_tx_tag_get(skb); + else if (!__vlan_get_tag(skb, &tag)) dst->value =3D tag; + else + *err =3D -1; } =20 =20 diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 2c790204d042..d75bfcf972f0 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -260,6 +260,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Q= disc *sch) return err; } =20 + sch->qstats.backlog +=3D qdisc_pkt_len(skb); sch->q.qlen++; =20 return NET_XMIT_SUCCESS; @@ -283,6 +284,7 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) return NULL; =20 qdisc_bstats_update(sch, skb); + sch->qstats.backlog -=3D qdisc_pkt_len(skb); sch->q.qlen--; =20 index =3D skb->tc_index & (p->indices - 1); @@ -398,6 +400,7 @@ static void dsmark_reset(struct Qdisc *sch) =20 pr_debug("dsmark_reset(sch %p,[qdisc %p])\n", sch, p); qdisc_reset(p->q); + sch->qstats.backlog =3D 0; sch->q.qlen =3D 0; } =20 diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index caa5affa4b29..92f0c1f36c1b 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -580,6 +580,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdis= c *sch) htb_activate(q, cl); } =20 + sch->qstats.backlog +=3D qdisc_pkt_len(skb); sch->q.qlen++; return NET_XMIT_SUCCESS; } @@ -867,6 +868,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) ok: qdisc_bstats_update(sch, skb); qdisc_unthrottled(sch); + sch->qstats.backlog -=3D qdisc_pkt_len(skb); sch->q.qlen--; return skb; } @@ -927,6 +929,7 @@ static unsigned int htb_drop(struct Qdisc *sch) unsigned int len; if (cl->un.leaf.q->ops->drop && (len =3D cl->un.leaf.q->ops->drop(cl->un.leaf.q))) { + sch->qstats.backlog -=3D len; sch->q.qlen--; if (!cl->un.leaf.q->q.qlen) htb_deactivate(q, cl); @@ -957,12 +960,12 @@ static void htb_reset(struct Qdisc *sch) } cl->prio_activity =3D 0; cl->cmode =3D HTB_CAN_SEND; - } } qdisc_watchdog_cancel(&q->watchdog); __skb_queue_purge(&q->direct_queue); sch->q.qlen =3D 0; + sch->qstats.backlog =3D 0; memset(q->row, 0, sizeof(q->row)); memset(q->row_mask, 0, sizeof(q->row_mask)); memset(q->wait_pq, 0, sizeof(q->wait_pq)); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 9907e31eb26c..93ea5ac2c7be 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1223,9 +1223,12 @@ static int __sctp_connect(struct sock* sk, =20 timeo =3D sock_sndtimeo(sk, f_flags & O_NONBLOCK); =20 - err =3D sctp_wait_for_connect(asoc, &timeo); - if ((err =3D=3D 0 || err =3D=3D -EINPROGRESS) && assoc_id) + if (assoc_id) *assoc_id =3D asoc->assoc_id; + err =3D sctp_wait_for_connect(asoc, &timeo); + /* Note: the asoc may be freed after the return of + * sctp_wait_for_connect. + */ =20 /* Don't free association on exit. */ asoc =3D NULL; @@ -4193,7 +4196,7 @@ static int sctp_getsockopt_disable_fragments(struct s= ock *sk, int len, static int sctp_getsockopt_events(struct sock *sk, int len, char __user *o= ptval, int __user *optlen) { - if (len <=3D 0) + if (len =3D=3D 0) return -EINVAL; if (len > sizeof(struct sctp_event_subscribe)) len =3D sizeof(struct sctp_event_subscribe); @@ -4239,6 +4242,12 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_associat= ion *asoc, struct sctp_af *af; int err =3D 0; =20 + /* If there is a thread waiting on more sndbuf space for + * sending on this asoc, it cannot be peeled. + */ + if (waitqueue_active(&asoc->wait)) + return -EBUSY; + /* An association cannot be branched off from an already peeled-off * socket, nor is this supported for tcp style sockets. */ @@ -5586,6 +5595,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int = level, int optname, if (get_user(len, optlen)) return -EFAULT; =20 + if (len < 0) + return -EINVAL; + sctp_lock_sock(sk); =20 switch (optname) { @@ -6486,7 +6498,6 @@ static int sctp_wait_for_sndbuf(struct sctp_associati= on *asoc, long *timeo_p, */ sctp_release_sock(sk); current_timeo =3D schedule_timeout(current_timeo); - BUG_ON(sk !=3D asoc->base.sk); sctp_lock_sock(sk); =20 *timeo_p =3D current_timeo; diff --git a/net/socket.c b/net/socket.c index bdcddce2d85d..f9483972b3ef 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1898,7 +1898,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, =20 static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, struct msghdr *msg_sys, unsigned flags, - struct used_address *used_address) + struct used_address *used_address, int *residue) { struct compat_msghdr __user *msg_compat =3D (struct compat_msghdr __user *)msg; @@ -2004,6 +2004,8 @@ static int ___sys_sendmsg(struct socket *sock, struct= msghdr __user *msg, memcpy(&used_address->name, msg_sys->msg_name, used_address->name_len); } + if (residue && err >=3D 0) + *residue =3D total_len - err; =20 out_freectl: if (ctl_buf !=3D ctl) @@ -2029,7 +2031,7 @@ long __sys_sendmsg(int fd, struct msghdr __user *msg,= unsigned flags) if (!sock) goto out; =20 - err =3D ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL); + err =3D ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, NULL); =20 fput_light(sock->file, fput_needed); out: @@ -2056,6 +2058,7 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mms= g, unsigned int vlen, struct compat_mmsghdr __user *compat_entry; struct msghdr msg_sys; struct used_address used_address; + int residue; =20 if (vlen > UIO_MAXIOV) vlen =3D UIO_MAXIOV; @@ -2074,7 +2077,8 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mms= g, unsigned int vlen, while (datagrams < vlen) { if (MSG_CMSG_COMPAT & flags) { err =3D ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, - &msg_sys, flags, &used_address); + &msg_sys, flags, &used_address, + &residue); if (err < 0) break; err =3D __put_user(err, &compat_entry->msg_len); @@ -2082,7 +2086,8 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mms= g, unsigned int vlen, } else { err =3D ___sys_sendmsg(sock, (struct msghdr __user *)entry, - &msg_sys, flags, &used_address); + &msg_sys, flags, &used_address, + &residue); if (err < 0) break; err =3D put_user(err, &entry->msg_len); @@ -2092,6 +2097,8 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mms= g, unsigned int vlen, if (err) break; ++datagrams; + if (residue) + break; } =20 fput_light(sock->file, fput_needed); @@ -2262,8 +2269,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mm= sg, unsigned int vlen, return err; =20 err =3D sock_error(sock->sk); - if (err) + if (err) { + datagrams =3D err; goto out_put; + } =20 entry =3D mmsg; compat_entry =3D (struct compat_mmsghdr __user *)mmsg; diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcaut= h_gss.c index 8d0f7d3c71c8..f7a9906c474b 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -1151,7 +1151,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *au= thp) case RPC_GSS_PROC_DESTROY: if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq)) goto auth_err; - rsci->h.expiry_time =3D get_seconds(); + rsci->h.expiry_time =3D seconds_since_boot(); set_bit(CACHE_NEGATIVE, &rsci->h.flags); if (resv->iov_len + 4 > PAGE_SIZE) goto drop; diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 3b18dd839668..52f9dd64049e 100644 --- a/scripts/kconfig/nconf.gui.c +++ b/scripts/kconfig/nconf.gui.c @@ -364,12 +364,14 @@ int dialog_inputbox(WINDOW *main_window, WINDOW *prompt_win; WINDOW *form_win; PANEL *panel; - int i, x, y; + int i, x, y, lines, columns, win_lines, win_cols; int res =3D -1; int cursor_position =3D strlen(init); int cursor_form_win; char *result =3D *resultp; =20 + getmaxyx(stdscr, lines, columns); + if (strlen(init)+1 > *result_len) { *result_len =3D strlen(init)+1; *resultp =3D result =3D realloc(result, *result_len); @@ -386,14 +388,19 @@ int dialog_inputbox(WINDOW *main_window, if (title) prompt_width =3D max(prompt_width, strlen(title)); =20 + win_lines =3D min(prompt_lines+6, lines-2); + win_cols =3D min(prompt_width+7, columns-2); + prompt_lines =3D max(win_lines-6, 0); + prompt_width =3D max(win_cols-7, 0); + /* place dialog in middle of screen */ - y =3D (LINES-(prompt_lines+4))/2; - x =3D (COLS-(prompt_width+4))/2; + y =3D (lines-win_lines)/2; + x =3D (columns-win_cols)/2; =20 strncpy(result, init, *result_len); =20 /* create the windows */ - win =3D newwin(prompt_lines+6, prompt_width+7, y, x); + win =3D newwin(win_lines, win_cols, y, x); prompt_win =3D derwin(win, prompt_lines+1, prompt_width, 2, 2); form_win =3D derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index e0e683cd3926..9f20d3c24d76 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -421,7 +421,6 @@ int snd_seq_pool_done(struct snd_seq_pool *pool) { unsigned long flags; struct snd_seq_event_cell *ptr; - int max_count =3D 5 * HZ; =20 if (snd_BUG_ON(!pool)) return -EINVAL; @@ -434,14 +433,8 @@ int snd_seq_pool_done(struct snd_seq_pool *pool) if (waitqueue_active(&pool->output_sleep)) wake_up(&pool->output_sleep); =20 - while (atomic_read(&pool->counter) > 0) { - if (max_count =3D=3D 0) { - snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n",= atomic_read(&pool->counter)); - break; - } + while (atomic_read(&pool->counter) > 0) schedule_timeout_uninterruptible(1); - max_count--; - } =09 /* release all resources */ spin_lock_irqsave(&pool->lock, flags); diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 4c9aa462de9b..17fe04d892f9 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -183,6 +183,8 @@ void __exit snd_seq_queues_delete(void) } } =20 +static void queue_use(struct snd_seq_queue *queue, int client, int use); + /* allocate a new queue - * return queue index value or negative value for error */ @@ -194,11 +196,11 @@ int snd_seq_queue_alloc(int client, int locked, unsig= ned int info_flags) if (q =3D=3D NULL) return -ENOMEM; q->info_flags =3D info_flags; + queue_use(q, client, 1); if (queue_list_add(q) < 0) { queue_delete(q); return -ENOMEM; } - snd_seq_queue_use(q->queue, client, 1); /* use this queue */ return q->queue; } =20 @@ -504,19 +506,9 @@ int snd_seq_queue_timer_set_tempo(int queueid, int cli= ent, return result; } =20 - -/* use or unuse this queue - - * if it is the first client, starts the timer. - * if it is not longer used by any clients, stop the timer. - */ -int snd_seq_queue_use(int queueid, int client, int use) +/* use or unuse this queue */ +static void queue_use(struct snd_seq_queue *queue, int client, int use) { - struct snd_seq_queue *queue; - - queue =3D queueptr(queueid); - if (queue =3D=3D NULL) - return -EINVAL; - mutex_lock(&queue->timer_mutex); if (use) { if (!test_and_set_bit(client, queue->clients_bitmap)) queue->clients++; @@ -531,6 +523,21 @@ int snd_seq_queue_use(int queueid, int client, int use) } else { snd_seq_timer_close(queue); } +} + +/* use or unuse this queue - + * if it is the first client, starts the timer. + * if it is not longer used by any clients, stop the timer. + */ +int snd_seq_queue_use(int queueid, int client, int use) +{ + struct snd_seq_queue *queue; + + queue =3D queueptr(queueid); + if (queue =3D=3D NULL) + return -EINVAL; + mutex_lock(&queue->timer_mutex); + queue_use(queue, client, use); mutex_unlock(&queue->timer_mutex); queuefree(queue); return 0; diff --git a/sound/usb/card.c b/sound/usb/card.c index b3ac38991e6e..413b32d6ef35 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -207,7 +207,6 @@ static int snd_usb_create_stream(struct snd_usb_audio *= chip, int ctrlif, int int if (! snd_usb_parse_audio_interface(chip, interface)) { usb_set_interface(dev, interface, 0); /* reset the current interface */ usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); - return -EINVAL; } =20 return 0; diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 2dc90a4a879c..9c36a1ff3172 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -841,9 +841,10 @@ static void volume_control_quirks(struct usb_mixer_ele= m_info *cval, case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */ case USB_ID(0x046d, 0x08ca): /* Logitech Quickcam Fusion */ case USB_ID(0x046d, 0x0991): + case USB_ID(0x046d, 0x09a2): /* QuickCam Communicate Deluxe/S7500 */ /* Most audio usb devices lie about volume resolution. * Most Logitech webcams have res =3D 384. - * Proboly there is some logitech magic behind this number --fishor + * Probably there is some logitech magic behind this number --fishor */ if (!strcmp(kctl->id.name, "Mic Capture Volume")) { snd_printk(KERN_INFO diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trac= e-event-scripting.c index c9dcbec7d800..6ac7d4b3833e 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -88,7 +88,8 @@ static void register_python_scripting(struct scripting_op= s *scripting_ops) if (err) die("error registering py script extension"); =20 - scripting_context =3D malloc(sizeof(struct scripting_context)); + if (scripting_context =3D=3D NULL) + scripting_context =3D malloc(sizeof(*scripting_context)); } =20 #ifdef NO_LIBPYTHON @@ -149,7 +150,8 @@ static void register_perl_scripting(struct scripting_op= s *scripting_ops) if (err) die("error registering pl script extension"); =20 - scripting_context =3D malloc(sizeof(struct scripting_context)); + if (scripting_context =3D=3D NULL) + scripting_context =3D malloc(sizeof(*scripting_context)); } =20 #ifdef NO_LIBPERL --Qn4G1eBrv+t66M9q-- --yKkvi6mMqAM+MlBZ Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUBWMq+hue/yOyVhhEJAQo4Fw/+IWxVaumB2LIhv6O6VuFFiVj5KkItd29W 8vSli+oKwaQFdDTS5/DyEqOyu4MPrlUL2nkaU0SUxyC9+jj+PnrhylbRsoLGn/l3 zBb/tPFr/kOqr+w37HZHXG7SAa0wV7IXVJ5EdR9xlC+NVhu14KWchHWyZv1qco2k Xo3aj2gTHsvIwJREiEoj+Kzb8hB/131MzzNaS0XfQWBZW4TvJYW+iJHQrSNwXnG2 jXOmEcWTIjJytTD3B+dvqK03T3idTDDUujjPwGksCxFfS4+r/8lM0muZ+HCgn+5N OYY7w6Y74z2/yhmq20/uDvJ8Eetk7atwSdUCoe5rWnwF9j99qtoXAjci2Mj9F7uk 4y6bfBbR3j2L6GoYxpQkR71KrYSyFNdRDr2kaJ7UbfZS7xaYNTHEsPZijmIzdr9X BXmNgSSDqvrbbTaIIux6ffiFLFuWC6wKrY5U01hm0NkZQPf93WPRNy5dvzY+0xRZ r98oynXKhTZUScZ/o79jlGc171Q9ydugDRiQPJa2yfNv9E4zbhYT+bQDxdfVL7FJ 3TP3eGLT80X44QaA+BxuwDkWi3gOc+imE827dle5jZZfn0ZEXw84JgQ+05+v87Tz xMwuTv1VTJ9Nnb8bdGR4UmB9xnRhC8xrEhoVIAm8UHhOuzFFOoLteSoub1ByMZYg v3oHQVkSf3Y= =auKi -----END PGP SIGNATURE----- --yKkvi6mMqAM+MlBZ--