From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755004AbdCPQeW (ORCPT ); Thu, 16 Mar 2017 12:34:22 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:34835 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752396AbdCPQeR (ORCPT ); Thu, 16 Mar 2017 12:34:17 -0400 Date: Thu, 16 Mar 2017 16:33:19 +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: <20170316163319.GQ4152@decadent.org.uk> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="Er97KPJOrxRt+yKZ" 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.16.42 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 --Er97KPJOrxRt+yKZ Content-Type: multipart/mixed; boundary="KRJ4yArSHF8vY7I3" Content-Disposition: inline --KRJ4yArSHF8vY7I3 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable I'm announcing the release of the 3.16.42 kernel. (This time with a signed mail.) All users of the 3.16 kernel series should upgrade. The updated 3.16.y git tree can be found at: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable= =2Egit linux-3.16.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.16.41 is attached to this message. Ben. ------------ .../devicetree/bindings/clock/imx31-clock.txt | 2 +- Documentation/virtual/kvm/api.txt | 1 + MAINTAINERS | 4 +- Makefile | 2 +- arch/arc/kernel/unaligned.c | 3 +- arch/arm/boot/dts/da850-evm.dts | 1 + arch/arm/boot/dts/imx31.dtsi | 18 +- arch/arm/boot/dts/imx6q-cm-fx6.dts | 1 - arch/arm/include/asm/cputype.h | 3 + arch/arm/kernel/hw_breakpoint.c | 16 ++ arch/arm/kernel/ptrace.c | 2 +- arch/arm/mach-davinci/da850.c | 12 +- arch/arm/mach-ux500/pm.c | 4 +- arch/arm/mach-zynq/common.c | 2 +- arch/arm/xen/enlighten.c | 3 +- arch/arm64/crypto/aes-ce-ccm-core.S | 53 +++--- arch/arm64/crypto/aes-ce.S | 1 + arch/arm64/crypto/aes-modes.S | 91 +++++----- arch/arm64/crypto/aes-neon.S | 25 +-- arch/arm64/crypto/ghash-ce-core.S | 6 +- arch/arm64/crypto/sha1-ce-core.S | 4 +- arch/arm64/crypto/sha2-ce-core.S | 4 +- arch/arm64/include/uapi/asm/ptrace.h | 1 + arch/arm64/kernel/entry.S | 2 +- arch/arm64/kernel/ptrace.c | 11 +- arch/arm64/kernel/traps.c | 28 ++- arch/cris/boot/rescue/Makefile | 8 + arch/mips/kvm/kvm_mips.c | 4 +- arch/parisc/include/asm/bitops.h | 8 +- arch/parisc/include/uapi/asm/bitsperlong.h | 2 - arch/parisc/include/uapi/asm/swab.h | 5 +- arch/powerpc/boot/ps3-head.S | 5 - arch/powerpc/boot/ps3.c | 8 +- arch/powerpc/boot/wrapper | 24 ++- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/include/asm/ppc-opcode.h | 10 +- arch/powerpc/include/uapi/asm/kvm.h | 1 + arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kernel/ibmebus.c | 16 +- arch/powerpc/kernel/misc_32.S | 2 +- arch/powerpc/kernel/prom_init.c | 3 + arch/powerpc/kernel/ptrace.c | 7 + arch/powerpc/kvm/book3s_hv.c | 6 + arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 + arch/sparc/kernel/leon_kernel.c | 56 +++--- arch/tile/kernel/ptrace.c | 2 +- arch/x86/boot/string.c | 1 + arch/x86/boot/string.h | 9 + arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/entry_32.S | 4 +- arch/x86/kvm/lapic.c | 6 + arch/x86/kvm/lapic.h | 1 + arch/x86/kvm/vmx.c | 10 +- arch/x86/kvm/x86.c | 12 +- arch/x86/pci/acpi.c | 10 ++ 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/bus/vexpress-config.c | 7 +- drivers/clk/clk-wm831x.c | 2 +- drivers/clk/shmobile/clk-mstp.c | 27 ++- drivers/clocksource/exynos_mct.c | 5 + drivers/crypto/caam/caamalg.c | 4 +- drivers/devfreq/devfreq.c | 19 ++- drivers/gpu/drm/ast/ast_main.c | 7 +- drivers/gpu/drm/gma500/psb_drv.c | 3 + drivers/gpu/drm/i915/intel_crt.c | 9 +- drivers/gpu/drm/i915/intel_display.c | 4 +- drivers/gpu/drm/i915/intel_pm.c | 11 +- drivers/gpu/drm/nouveau/dispnv04/hw.c | 3 +- drivers/gpu/drm/radeon/radeon_cursor.c | 56 ++++-- drivers/gpu/drm/radeon/radeon_mode.h | 1 + drivers/gpu/drm/radeon/si_dpm.c | 14 +- drivers/hid/hid-cypress.c | 3 + drivers/hwmon/ds620.c | 2 +- drivers/hwmon/g762.c | 11 +- drivers/i2c/i2c-dev.c | 2 +- drivers/i2c/muxes/i2c-mux-pca954x.c | 5 +- drivers/iio/humidity/dht11.c | 6 +- drivers/infiniband/core/mad.c | 2 +- drivers/infiniband/core/multicast.c | 7 +- drivers/infiniband/core/uverbs_cmd.c | 1 - drivers/infiniband/core/verbs.c | 4 +- drivers/infiniband/hw/cxgb4/device.c | 1 + drivers/infiniband/hw/mlx4/ah.c | 6 +- drivers/infiniband/hw/mlx4/main.c | 30 ++-- drivers/infiniband/hw/mlx4/qp.c | 3 +- drivers/infiniband/hw/mlx5/main.c | 1 + drivers/infiniband/hw/mlx5/mr.c | 28 +++ drivers/infiniband/ulp/ipoib/ipoib_cm.c | 2 - drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 7 +- drivers/input/serio/i8042-x86ia64io.h | 6 + drivers/iommu/amd_iommu.c | 2 +- drivers/isdn/hardware/eicon/message.c | 3 +- drivers/md/dm-crypt.c | 7 +- drivers/md/dm.c | 10 +- drivers/md/md.c | 2 +- drivers/md/persistent-data/dm-space-map-metadata.c | 14 +- drivers/md/raid5.c | 9 + drivers/media/i2c/Kconfig | 1 + drivers/media/platform/davinci/vpfe_capture.c | 1 + drivers/media/rc/ite-cir.c | 2 + drivers/media/usb/siano/smsusb.c | 18 +- drivers/misc/mei/client.c | 20 ++- drivers/mmc/core/mmc.c | 4 +- drivers/mmc/host/mxs-mmc.c | 6 +- drivers/mmc/host/sdhci.c | 23 ++- drivers/mtd/nand/Kconfig | 2 +- drivers/net/bonding/bond_netlink.c | 6 +- drivers/net/can/c_can/c_can_pci.c | 1 + drivers/net/can/ti_hecc.c | 16 +- drivers/net/ethernet/atheros/alx/main.c | 7 +- drivers/net/ethernet/broadcom/bcmsysport.c | 43 +++-- drivers/net/ethernet/cisco/enic/enic_main.c | 18 +- drivers/net/ethernet/emulex/benet/be_cmds.c | 2 +- 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 | 13 +- drivers/net/ethernet/mellanox/mlx4/eq.c | 23 ++- drivers/net/ethernet/mellanox/mlx4/icm.c | 7 +- .../net/ethernet/mellanox/mlx4/resource_tracker.c | 11 +- drivers/net/ethernet/renesas/sh_eth.c | 6 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 20 ++- drivers/net/ethernet/xilinx/xilinx_emaclite.c | 126 +++++++------- drivers/net/hyperv/netvsc_drv.c | 4 + drivers/net/macvtap.c | 4 +- drivers/net/tun.c | 20 ++- drivers/net/usb/catc.c | 56 +++--- drivers/net/usb/cdc_ether.c | 8 + drivers/net/usb/cdc_ncm.c | 7 + drivers/net/usb/pegasus.c | 29 +++- drivers/net/usb/qmi_wwan.c | 7 + drivers/net/usb/r8152.c | 7 +- drivers/net/usb/rtl8150.c | 34 +++- drivers/net/vxlan.c | 8 +- drivers/net/xen-netfront.c | 9 +- drivers/pci/hotplug/rpadlpar_core.c | 10 +- drivers/pci/pci.c | 4 + drivers/platform/x86/intel_mid_powerbtn.c | 2 +- drivers/regulator/stw481x-vmmc.c | 3 +- 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/megaraid/megaraid_sas_fusion.c | 1 + drivers/scsi/mvsas/mv_94xx.c | 2 +- drivers/scsi/qla2xxx/qla_os.c | 16 +- drivers/scsi/scsi_sysfs.c | 4 - drivers/scsi/sg.c | 4 + drivers/ssb/pci.c | 1 + drivers/staging/iio/adc/ad7606_core.c | 2 +- drivers/staging/media/davinci_vpfe/vpfe_video.c | 2 +- drivers/target/iscsi/iscsi_target_tpg.c | 1 - drivers/target/target_core_sbc.c | 8 +- drivers/target/target_core_transport.c | 17 +- drivers/target/target_core_xcopy.c | 2 +- drivers/thermal/thermal_hwmon.c | 2 +- drivers/tty/n_hdlc.c | 143 ++++++++-------- drivers/tty/serial/atmel_serial.c | 11 +- drivers/tty/sysrq.c | 4 +- drivers/usb/class/cdc-acm.c | 1 + drivers/usb/core/config.c | 10 ++ drivers/usb/core/hub.c | 134 ++++++--------- drivers/usb/core/quirks.c | 4 + drivers/usb/dwc3/ep0.c | 37 ++-- drivers/usb/dwc3/gadget.c | 20 ++- drivers/usb/gadget/composite.c | 23 ++- drivers/usb/gadget/dummy_hcd.c | 6 +- drivers/usb/gadget/inode.c | 17 +- drivers/usb/gadget/uvc_video.c | 2 +- drivers/usb/host/uhci-pci.c | 4 + drivers/usb/host/xhci-mem.c | 42 ++++- drivers/usb/host/xhci-pci.c | 3 +- drivers/usb/host/xhci-ring.c | 39 +++-- drivers/usb/host/xhci.c | 13 -- drivers/usb/musb/musbhsdma.h | 2 +- drivers/usb/phy/phy-am335x-control.c | 2 + drivers/usb/serial/ch341.c | 187 +++++++++++++----= ---- drivers/usb/serial/cyberjack.c | 10 ++ drivers/usb/serial/garmin_gps.c | 1 + drivers/usb/serial/io_edgeport.c | 5 + drivers/usb/serial/io_ti.c | 14 +- drivers/usb/serial/iuu_phoenix.c | 11 ++ drivers/usb/serial/keyspan_pda.c | 14 ++ drivers/usb/serial/kl5kusb105.c | 35 +++- drivers/usb/serial/kobil_sct.c | 12 ++ drivers/usb/serial/mos7720.c | 51 +++--- drivers/usb/serial/mos7840.c | 16 +- drivers/usb/serial/omninet.c | 13 ++ drivers/usb/serial/option.c | 8 + drivers/usb/serial/oti6858.c | 16 ++ drivers/usb/serial/pl2303.c | 9 + drivers/usb/serial/pl2303.h | 1 + drivers/usb/serial/qcserial.c | 1 + drivers/usb/serial/quatech2.c | 4 - drivers/usb/serial/spcp8x5.c | 14 ++ drivers/usb/serial/ti_usb_3410_5052.c | 7 + drivers/usb/storage/unusual_devs.h | 7 + drivers/vme/bridges/vme_ca91cx42.c | 2 +- drivers/xen/gntdev.c | 2 +- fs/block_dev.c | 9 +- fs/btrfs/async-thread.c | 14 ++ fs/btrfs/async-thread.h | 1 + fs/btrfs/delayed-inode.c | 15 +- fs/btrfs/extent-tree.c | 5 +- fs/btrfs/ioctl.c | 6 +- fs/btrfs/tree-log.c | 3 +- fs/ceph/mds_client.c | 9 +- fs/cifs/cifsglob.h | 3 + fs/cifs/cifsproto.h | 3 + fs/cifs/connect.c | 34 +++- fs/cifs/smb2file.c | 2 +- fs/cifs/smb2pdu.c | 77 ++++++--- fs/cifs/smb2proto.h | 1 + fs/exec.c | 10 +- fs/ext4/inline.c | 4 +- fs/ext4/inode.c | 6 + fs/ext4/mballoc.c | 4 +- fs/ext4/super.c | 64 ++++--- fs/f2fs/debug.c | 1 + fs/nfs/dir.c | 15 +- fs/nfs/file.c | 2 +- fs/nfs/filelayout/filelayoutdev.c | 3 +- fs/nfs/nfs4state.c | 1 + 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_bmap_util.c | 7 +- fs/xfs/xfs_log_recover.c | 1 + include/linux/can/core.h | 7 +- include/linux/cpu.h | 15 +- include/linux/jump_label_ratelimit.h | 5 + include/linux/netdevice.h | 9 +- include/linux/nfs4.h | 3 +- include/linux/sunrpc/clnt.h | 1 + include/linux/tcp.h | 7 +- include/net/cfg80211.h | 11 ++ include/net/cipso_ipv4.h | 4 + include/net/netfilter/nf_log.h | 2 + include/net/sock.h | 17 +- include/uapi/linux/usb/ch9.h | 19 +++ ipc/shm.c | 13 +- kernel/cpu.c | 13 +- kernel/events/core.c | 42 ++--- kernel/futex.c | 2 +- kernel/jump_label.c | 7 + kernel/printk/printk.c | 2 +- kernel/sched/cputime.c | 3 + kernel/sysctl.c | 1 + kernel/trace/trace_functions_graph.c | 17 +- lib/vsprintf.c | 2 +- mm/filemap.c | 5 + mm/huge_memory.c | 19 ++- mm/hugetlb.c | 37 +++- 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 | 109 ++++++------ net/core/drop_monitor.c | 39 ++++- net/core/sock.c | 16 +- net/dccp/ipv4.c | 26 +-- net/dccp/ipv6.c | 16 +- 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/netfilter/ipt_rpfilter.c | 8 +- net/ipv4/ping.c | 2 + net/ipv4/route.c | 12 ++ net/ipv4/tcp_fastopen.c | 3 +- net/ipv4/tcp_output.c | 21 ++- net/ipv4/udp.c | 2 +- net/ipv6/addrconf.c | 4 +- net/ipv6/ip6_gre.c | 3 + net/ipv6/ip6_offload.c | 1 + net/ipv6/ip6_output.c | 11 +- net/ipv6/ip6_tunnel.c | 49 ++++-- net/ipv6/ip6mr.c | 1 + net/ipv6/mcast.c | 50 +++--- net/ipv6/netfilter/ip6t_rpfilter.c | 8 +- net/ipv6/raw.c | 7 +- net/ipv6/sit.c | 5 +- net/ipv6/udp.c | 2 +- net/irda/irqueue.c | 34 ++-- net/l2tp/l2tp_core.h | 1 + net/l2tp/l2tp_ip.c | 27 ++- net/l2tp/l2tp_ip6.c | 2 +- net/llc/llc_conn.c | 3 + net/llc/llc_sap.c | 3 + net/mac80211/mesh.c | 2 +- net/mac80211/mlme.c | 17 +- net/netfilter/nf_log.c | 1 - net/netfilter/nft_log.c | 3 +- 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/sched/sch_netem.c | 61 ++++++- net/sctp/socket.c | 19 ++- net/socket.c | 19 ++- net/sunrpc/auth_gss/gss_rpc_xdr.c | 2 +- net/sunrpc/auth_gss/svcauth_gss.c | 2 +- net/sunrpc/clnt.c | 5 + net/sunrpc/sunrpc_syms.c | 1 + net/vmw_vsock/af_vsock.c | 21 +-- net/wireless/core.h | 1 + net/wireless/mlme.c | 12 ++ net/wireless/sme.c | 14 ++ scripts/kconfig/nconf.gui.c | 15 +- sound/core/seq/seq_memory.c | 9 +- sound/core/seq/seq_queue.c | 33 ++-- sound/pci/hda/patch_conexant.c | 28 +++ sound/pci/hda/patch_hdmi.c | 1 + sound/pci/hda/patch_realtek.c | 2 + sound/usb/card.c | 1 - sound/usb/hiface/pcm.c | 2 + sound/usb/mixer.c | 3 +- tools/perf/builtin-trace.c | 4 +- tools/perf/util/trace-event-scripting.c | 6 +- tools/testing/selftests/net/run_netsocktests | 2 +- .../powerpc/pmu/ebb/pmc56_overflow_test.c | 2 +- 339 files changed, 3027 insertions(+), 1429 deletions(-) Adrian Hunter (1): mmc: sdhci: Fix recovery from tuning timeout 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 Aleksa Sarai (1): fs: exec: apply CLOEXEC before changing dumpable task flags Aleksander Morgado (1): USB: serial: qcserial: add Dell DW5570 QDL Alex Deucher (2): drm/radeon: add additional pci revision to dpm workaround drm/radeon: drop verde dpm quirks Alex Porosanu (1): crypto: caam - fix AEAD givenc descriptors Alexander Popov (1): tty: n_hdlc: get rid of racy n_hdlc.tbuf Alexander Usyskin (1): mei: move write cb to completion on credentials failures Alexey Kodanev (1): tcp: initialize max window for a new fastopen socket Amir Vadai (1): net/sched: pedit: make sure that offset is valid Ander Conselvan de Oliveira (1): drm/i915: Don't leak edid in intel_crt_detect_ddc() Andrew Collins (1): net: Add netdev all_adj_list refcnt propagation to fix panic Andrey Ryabinin (1): drm/i915: fix use-after-free in page_flip_completed() 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 (3): mmc: core: fix multi-bit bus width without high-speed mode net: xilinx_emaclite: fix receive buffer overflow net: xilinx_emaclite: fix freezes due to unordered I/O Anton Blanchard (1): powerpc: Ignore reserved field in DCSR and PVR reads and writes Ard Biesheuvel (7): crypto: arm64/ghash-ce - fix for big endian crypto: arm64/sha1-ce - fix for big endian crypto: arm64/sha2-ce - fix for big endian crypto: arm64/aes-ccm-ce: fix for big endian crypto: arm64/aes-neon - fix for big endian crypto: arm64/aes-xts-ce: fix for big endian crypto: arm64/aes-blk - honour iv_out requirement in CBC and CTR modes Arnaldo Carvalho de Melo (2): perf trace: Use the syscall raw_syscalls:sys_enter timestamp perf scripting: Avoid leaking the scripting_context variable Arnd Bergmann (5): scsi: mvsas: fix command_active typo DaVinci-VPFE-Capture: fix error handling s5k4ecgx: select CRC32 helper ARM: ux500: fix prcmu_is_cpu_in_wfi() calculation ISDN: eicon: silence misleading array-bounds warning 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 Axel Lin (1): PM / devfreq: Add proper locking around list_del() Baolin Wang (1): usb: host: xhci: Fix possible wild pointer when handling abort command Bart Van Assche (4): dm rq: fix a race condition in rq_completed() IB/mad: Fix an array index check IPoIB: Avoid reading an uninitialized member variable IB/multicast: Check ib_find_pkey() return value Bartosz Golaszewski (1): ARM: davinci: da850: don't add emac clock to lookup table twice Ben Hutchings (8): kconfig/nconf: Fix hang when editing symbol with a long prompt pegasus: Use heap buffers for all register access 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.16.42 Beniamino Galvani (1): bonding: set carrier off for devices created through netlink Benjamin Block (1): scsi: zfcp: fix use-after-"free" in FC ingress path after TMF Benjamin Marzinski (1): dm space map metadata: fix 'struct sm_metadata' leak on failed create Benjamin Poirier (1): mlx4: Invoke softirqs after napi_reschedule Bjorn Helgaas (1): x86/PCI: Ignore _CRS on Supermicro X8DTH-i/6/iF/6F Bj=C3=B8rn Mork (3): USB: serial: option: add device ID for HP lt2523 (Novatel E371) cdc_ncm: workaround for EM7455 "silent" data interface qmi_wwan/cdc_ether: add device ID for HP lt2523 (Novatel E371) WWAN c= ard Boris Ostrovsky (2): xen/gntdev: Use VM_MIXEDMAP instead of VM_IO to avoid NUMA balancing 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 Chanwoo Choi (1): PM / devfreq: Fix the bug of devfreq_add_device when governor is NULL Chris Brandt (1): clk: renesas: mstp: Support 8-bit registers for r7s72100 Chris Friesen (1): route: do not cache fib route info on local routes with oif Christopher Spinrath (1): ARM: dts: imx6q-cm-fx6: fix fec pinctrl Chuck Lever (2): nfs: Don't increment lock sequence ID after NFS4ERR_MOVED nfs: Fix "Don't increment lock sequence ID after NFS4ERR_MOVED" Con Kolivas (1): ALSA: usb-audio: Add QuickCam Communicate Deluxe/S7500 to volume_cont= rol_quirks Dan Carpenter (6): usb: xhci-mem: use passed in GFP flags instead of GFP_KERNEL staging: media: davinci_vpfe: unlock on error in vpfe_reqbufs() ext4: return -ENOMEM instead of success 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 Daniel Dressler (1): Btrfs: delayed-inode: replace root args iff only fs_info used Daniele Palmas (1): USB: serial: option: add support for Telit LE922A PIDs 0x1040, 0x1041 Darren Stevens (1): powerpc: Add missing error check to prom_find_boot_cpu() Darrick J. Wong (2): ext4: reject inodes with negative size xfs: update MAINTAINERS Dave Jones (1): ipv6: handle -EFAULT from skb_copy_bits Dave Martin (6): tile/ptrace: Preserve previous registers for short regset write arm64/ptrace: Preserve previous registers for short regset write arm64/ptrace: Avoid uninitialised struct padding in fpr_set() arm64/ptrace: Reject attempts to set incomplete hardware breakpoint f= ields powerpc/ptrace: Preserve previous fprs/vsrs on short regset write ARM: 8643/3: arm/ptrace: Preserve previous registers for short regset= write David Henningsson (1): ALSA: hda - Add inverted internal mic for Asus Aspire 4830T David Matlack (2): jump_labels: API for flushing deferred jump label updates KVM: x86: flush pending lapic jump label updates on module unload 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 Einar J=C3=B3n (1): can: c_can_pci: fix null-pointer-deref in c_can_start() - set device = pointer Eli Cohen (1): IB/mlx5: Wait for all async command completions to complete Eran Ben Elisha (1): IB/mlx4: When no DMFS for IPoIB, don't allow NET_IF QPs Eric Dumazet (22): gro: use min_t() in skb_gro_reset_offset() net: fix harmonize_features() vs NETIF_F_HIGHDMA ip6_tunnel: must reload ipv6h in ip6ip6_tnl_xmit() sysctl: fix proc_doulongvec_ms_jiffies_minmax() net: use a work queue to defer net_disable_timestamp() work 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() ipv6: dccp: add missing bind_conflict to dccp_ipv6_mapped 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 (2): xfs: fix up xfs_swap_extent_forks inline extent handling xfs: set AGI buffer type in xlog_recover_clear_agi_bucket Eugenia Emantayev (1): net/mlx4_en: Fix bad WQE issue Eva Rachel Retuya (1): staging: iio: ad7606: fix improper setting of oversampling pins Fabien Parent (1): ARM: dts: da850-evm: fix read access to SPI flash Felipe Balbi (7): usb: gadget: composite: correctly initialize ep->maxpacket usb: add helper to extract bits 12:11 of wMaxPacketSize usb: gadget: composite: always set ep->mult to a sensible value usb: dwc3: gadget: set PCM1 field of isochronous-first TRBs usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() usb: dwc3: ep0: explicitly call dwc3_ep0_prepare_one_trb() usb: dwc3: gadget: always unmap EP0 requests Feng Tang (1): net: alx: Work around the DMA RX overflow issue Florian Fainelli (6): drivers: base: dma-mapping: Fix typo in dmam_alloc_non_coherent comme= nts net: korina: Fix NAPI versus resources freeing net: stmmac: Fix race between stmmac_drv_probe and stmmac_open net: stmmac: Fix error path after register_netdev move net: systemport: Pad packet before inserting TSB net: systemport: Decouple flow control from __bcm_sysport_tx_reclaim Gabriel Krisman Bertazi (1): mmc: sdhci: Ignore unexpected CARD_INT interrupts Geert Uytterhoeven (1): usb: hub: Move hub_port_disable() to fix warning if PM is disabled Geliang Tang (1): fs/notify/inode_mark.c: use list_next_entry in fsnotify_unmount_inodes Geoff Levand (1): powerpc/ps3: Fix system hang with GCC 5 builds Gerald Schaefer (1): s390/vmlogrdr: fix IUCV buffer allocation Giuseppe Lippolis (1): USB: serial: option: add dlink dwm-158 Govindarajulu Varadarajan (1): enic: set skb->hash type properly Greg Kroah-Hartman (2): usb: gadgetfs: restrict upper bound on device configuration size HID: hid-cypress: validate length of report Guenter Roeck (3): cris: Only build flash rescue image if CONFIG_ETRAX_AXISFLASHMAP is s= elected hwmon: (ds620) Fix overflows seen when writing temperature limits hwmon: (g762) Fix overflows and crash seen when writing limit attribu= tes 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() Hannes Frederic Sowa (1): udp: prevent skbs lingering in tunnel socket queues Hans de Goede (1): drm/i915/dsi: Do not clear DPOUNIT_CLOCK_GATE_DISABLE from vlv_init_d= isplay_clock_gating Hauke Mehrtens (1): mtd: nand: xway: disable module support 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 Hiroshi Shimamoto (1): sched/cputime: Fix invalid gtime in proc Huang Rui (1): iommu/amd: Fix the left value check of cmd buffer Hui Wang (1): ALSA: hda - adding a new NV HDMI/DP codec ID in the driver Ian Campbell (1): VSOCK: do not disconnect socket when peer has shutdown SEND only Ilia Mirkin (1): drm/nouveau/nv1a,nv1f/disp: fix memory clock rate retrieval Ilya Dryomov (1): libceph: verify authorize reply on connect Ivan Vecera (1): be2net: fix status check in be_cmd_pmac_add() J. Bruce Fields (2): svcrpc: don't leak contexts on PROC_DESTROY svcrpc: fix oops in absence of krb5 module Jack Morgenstein (5): IB/mlx4: Fix out-of-range array index in destroy qp flow net/mlx4_core: Use-after-free causes a resource leak in flow-steering= detach net/mlx4_core: Fix racy CQ (Completion Queue) free net/mlx4_core: Fix when to save some qp context flags for dynamic VST= to VGT transitions net/mlx4_core: Eliminate warning messages for SRQ_LIMIT under SRIOV Jakub Sitnicki (1): ipv6: Skip XFRM lookup if dst_entry in socket cache is valid James Hogan (1): KVM: MIPS: Flush KVM entry code from icache globally 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 (3): btrfs: fix error handling when run_delayed_extent_op fails btrfs: fix locking when we put back a delayed ref that's too new 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 Slaby (2): net: sctp, forbid negative length TTY: n_hdlc, fix lockdep false positive Johan Hovold (34): powerpc/ibmebus: Fix device reference leaks in sysfs interface powerpc/ibmebus: Fix further device reference leaks powerpc/pci/rpadlpar: Fix device reference leaks USB: phy: am335x-control: fix device and of_node leaks USB: serial: kl5kusb105: fix open error path bus: vexpress-config: fix device reference leak 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: quatech2: fix sleep-while-atomic in close USB: serial: spcp8x5: fix NULL-deref at open USB: serial: ti_usb_3410_5052: fix NULL-deref at open 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 Johannes Berg (1): cfg80211/mac80211: fix BSS leaks when abandoning assoc attempts John Brooks (1): iio: dht11: Use usleep_range instead of msleep for start signal Joonyoung Shim (1): clocksource/exynos_mct: Clear interrupt when cpu is shut down Josef Bacik (1): nbd: only set MSG_MORE when we have more to send Julien Grall (1): arm/xen: Use alloc_percpu rather than __alloc_percpu Jussi Laako (1): ALSA: hiface: Fix M2Tech hiFace driver sampling rate change Kamal Heib (1): IB/IPoIB: Remove can't use GFP_NOIO warning Kashyap Desai (1): scsi: megaraid_sas: For SRIOV enabled firmware, ensure VF driver wait= s for 30secs before reset 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 Kinglong Mee (1): SUNRPC: cleanup ida information when removing sunrpc module Kirtika Ruchandani (1): regmap: cache: Remove unused 'blksize' variable Konstantin Khlebnikov (1): md/raid5: limit request size according to implementation limits 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() Kyle Roeschley (1): ARM: zynq: Reserve correct amount of non-DMA RAM Larry Finger (2): ssb: Fix error routine when fallback SPROM fails powerpc: Fix build warning on 32-bit PPC Leon Romanovsky (1): net/mlx4: Remove BUG_ON from ICM allocation routine Linus Walleij (1): regulator: stw481x-vmmc: fix ages old enable error Liping Zhang (2): netfilter: rpfilter: fix incorrect loopback packet judgment netfilter: nft_log: restrict the log prefix length to 127 Lu Baolu (2): usb: xhci: fix possible wild pointer usb: xhci: hold lock over xhci_abort_cmd_ring() 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 Madhavan Srinivasan (1): selftest/powerpc: Wrong PMC initialized in pmc56_overflow test Maor Gottlieb (3): IB/mlx5: Put non zero value in max_ah IB/mlx4: Set traffic class in AH 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 Bloch (1): IB/core: Save QP in ib_flow structure Mark Rutland (2): ARM: 8634/1: hw_breakpoint: blacklist Scorpion CPUs arm64: avoid returning from bad_mode Mathias Nyman (4): usb: hub: Fix auto-remount of safely removed or ejected USB-3 devices xhci: free xhci virtual devices with leaf nodes first xhci: Handle command completion and timeout race xhci: fix deadlock at host remove by running watchdog correctly Mauro Carvalho Chehab (1): siano: make it work again with CONFIG_VMAP_STACK Maxim Patlasov (1): btrfs: limit async_work allocation and worker func duration 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 Michel D=C3=A4nzer (2): drm/radeon: Hide the HW cursor while it's out of bounds drm/radeon: Use mode h/vdisplay fields to hide out of bounds HW cursor Mike Kravetz (1): mm/hugetlb.c: fix reservation race when freeing surplus pages 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 Neil Horman (1): netem: Segment GSO packets on enqueue NeilBrown (2): block_dev: don't test bdev->bd_contains when it is not stable NFSv4.1: nfs4_fl_prepare_ds must be careful about reporting success. Nicholas Bellinger (3): target: Use correct SCSI status during EXTENDED_COPY exception target: Fix early transport_generic_handle_tmr abort scenario target: Fix COMPARE_AND_WRITE ref leak for non GOOD status Nicholas Mc Guire (1): x86/boot: Add missing declaration of string functions Nicholas Piggin (1): powerpc/boot: Request no dynamic linker for boot wrapper Nicolai Stange (1): f2fs: set ->owner for debugfs status file's file_operations 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 Oliver Neukum (1): usb: storage: unusual_uas: Add JMicron JMS56x to unusual device Ondrej Kozina (1): dm crypt: mark key as invalid until properly loaded Pan Bian (2): USB: serial: kl5kusb105: abort on open exception path clk: clk-wm831x: fix a logic error Paolo Abeni (1): ip6_tunnel: disable caching when the traffic class is inherited Paolo Bonzini (1): kvm: fix page struct leak in handle_vmon Patrik Jakobsson (1): drm/gma500: Add compat ioctl Paul Mackerras (1): KVM: PPC: Book3S HV: Save/restore XER in checkpointed register state Pavel Shilovsky (3): CIFS: Fix missing nls unload in smb2_reconnect() CIFS: Fix a possible memory corruption in push locks CIFS: Fix a possible memory corruption during reconnect Peter Zijlstra (1): perf/core: Fix PERF_RECORD_MMAP2 prot/flags for anonymous memory Quinn Tran (1): qla2xxx: Fix crash due to null pointer access Rabin Vincent (1): block: protect iterate_bdevs() against concurrent close 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 Genoud (1): tty/serial: atmel: RS485 half duplex w/DMA: enable RX after TX is done Richard Weinberger (1): ubifs: Fix journal replay wrt. xattr nodes Robbie Ko (1): Btrfs: fix tree search logic when replaying directory entry deletes Rolf Eike Beer (1): selftests: do not require bash to run netsocktests testcase Russell Currey (1): drivers/gpu/drm/ast: Fix infinite loop if read fails Russell King (1): i2c: mux: pca954x: fix i2c mux selection caching Saeed Mahameed (1): IB/mlx4: Fix port query for 56Gb Ethernet links Salvatore Benedetto (1): crypto: api - Clear CRYPTO_ALG_DEAD bit before registering an alg Sergei Shtylyov (3): sh_eth: enable RX descriptor word 0 shift on SH7734 sh_eth: fix EESIPR values for SH77{34|63} sh_eth: R8A7740 supports packet shecksumming Sergey Senozhatsky (1): printk: use rcuidle console tracepoint Shannon Nelson (1): tcp: fix tcp_fastopen unaligned access complaints on sparc Shaohua Li (1): md: MD_RECOVERY_NEEDED is set for mddev->recovery Shmulik Ladkani (1): net/sched: em_meta: Fix 'meta vlan' to correctly recognize zero VID f= rames Simon Horman (1): sit: correct IP protocol used in ipip6_err 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 Steven Rostedt (Red Hat) (2): ftrace/x86_32: Set ftrace_stub to weak to prevent gcc from using shor= t jumps to it fgraph: Handle a case where a tracer ignores set_graph_notrace Takashi Iwai (7): ALSA: usb-audio: Fix bogus error return in snd_usb_create_stream() ALSA: hda - Add the top speaker pin config for HP Spectre x360 ALSA: hda - Gate the mic jack on HP Z1 Gen3 AiO ALSA: hda - Fix up GPIO for ASUS ROG Ranger ALSA: hda - Apply asus-mode8 fixup to ASUS X71SL 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 Trond Myklebust (1): NFS: Fix a performance regression in readdir Vineet Gupta (2): ARC: [arcompact] handle unaligned access delay slot corner case ARC: [arcompact] brown paper bag bug in unaligned access delay slot f= ixup Vlad Tsyrklevich (1): i2c: fix kernel memory disclosure in dev interface Vladimir Zapolskiy (3): ARM: dts: imx31: fix clock control module interrupts description ARM: dts: imx31: move CCM device node to AIPS2 bus devices ARM: dts: imx31: fix AVIC base address WANG Cong (4): ping: fix a null pointer dereference sch_htb: update backlog as well sch_dsmark: update backlog as well sit: fix a double free on error path Wan Ahmad Zainie (1): usb: xhci: apply XHCI_PME_STUCK_QUIRK to Intel Apollo Lake Wei Fang (1): scsi: avoid a permanent stop of the scsi device's request queue Wei Yongjun (1): iw_cxgb4: Fix error return code in c4iw_rdev_open() 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 hayeswang (1): r8152: fix the sw rx checksum is unavailable stephen hemminger (1): netvsc: reduce maximum GSO size --KRJ4yArSHF8vY7I3 Content-Type: text/x-diff; charset=UTF-8; name="linux-3.16.42.patch" Content-Disposition: attachment; filename="linux-3.16.42.patch" Content-Transfer-Encoding: quoted-printable diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.txt b/Docu= mentation/devicetree/bindings/clock/imx31-clock.txt index 19df842c694f..8163d565f697 100644 --- a/Documentation/devicetree/bindings/clock/imx31-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx31-clock.txt @@ -77,7 +77,7 @@ Examples: clks: ccm@53f80000{ compatible =3D "fsl,imx31-ccm"; reg =3D <0x53f80000 0x4000>; - interrupts =3D <0 31 0x04 0 53 0x04>; + interrupts =3D <31>, <53>; #clock-cells =3D <1>; }; =20 diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/= api.txt index 769c2cb7f9b3..e86da4377402 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1891,6 +1891,7 @@ registers, find a list below: PPC | KVM_REG_PPC_TM_VSCR | 32 PPC | KVM_REG_PPC_TM_DSCR | 64 PPC | KVM_REG_PPC_TM_TAR | 64 + PPC | KVM_REG_PPC_TM_XER | 64 =20 ARM registers are mapped using the lower 32 bits. The upper 16 of that is the register group type, or coprocessor number: diff --git a/MAINTAINERS b/MAINTAINERS index 65791c0891a9..b2a5243e9d0b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10057,11 +10057,11 @@ F: arch/x86/xen/*swiotlb* F: drivers/xen/*swiotlb* =20 XFS FILESYSTEM -M: Dave Chinner +M: Darrick J. Wong M: linux-xfs@vger.kernel.org L: linux-xfs@vger.kernel.org W: http://xfs.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git +T: git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git S: Supported F: Documentation/filesystems/xfs.txt F: fs/xfs/ diff --git a/Makefile b/Makefile index 1edbcba47f75..9deaac9255ff 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION =3D 3 PATCHLEVEL =3D 16 -SUBLEVEL =3D 41 +SUBLEVEL =3D 42 EXTRAVERSION =3D NAME =3D Museum of Fishiegoodies =20 diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c index 7ff5b5c183bb..2cc82b6ec23d 100644 --- a/arch/arc/kernel/unaligned.c +++ b/arch/arc/kernel/unaligned.c @@ -240,8 +240,9 @@ int misaligned_fixup(unsigned long address, struct pt_r= egs *regs, if (state.fault) goto fault; =20 + /* clear any remanants of delay slot */ if (delay_mode(regs)) { - regs->ret =3D regs->bta; + regs->ret =3D regs->bta & ~1U; regs->status32 &=3D ~STATUS_DE_MASK; } else { regs->ret +=3D state.instr_len; diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.= dts index 1e11e5a5f723..21342ab78ff5 100644 --- a/arch/arm/boot/dts/da850-evm.dts +++ b/arch/arm/boot/dts/da850-evm.dts @@ -59,6 +59,7 @@ #size-cells =3D <1>; compatible =3D "m25p64"; spi-max-frequency =3D <30000000>; + m25p,fast-read; reg =3D <0>; partition@0 { label =3D "U-Boot-SPL"; diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi index c34f82581248..626e5e374572 100644 --- a/arch/arm/boot/dts/imx31.dtsi +++ b/arch/arm/boot/dts/imx31.dtsi @@ -30,11 +30,11 @@ }; }; =20 - avic: avic-interrupt-controller@60000000 { + avic: interrupt-controller@68000000 { compatible =3D "fsl,imx31-avic", "fsl,avic"; interrupt-controller; #interrupt-cells =3D <1>; - reg =3D <0x60000000 0x100000>; + reg =3D <0x68000000 0x100000>; }; =20 soc { @@ -110,13 +110,6 @@ interrupts =3D <19>; clocks =3D <&clks 25>; }; - - clks: ccm@53f80000{ - compatible =3D "fsl,imx31-ccm"; - reg =3D <0x53f80000 0x4000>; - interrupts =3D <0 31 0x04 0 53 0x04>; - #clock-cells =3D <1>; - }; }; =20 aips@53f00000 { /* AIPS2 */ @@ -126,6 +119,13 @@ reg =3D <0x53f00000 0x100000>; ranges; =20 + clks: ccm@53f80000{ + compatible =3D "fsl,imx31-ccm"; + reg =3D <0x53f80000 0x4000>; + interrupts =3D <31>, <53>; + #clock-cells =3D <1>; + }; + gpt: timer@53f90000 { compatible =3D "fsl,imx31-gpt"; reg =3D <0x53f90000 0x4000>; diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-c= m-fx6.dts index 99b46f8030ad..172579a14aae 100644 --- a/arch/arm/boot/dts/imx6q-cm-fx6.dts +++ b/arch/arm/boot/dts/imx6q-cm-fx6.dts @@ -65,7 +65,6 @@ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 - MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 >; }; =20 diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 8c2b7321a478..4b401f1092f3 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -79,6 +79,9 @@ #define ARM_CPU_XSCALE_ARCH_V2 0x4000 #define ARM_CPU_XSCALE_ARCH_V3 0x6000 =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 4d963fb66e3f..5c7404326b7c 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -1067,6 +1067,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; + } + has_ossr =3D core_has_os_save_restore(); =20 /* Determine how many BRPs/WRPs are available. */ diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index a20ebfeac471..e81c15665f10 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -600,7 +600,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/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 45ce065e7170..1180a75cd707 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -297,6 +297,16 @@ static struct clk emac_clk =3D { .gpsc =3D 1, }; =20 +/* + * In order to avoid adding the emac_clk to the clock lookup table twice (= and + * screwing up the linked list in the process) create a separate clock for + * mdio inheriting the rate from emac_clk. + */ +static struct clk mdio_clk =3D { + .name =3D "mdio", + .parent =3D &emac_clk, +}; + static struct clk mcasp_clk =3D { .name =3D "mcasp", .parent =3D &pll0_sysclk2, @@ -461,7 +471,7 @@ static struct clk_lookup da850_clks[] =3D { CLK(NULL, "arm", &arm_clk), CLK(NULL, "rmii", &rmii_clk), CLK("davinci_emac.1", NULL, &emac_clk), - CLK("davinci_mdio.0", "fck", &emac_clk), + CLK("davinci_mdio.0", "fck", &mdio_clk), CLK("davinci-mcasp.0", NULL, &mcasp_clk), CLK("da8xx_lcdc.0", "fck", &lcdc_clk), CLK("da830-mmc.0", NULL, &mmcsd0_clk), diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c index b80a9a2e356e..ac32ad229429 100644 --- a/arch/arm/mach-ux500/pm.c +++ b/arch/arm/mach-ux500/pm.c @@ -131,8 +131,8 @@ bool prcmu_pending_irq(void) */ bool prcmu_is_cpu_in_wfi(int cpu) { - return readl(PRCM_ARM_WFI_STANDBY) & cpu ? PRCM_ARM_WFI_STANDBY_WFI1 : - PRCM_ARM_WFI_STANDBY_WFI0; + return readl(PRCM_ARM_WFI_STANDBY) & + (cpu ? PRCM_ARM_WFI_STANDBY_WFI1 : PRCM_ARM_WFI_STANDBY_WFI0); } =20 /* diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 31a6fa40ba37..b4214cf082b1 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -59,7 +59,7 @@ void __iomem *zynq_scu_base; static void __init zynq_memory_init(void) { if (!__pa(PAGE_OFFSET)) - memblock_reserve(__pa(PAGE_OFFSET), __pa(swapper_pg_dir)); + memblock_reserve(__pa(PAGE_OFFSET), 0x80000); } =20 static struct platform_device zynq_cpuidle_device =3D { diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 1e632430570b..e4d719ff71f6 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -291,8 +291,7 @@ static int __init xen_guest_init(void) * for secondary CPUs as they are brought up. * For uniformity we use VCPUOP_register_vcpu_info even on cpu0. */ - xen_vcpu_info =3D __alloc_percpu(sizeof(struct vcpu_info), - sizeof(struct vcpu_info)); + xen_vcpu_info =3D alloc_percpu(struct vcpu_info); if (xen_vcpu_info =3D=3D NULL) return -ENOMEM; =20 diff --git a/arch/arm64/crypto/aes-ce-ccm-core.S b/arch/arm64/crypto/aes-ce= -ccm-core.S index 432e4841cd81..d04eb27746d2 100644 --- a/arch/arm64/crypto/aes-ce-ccm-core.S +++ b/arch/arm64/crypto/aes-ce-ccm-core.S @@ -9,6 +9,7 @@ */ =20 #include +#include =20 .text .arch armv8-a+crypto @@ -19,7 +20,7 @@ */ ENTRY(ce_aes_ccm_auth_data) ldr w8, [x3] /* leftover from prev round? */ - ld1 {v0.2d}, [x0] /* load mac */ + ld1 {v0.16b}, [x0] /* load mac */ cbz w8, 1f sub w8, w8, #16 eor v1.16b, v1.16b, v1.16b @@ -31,7 +32,7 @@ ENTRY(ce_aes_ccm_auth_data) beq 8f /* out of input? */ cbnz w8, 0b eor v0.16b, v0.16b, v1.16b -1: ld1 {v3.2d}, [x4] /* load first round key */ +1: ld1 {v3.16b}, [x4] /* load first round key */ prfm pldl1strm, [x1] cmp w5, #12 /* which key size? */ add x6, x4, #16 @@ -41,17 +42,17 @@ ENTRY(ce_aes_ccm_auth_data) mov v5.16b, v3.16b b 4f 2: mov v4.16b, v3.16b - ld1 {v5.2d}, [x6], #16 /* load 2nd round key */ + ld1 {v5.16b}, [x6], #16 /* load 2nd round key */ 3: aese v0.16b, v4.16b aesmc v0.16b, v0.16b -4: ld1 {v3.2d}, [x6], #16 /* load next round key */ +4: ld1 {v3.16b}, [x6], #16 /* load next round key */ aese v0.16b, v5.16b aesmc v0.16b, v0.16b -5: ld1 {v4.2d}, [x6], #16 /* load next round key */ +5: ld1 {v4.16b}, [x6], #16 /* load next round key */ subs w7, w7, #3 aese v0.16b, v3.16b aesmc v0.16b, v0.16b - ld1 {v5.2d}, [x6], #16 /* load next round key */ + ld1 {v5.16b}, [x6], #16 /* load next round key */ bpl 3b aese v0.16b, v4.16b subs w2, w2, #16 /* last data? */ @@ -60,7 +61,7 @@ ENTRY(ce_aes_ccm_auth_data) ld1 {v1.16b}, [x1], #16 /* load next input block */ eor v0.16b, v0.16b, v1.16b /* xor with mac */ bne 1b -6: st1 {v0.2d}, [x0] /* store mac */ +6: st1 {v0.16b}, [x0] /* store mac */ beq 10f adds w2, w2, #16 beq 10f @@ -79,7 +80,7 @@ ENTRY(ce_aes_ccm_auth_data) adds w7, w7, #1 bne 9b eor v0.16b, v0.16b, v1.16b - st1 {v0.2d}, [x0] + st1 {v0.16b}, [x0] 10: str w8, [x3] ret ENDPROC(ce_aes_ccm_auth_data) @@ -89,27 +90,27 @@ ENDPROC(ce_aes_ccm_auth_data) * u32 rounds); */ ENTRY(ce_aes_ccm_final) - ld1 {v3.2d}, [x2], #16 /* load first round key */ - ld1 {v0.2d}, [x0] /* load mac */ + ld1 {v3.16b}, [x2], #16 /* load first round key */ + ld1 {v0.16b}, [x0] /* load mac */ cmp w3, #12 /* which key size? */ sub w3, w3, #2 /* modified # of rounds */ - ld1 {v1.2d}, [x1] /* load 1st ctriv */ + ld1 {v1.16b}, [x1] /* load 1st ctriv */ bmi 0f bne 3f mov v5.16b, v3.16b b 2f 0: mov v4.16b, v3.16b -1: ld1 {v5.2d}, [x2], #16 /* load next round key */ +1: ld1 {v5.16b}, [x2], #16 /* load next round key */ aese v0.16b, v4.16b aese v1.16b, v4.16b aesmc v0.16b, v0.16b aesmc v1.16b, v1.16b -2: ld1 {v3.2d}, [x2], #16 /* load next round key */ +2: ld1 {v3.16b}, [x2], #16 /* load next round key */ aese v0.16b, v5.16b aese v1.16b, v5.16b aesmc v0.16b, v0.16b aesmc v1.16b, v1.16b -3: ld1 {v4.2d}, [x2], #16 /* load next round key */ +3: ld1 {v4.16b}, [x2], #16 /* load next round key */ subs w3, w3, #3 aese v0.16b, v3.16b aese v1.16b, v3.16b @@ -120,47 +121,47 @@ ENTRY(ce_aes_ccm_final) aese v1.16b, v4.16b /* final round key cancels out */ eor v0.16b, v0.16b, v1.16b /* en-/decrypt the mac */ - st1 {v0.2d}, [x0] /* store result */ + st1 {v0.16b}, [x0] /* store result */ ret ENDPROC(ce_aes_ccm_final) =20 .macro aes_ccm_do_crypt,enc ldr x8, [x6, #8] /* load lower ctr */ - ld1 {v0.2d}, [x5] /* load mac */ - rev x8, x8 /* keep swabbed ctr in reg */ + ld1 {v0.16b}, [x5] /* load mac */ +CPU_LE( rev x8, x8 ) /* keep swabbed ctr in reg */ 0: /* outer loop */ - ld1 {v1.1d}, [x6] /* load upper ctr */ + ld1 {v1.8b}, [x6] /* load upper ctr */ prfm pldl1strm, [x1] add x8, x8, #1 rev x9, x8 cmp w4, #12 /* which key size? */ sub w7, w4, #2 /* get modified # of rounds */ ins v1.d[1], x9 /* no carry in lower ctr */ - ld1 {v3.2d}, [x3] /* load first round key */ + ld1 {v3.16b}, [x3] /* load first round key */ add x10, x3, #16 bmi 1f bne 4f mov v5.16b, v3.16b b 3f 1: mov v4.16b, v3.16b - ld1 {v5.2d}, [x10], #16 /* load 2nd round key */ + ld1 {v5.16b}, [x10], #16 /* load 2nd round key */ 2: /* inner loop: 3 rounds, 2x interleaved */ aese v0.16b, v4.16b aese v1.16b, v4.16b aesmc v0.16b, v0.16b aesmc v1.16b, v1.16b -3: ld1 {v3.2d}, [x10], #16 /* load next round key */ +3: ld1 {v3.16b}, [x10], #16 /* load next round key */ aese v0.16b, v5.16b aese v1.16b, v5.16b aesmc v0.16b, v0.16b aesmc v1.16b, v1.16b -4: ld1 {v4.2d}, [x10], #16 /* load next round key */ +4: ld1 {v4.16b}, [x10], #16 /* load next round key */ subs w7, w7, #3 aese v0.16b, v3.16b aese v1.16b, v3.16b aesmc v0.16b, v0.16b aesmc v1.16b, v1.16b - ld1 {v5.2d}, [x10], #16 /* load next round key */ + ld1 {v5.16b}, [x10], #16 /* load next round key */ bpl 2b aese v0.16b, v4.16b aese v1.16b, v4.16b @@ -177,14 +178,14 @@ ENDPROC(ce_aes_ccm_final) eor v0.16b, v0.16b, v2.16b /* xor mac with pt ^ rk[last] */ st1 {v1.16b}, [x0], #16 /* write output block */ bne 0b - rev x8, x8 - st1 {v0.2d}, [x5] /* store mac */ +CPU_LE( rev x8, x8 ) + st1 {v0.16b}, [x5] /* store mac */ str x8, [x6, #8] /* store lsb end of ctr (BE) */ 5: ret =20 6: eor v0.16b, v0.16b, v5.16b /* final round mac */ eor v1.16b, v1.16b, v5.16b /* final round enc */ - st1 {v0.2d}, [x5] /* store mac */ + st1 {v0.16b}, [x5] /* store mac */ add w2, w2, #16 /* process partial tail block */ 7: ldrb w9, [x1], #1 /* get 1 byte of input */ umov w6, v1.b[0] /* get top crypted ctr byte */ diff --git a/arch/arm64/crypto/aes-ce.S b/arch/arm64/crypto/aes-ce.S index 685a18f731eb..56a258d4bada 100644 --- a/arch/arm64/crypto/aes-ce.S +++ b/arch/arm64/crypto/aes-ce.S @@ -10,6 +10,7 @@ */ =20 #include +#include =20 #define AES_ENTRY(func) ENTRY(ce_ ## func) #define AES_ENDPROC(func) ENDPROC(ce_ ## func) diff --git a/arch/arm64/crypto/aes-modes.S b/arch/arm64/crypto/aes-modes.S index f6e372c528eb..838dad5c209f 100644 --- a/arch/arm64/crypto/aes-modes.S +++ b/arch/arm64/crypto/aes-modes.S @@ -193,15 +193,16 @@ AES_ENTRY(aes_cbc_encrypt) cbz w6, .Lcbcencloop =20 ld1 {v0.16b}, [x5] /* get iv */ - enc_prepare w3, x2, x5 + enc_prepare w3, x2, x6 =20 .Lcbcencloop: ld1 {v1.16b}, [x1], #16 /* get next pt block */ eor v0.16b, v0.16b, v1.16b /* ..and xor with iv */ - encrypt_block v0, w3, x2, x5, w6 + encrypt_block v0, w3, x2, x6, w7 st1 {v0.16b}, [x0], #16 subs w4, w4, #1 bne .Lcbcencloop + st1 {v0.16b}, [x5] /* return iv */ ret AES_ENDPROC(aes_cbc_encrypt) =20 @@ -211,7 +212,7 @@ AES_ENTRY(aes_cbc_decrypt) cbz w6, .LcbcdecloopNx =20 ld1 {v7.16b}, [x5] /* get iv */ - dec_prepare w3, x2, x5 + dec_prepare w3, x2, x6 =20 .LcbcdecloopNx: #if INTERLEAVE >=3D 2 @@ -248,7 +249,7 @@ AES_ENTRY(aes_cbc_decrypt) .Lcbcdecloop: ld1 {v1.16b}, [x1], #16 /* get next ct block */ mov v0.16b, v1.16b /* ...and copy to v0 */ - decrypt_block v0, w3, x2, x5, w6 + decrypt_block v0, w3, x2, x6, w7 eor v0.16b, v0.16b, v7.16b /* xor with iv =3D> pt */ mov v7.16b, v1.16b /* ct is next iv */ st1 {v0.16b}, [x0], #16 @@ -256,6 +257,7 @@ AES_ENTRY(aes_cbc_decrypt) bne .Lcbcdecloop .Lcbcdecout: FRAME_POP + st1 {v7.16b}, [x5] /* return iv */ ret AES_ENDPROC(aes_cbc_decrypt) =20 @@ -267,24 +269,15 @@ AES_ENDPROC(aes_cbc_decrypt) =20 AES_ENTRY(aes_ctr_encrypt) FRAME_PUSH - cbnz w6, .Lctrfirst /* 1st time around? */ - umov x5, v4.d[1] /* keep swabbed ctr in reg */ - rev x5, x5 -#if INTERLEAVE >=3D 2 - cmn w5, w4 /* 32 bit overflow? */ - bcs .Lctrinc - add x5, x5, #1 /* increment BE ctr */ - b .LctrincNx -#else - b .Lctrinc -#endif -.Lctrfirst: + cbz w6, .Lctrnotfirst /* 1st time around? */ enc_prepare w3, x2, x6 ld1 {v4.16b}, [x5] - umov x5, v4.d[1] /* keep swabbed ctr in reg */ - rev x5, x5 + +.Lctrnotfirst: + umov x8, v4.d[1] /* keep swabbed ctr in reg */ + rev x8, x8 #if INTERLEAVE >=3D 2 - cmn w5, w4 /* 32 bit overflow? */ + cmn w8, w4 /* 32 bit overflow? */ bcs .Lctrloop .LctrloopNx: subs w4, w4, #INTERLEAVE @@ -292,11 +285,11 @@ AES_ENTRY(aes_ctr_encrypt) #if INTERLEAVE =3D=3D 2 mov v0.8b, v4.8b mov v1.8b, v4.8b - rev x7, x5 - add x5, x5, #1 + rev x7, x8 + add x8, x8, #1 ins v0.d[1], x7 - rev x7, x5 - add x5, x5, #1 + rev x7, x8 + add x8, x8, #1 ins v1.d[1], x7 ld1 {v2.16b-v3.16b}, [x1], #32 /* get 2 input blocks */ do_encrypt_block2x @@ -305,7 +298,7 @@ AES_ENTRY(aes_ctr_encrypt) st1 {v0.16b-v1.16b}, [x0], #32 #else ldr q8, =3D0x30000000200000001 /* addends 1,2,3[,0] */ - dup v7.4s, w5 + dup v7.4s, w8 mov v0.16b, v4.16b add v7.4s, v7.4s, v8.4s mov v1.16b, v4.16b @@ -323,18 +316,12 @@ AES_ENTRY(aes_ctr_encrypt) eor v2.16b, v7.16b, v2.16b eor v3.16b, v5.16b, v3.16b st1 {v0.16b-v3.16b}, [x0], #64 - add x5, x5, #INTERLEAVE + add x8, x8, #INTERLEAVE #endif - cbz w4, .LctroutNx -.LctrincNx: - rev x7, x5 + rev x7, x8 ins v4.d[1], x7 + cbz w4, .Lctrout b .LctrloopNx -.LctroutNx: - sub x5, x5, #1 - rev x7, x5 - ins v4.d[1], x7 - b .Lctrout .Lctr1x: adds w4, w4, #INTERLEAVE beq .Lctrout @@ -342,30 +329,39 @@ AES_ENTRY(aes_ctr_encrypt) .Lctrloop: mov v0.16b, v4.16b encrypt_block v0, w3, x2, x6, w7 + + adds x8, x8, #1 /* increment BE ctr */ + rev x7, x8 + ins v4.d[1], x7 + bcs .Lctrcarry /* overflow? */ + +.Lctrcarrydone: subs w4, w4, #1 bmi .Lctrhalfblock /* blocks < 0 means 1/2 block */ ld1 {v3.16b}, [x1], #16 eor v3.16b, v0.16b, v3.16b st1 {v3.16b}, [x0], #16 - beq .Lctrout -.Lctrinc: - adds x5, x5, #1 /* increment BE ctr */ - rev x7, x5 - ins v4.d[1], x7 - bcc .Lctrloop /* no overflow? */ - umov x7, v4.d[0] /* load upper word of ctr */ - rev x7, x7 /* ... to handle the carry */ - add x7, x7, #1 - rev x7, x7 - ins v4.d[0], x7 - b .Lctrloop + bne .Lctrloop + +.Lctrout: + st1 {v4.16b}, [x5] /* return next CTR value */ + FRAME_POP + ret + .Lctrhalfblock: ld1 {v3.8b}, [x1] eor v3.8b, v0.8b, v3.8b st1 {v3.8b}, [x0] -.Lctrout: FRAME_POP ret + +.Lctrcarry: + umov x7, v4.d[0] /* load upper word of ctr */ + rev x7, x7 /* ... to handle the carry */ + add x7, x7, #1 + rev x7, x7 + ins v4.d[0], x7 + b .Lctrcarrydone AES_ENDPROC(aes_ctr_encrypt) .ltorg =20 @@ -386,7 +382,8 @@ AES_ENDPROC(aes_ctr_encrypt) .endm =20 .Lxts_mul_x: - .word 1, 0, 0x87, 0 +CPU_LE( .quad 1, 0x87 ) +CPU_BE( .quad 0x87, 1 ) =20 AES_ENTRY(aes_xts_encrypt) FRAME_PUSH diff --git a/arch/arm64/crypto/aes-neon.S b/arch/arm64/crypto/aes-neon.S index b93170e1cc93..85f07ead7c5c 100644 --- a/arch/arm64/crypto/aes-neon.S +++ b/arch/arm64/crypto/aes-neon.S @@ -9,6 +9,7 @@ */ =20 #include +#include =20 #define AES_ENTRY(func) ENTRY(neon_ ## func) #define AES_ENDPROC(func) ENDPROC(neon_ ## func) @@ -83,13 +84,13 @@ .endm =20 .macro do_block, enc, in, rounds, rk, rkp, i - ld1 {v15.16b}, [\rk] + ld1 {v15.4s}, [\rk] add \rkp, \rk, #16 mov \i, \rounds 1111: eor \in\().16b, \in\().16b, v15.16b /* ^round key */ tbl \in\().16b, {\in\().16b}, v13.16b /* ShiftRows */ sub_bytes \in - ld1 {v15.16b}, [\rkp], #16 + ld1 {v15.4s}, [\rkp], #16 subs \i, \i, #1 beq 2222f .if \enc =3D=3D 1 @@ -229,7 +230,7 @@ .endm =20 .macro do_block_2x, enc, in0, in1 rounds, rk, rkp, i - ld1 {v15.16b}, [\rk] + ld1 {v15.4s}, [\rk] add \rkp, \rk, #16 mov \i, \rounds 1111: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */ @@ -237,7 +238,7 @@ sub_bytes_2x \in0, \in1 tbl \in0\().16b, {\in0\().16b}, v13.16b /* ShiftRows */ tbl \in1\().16b, {\in1\().16b}, v13.16b /* ShiftRows */ - ld1 {v15.16b}, [\rkp], #16 + ld1 {v15.4s}, [\rkp], #16 subs \i, \i, #1 beq 2222f .if \enc =3D=3D 1 @@ -254,7 +255,7 @@ .endm =20 .macro do_block_4x, enc, in0, in1, in2, in3, rounds, rk, rkp, i - ld1 {v15.16b}, [\rk] + ld1 {v15.4s}, [\rk] add \rkp, \rk, #16 mov \i, \rounds 1111: eor \in0\().16b, \in0\().16b, v15.16b /* ^round key */ @@ -266,7 +267,7 @@ tbl \in1\().16b, {\in1\().16b}, v13.16b /* ShiftRows */ tbl \in2\().16b, {\in2\().16b}, v13.16b /* ShiftRows */ tbl \in3\().16b, {\in3\().16b}, v13.16b /* ShiftRows */ - ld1 {v15.16b}, [\rkp], #16 + ld1 {v15.4s}, [\rkp], #16 subs \i, \i, #1 beq 2222f .if \enc =3D=3D 1 @@ -306,12 +307,16 @@ .text .align 4 .LForward_ShiftRows: - .byte 0x0, 0x5, 0xa, 0xf, 0x4, 0x9, 0xe, 0x3 - .byte 0x8, 0xd, 0x2, 0x7, 0xc, 0x1, 0x6, 0xb +CPU_LE( .byte 0x0, 0x5, 0xa, 0xf, 0x4, 0x9, 0xe, 0x3 ) +CPU_LE( .byte 0x8, 0xd, 0x2, 0x7, 0xc, 0x1, 0x6, 0xb ) +CPU_BE( .byte 0xb, 0x6, 0x1, 0xc, 0x7, 0x2, 0xd, 0x8 ) +CPU_BE( .byte 0x3, 0xe, 0x9, 0x4, 0xf, 0xa, 0x5, 0x0 ) =20 .LReverse_ShiftRows: - .byte 0x0, 0xd, 0xa, 0x7, 0x4, 0x1, 0xe, 0xb - .byte 0x8, 0x5, 0x2, 0xf, 0xc, 0x9, 0x6, 0x3 +CPU_LE( .byte 0x0, 0xd, 0xa, 0x7, 0x4, 0x1, 0xe, 0xb ) +CPU_LE( .byte 0x8, 0x5, 0x2, 0xf, 0xc, 0x9, 0x6, 0x3 ) +CPU_BE( .byte 0x3, 0x6, 0x9, 0xc, 0xf, 0x2, 0x5, 0x8 ) +CPU_BE( .byte 0xb, 0xe, 0x1, 0x4, 0x7, 0xa, 0xd, 0x0 ) =20 .LForward_Sbox: .byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 diff --git a/arch/arm64/crypto/ghash-ce-core.S b/arch/arm64/crypto/ghash-ce= -core.S index dc457015884e..f0bb9f0b524f 100644 --- a/arch/arm64/crypto/ghash-ce-core.S +++ b/arch/arm64/crypto/ghash-ce-core.S @@ -29,8 +29,8 @@ * struct ghash_key const *k, const char *head) */ ENTRY(pmull_ghash_update) - ld1 {SHASH.16b}, [x3] - ld1 {XL.16b}, [x1] + ld1 {SHASH.2d}, [x3] + ld1 {XL.2d}, [x1] movi MASK.16b, #0xe1 ext SHASH2.16b, SHASH.16b, SHASH.16b, #8 shl MASK.2d, MASK.2d, #57 @@ -74,6 +74,6 @@ CPU_LE( rev64 T1.16b, T1.16b ) =20 cbnz w0, 0b =20 - st1 {XL.16b}, [x1] + st1 {XL.2d}, [x1] ret ENDPROC(pmull_ghash_update) diff --git a/arch/arm64/crypto/sha1-ce-core.S b/arch/arm64/crypto/sha1-ce-c= ore.S index 09d57d98609c..1fb70893ce55 100644 --- a/arch/arm64/crypto/sha1-ce-core.S +++ b/arch/arm64/crypto/sha1-ce-core.S @@ -78,7 +78,7 @@ ENTRY(sha1_ce_transform) ld1r {k3.4s}, [x6] =20 /* load state */ - ldr dga, [x2] + ld1 {dgav.4s}, [x2] ldr dgb, [x2, #16] =20 /* load partial state (if supplied) */ @@ -147,7 +147,7 @@ CPU_LE( rev32 v11.16b, v11.16b ) b 2b =20 /* store new state */ -3: str dga, [x2] +3: st1 {dgav.4s}, [x2] str dgb, [x2, #16] ret ENDPROC(sha1_ce_transform) diff --git a/arch/arm64/crypto/sha2-ce-core.S b/arch/arm64/crypto/sha2-ce-c= ore.S index 7f29fc031ea8..0acd61ef8cb2 100644 --- a/arch/arm64/crypto/sha2-ce-core.S +++ b/arch/arm64/crypto/sha2-ce-core.S @@ -85,7 +85,7 @@ ENTRY(sha2_ce_transform) ld1 {v12.4s-v15.4s}, [x8] =20 /* load state */ - ldp dga, dgb, [x2] + ld1 {dgav.4s, dgbv.4s}, [x2] =20 /* load partial input (if supplied) */ cbz x3, 0f @@ -151,6 +151,6 @@ CPU_LE( rev32 v19.16b, v19.16b ) b 2b =20 /* store new state */ -3: stp dga, dgb, [x2] +3: st1 {dgav.4s, dgbv.4s}, [x2] ret ENDPROC(sha2_ce_transform) diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi= /asm/ptrace.h index 6913643bbe54..c136fd53c847 100644 --- a/arch/arm64/include/uapi/asm/ptrace.h +++ b/arch/arm64/include/uapi/asm/ptrace.h @@ -75,6 +75,7 @@ struct user_fpsimd_state { __uint128_t vregs[32]; __u32 fpsr; __u32 fpcr; + __u32 __reserved[2]; }; =20 struct user_hwdebug_state { diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 8993a69099c7..67738737be9d 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -491,7 +491,7 @@ el0_inv: mov x0, sp mov x1, #BAD_SYNC mrs x2, esr_el1 - b bad_mode + b bad_el0_sync ENDPROC(el0_sync) =20 .align 6 diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index d2b9a3f7457d..07c5f63a3362 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -446,6 +446,8 @@ static int hw_break_set(struct task_struct *target, /* (address, ctrl) registers */ limit =3D regset->n * regset->size; while (count && offset < limit) { + if (count < PTRACE_HBP_ADDR_SZ) + return -EINVAL; ret =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, &addr, offset, offset + PTRACE_HBP_ADDR_SZ); if (ret) @@ -455,6 +457,8 @@ static int hw_break_set(struct task_struct *target, return ret; offset +=3D PTRACE_HBP_ADDR_SZ; =20 + if (!count) + break; ret =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, offset, offset + PTRACE_HBP_CTRL_SZ); if (ret) @@ -491,7 +495,7 @@ static int gpr_set(struct task_struct *target, const st= ruct user_regset *regset, const void *kbuf, const void __user *ubuf) { int ret; - struct user_pt_regs newregs; + struct user_pt_regs newregs =3D task_pt_regs(target)->user_regs; =20 ret =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1); if (ret) @@ -521,7 +525,8 @@ static int fpr_set(struct task_struct *target, const st= ruct user_regset *regset, const void *kbuf, const void __user *ubuf) { int ret; - struct user_fpsimd_state newstate; + struct user_fpsimd_state newstate =3D + target->thread.fpsimd_state.user_fpsimd; =20 ret =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newstate, 0, -1); if (ret) @@ -545,7 +550,7 @@ static int tls_set(struct task_struct *target, const st= ruct user_regset *regset, const void *kbuf, const void __user *ubuf) { int ret; - unsigned long tls; + unsigned long tls =3D target->thread.tp_value; =20 ret =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); if (ret) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index c43cfa9b8304..c1c2ad6a1c94 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -309,16 +309,33 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) } =20 /* - * bad_mode handles the impossible case in the exception vector. + * bad_mode handles the impossible case in the exception vector. This is a= lways + * fatal. */ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int es= r) { - siginfo_t info; - void __user *pc =3D (void __user *)instruction_pointer(regs); console_verbose(); =20 pr_crit("Bad mode in %s handler detected, code 0x%08x\n", handler[reason], esr); + + die("Oops - bad mode", regs, 0); + local_irq_disable(); + panic("bad mode"); +} + +/* + * bad_el0_sync handles unexpected, but potentially recoverable synchronous + * exceptions taken from EL0. Unlike bad_mode, this returns. + */ +asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned in= t esr) +{ + siginfo_t info; + void __user *pc =3D (void __user *)instruction_pointer(regs); + console_verbose(); + + pr_crit("Bad EL0 synchronous exception detected on CPU%d, code 0x%08x\n", + smp_processor_id(), esr); __show_regs(regs); =20 info.si_signo =3D SIGILL; @@ -326,7 +343,10 @@ asmlinkage void bad_mode(struct pt_regs *regs, int rea= son, unsigned int esr) info.si_code =3D ILL_ILLOPC; info.si_addr =3D pc; =20 - arm64_notify_die("Oops - bad mode", regs, &info, 0); + current->thread.fault_address =3D 0; + current->thread.fault_code =3D 0; + + force_sig_info(info.si_signo, &info, current); } =20 void __pte_error(const char *file, int line, unsigned long val) 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/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c index 72aad2a9a6b4..263c6c1c9bbb 100644 --- a/arch/mips/kvm/kvm_mips.c +++ b/arch/mips/kvm/kvm_mips.c @@ -343,8 +343,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, = unsigned int id) mips32_GuestExceptionEnd - mips32_GuestException); =20 /* Invalidate the icache for these ranges */ - local_flush_icache_range((unsigned long)gebase, - (unsigned long)gebase + ALIGN(size, PAGE_SIZE)); + flush_icache_range((unsigned long)gebase, + (unsigned long)gebase + ALIGN(size, PAGE_SIZE)); =20 /* Allocate comm page for guest kernel, a TLB will be reserved for mappin= g GVA @ 0xFFFF8000 to this page */ vcpu->arch.kseg0_commpage =3D kzalloc(PAGE_SIZE << 1, GFP_KERNEL); diff --git a/arch/parisc/include/asm/bitops.h b/arch/parisc/include/asm/bit= ops.h index 3f9406d9b9d6..da87943328a5 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 #include @@ -17,6 +17,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/uapi/asm/bitsperlong.h b/arch/parisc/inclu= de/uapi/asm/bitsperlong.h index 75196b415d3f..540c94de4427 100644 --- a/arch/parisc/include/uapi/asm/bitsperlong.h +++ b/arch/parisc/include/uapi/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/uapi/asm/swab.h b/arch/parisc/include/uapi= /asm/swab.h index e78403b129ef..928e1bbac98f 100644 --- a/arch/parisc/include/uapi/asm/swab.h +++ b/arch/parisc/include/uapi/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 4ec2d86d3c50..a05558a7e51a 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/boot/wrapper b/arch/powerpc/boot/wrapper index ae0f88ec4a32..c70210d9fb89 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -144,6 +144,28 @@ case "$elfformat" in elf32-powerpc) format=3Delf32ppc ;; esac =20 +ld_version() +{ + # Poached from scripts/ld-version.sh, but we don't want to call that b= ecause + # this script (wrapper) is distributed separately from the kernel sour= ce. + # Extract linker version number from stdin and turn into single number. + awk '{ + gsub(".*\\)", ""); + gsub(".*version ", ""); + gsub("-.*", ""); + split($1,a, "."); + print a[1]*100000000 + a[2]*1000000 + a[3]*10000; + exit + }' +} + +# Do not include PT_INTERP segment when linking pie. Non-pie linking +# just ignores this option. +LD_VERSION=3D$(${CROSS}ld --version | ld_version) +LD_NO_DL_MIN_VERSION=3D$(echo 2.26 | ld_version) +if [ "$LD_VERSION" -ge "$LD_NO_DL_MIN_VERSION" ] ; then + nodl=3D"--no-dynamic-linker" +fi =20 platformo=3D$object/"$platform".o lds=3D$object/zImage.lds @@ -395,7 +417,7 @@ if [ "$platform" !=3D "miboot" ]; then if [ -n "$link_address" ] ; then text_start=3D"-Ttext $link_address" fi - ${CROSS}ld -m $format -T $lds $text_start $pie -o "$ofile" \ + ${CROSS}ld -m $format -T $lds $text_start $pie $nodl -o "$ofile" \ $platformo $tmp $object/wrapper.a rm $tmp fi diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm= /kvm_host.h index 2149dbcf8931..c2a82045d64e 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -532,6 +532,7 @@ struct kvm_vcpu_arch { u64 tfiar; =20 u32 cr_tm; + u64 xer_tm; u64 lr_tm; u64 ctr_tm; u64 amr_tm; diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/a= sm/ppc-opcode.h index 3132bb9365f3..f47c3d9cb997 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -149,7 +149,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_MSGSNDP 0x7c00011c #define PPC_INST_NOP 0x60000000 @@ -161,13 +161,13 @@ #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 #define PPC_INST_MFSPR_DSCR_USER 0x7c0302a6 -#define PPC_INST_MFSPR_DSCR_USER_MASK 0xfc1fffff +#define PPC_INST_MFSPR_DSCR_USER_MASK 0xfc1ffffe #define PPC_INST_MTSPR_DSCR_USER 0x7c0303a6 -#define PPC_INST_MTSPR_DSCR_USER_MASK 0xfc1fffff +#define PPC_INST_MTSPR_DSCR_USER_MASK 0xfc1ffffe #define PPC_INST_SLBFEE 0x7c0007a7 =20 #define PPC_INST_STRING 0x7c00042a diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uap= i/asm/kvm.h index de7d426a9b0c..93783f7cf729 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -580,6 +580,7 @@ struct kvm_get_htab_header { #define KVM_REG_PPC_TM_VSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67) #define KVM_REG_PPC_TM_DSCR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68) #define KVM_REG_PPC_TM_TAR (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69) +#define KVM_REG_PPC_TM_XER (KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x6a) =20 /* PPC64 eXternal Interrupt Controller Specification */ #define KVM_DEV_XICS_GRP_SOURCES 1 /* 64-bit source attributes */ diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-of= fsets.c index 88abea889876..213fcaf4168d 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -572,6 +572,7 @@ int main(void) DEFINE(VCPU_VRS_TM, offsetof(struct kvm_vcpu, arch.vr_tm.vr)); DEFINE(VCPU_VRSAVE_TM, offsetof(struct kvm_vcpu, arch.vrsave_tm)); DEFINE(VCPU_CR_TM, offsetof(struct kvm_vcpu, arch.cr_tm)); + DEFINE(VCPU_XER_TM, offsetof(struct kvm_vcpu, arch.xer_tm)); DEFINE(VCPU_LR_TM, offsetof(struct kvm_vcpu, arch.lr_tm)); DEFINE(VCPU_CTR_TM, offsetof(struct kvm_vcpu, arch.ctr_tm)); DEFINE(VCPU_AMR_TM, offsetof(struct kvm_vcpu, arch.amr_tm)); diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 1114d13ac19f..99ed2cc4c92f 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -180,6 +180,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("/"); @@ -188,9 +189,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) { @@ -262,6 +266,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 @@ -269,8 +274,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; @@ -307,6 +314,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/misc_32.S b/arch/powerpc/kernel/misc_32.S index 7c6bb4b17b49..2c70bbcb006f 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -313,7 +313,7 @@ _GLOBAL(flush_instruction_cache) lis r3, KERNELBASE@h iccci 0,r3 #endif -#elif CONFIG_FSL_BOOKE +#elif defined(CONFIG_FSL_BOOKE) BEGIN_FTR_SECTION mfspr r3,SPRN_L1CSR0 ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_ini= t.c index 69be680f7184..c49a85c5fc6b 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -2635,6 +2635,9 @@ static void __init prom_find_boot_cpu(void) =20 cpu_pkg =3D call_prom("instance-to-package", 1, 1, prom_cpu); =20 + if (!PHANDLE_VALID(cpu_pkg)) + return; + prom_getprop(cpu_pkg, "reg", &rval, sizeof(rval)); prom.cpu =3D be32_to_cpu(rval); =20 diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 665ff668d8ae..1b3f715db647 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -394,6 +394,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); + buf[32] =3D target->thread.fp_state.fpscr; + /* copy to local buffer then write that out */ i =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1); if (i) @@ -537,6 +541,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.fp_state.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/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index a416b6bb0d6a..d39faa230eb1 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -988,6 +988,9 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu,= u64 id, case KVM_REG_PPC_TM_CR: *val =3D get_reg_val(id, vcpu->arch.cr_tm); break; + case KVM_REG_PPC_TM_XER: + *val =3D get_reg_val(id, vcpu->arch.xer_tm); + break; case KVM_REG_PPC_TM_LR: *val =3D get_reg_val(id, vcpu->arch.lr_tm); break; @@ -1201,6 +1204,9 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcp= u, u64 id, case KVM_REG_PPC_TM_CR: vcpu->arch.cr_tm =3D set_reg_val(id, *val); break; + case KVM_REG_PPC_TM_XER: + vcpu->arch.xer_tm =3D set_reg_val(id, *val); + break; case KVM_REG_PPC_TM_LR: vcpu->arch.lr_tm =3D set_reg_val(id, *val); break; diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/boo= k3s_hv_rmhandlers.S index ab69a5f242d1..da1aa24d586f 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -2356,11 +2356,13 @@ kvmppc_save_tm: mfctr r7 mfspr r8, SPRN_AMR mfspr r10, SPRN_TAR + mfxer r11 std r5, VCPU_LR_TM(r9) stw r6, VCPU_CR_TM(r9) std r7, VCPU_CTR_TM(r9) std r8, VCPU_AMR_TM(r9) std r10, VCPU_TAR_TM(r9) + std r11, VCPU_XER_TM(r9) =20 /* Restore r12 as trap number. */ lwz r12, VCPU_TRAP(r9) @@ -2453,11 +2455,13 @@ kvmppc_restore_tm: ld r7, VCPU_CTR_TM(r4) ld r8, VCPU_AMR_TM(r4) ld r9, VCPU_TAR_TM(r4) + ld r10, VCPU_XER_TM(r4) mtlr r5 mtcr r6 mtctr r7 mtspr SPRN_AMR, r8 mtspr SPRN_TAR, r9 + mtxer r10 =20 /* * Load up PPR and DSCR values but don't put them in the actual SPRs diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kerne= l.c index 683c4af999de..6b46d2f1c741 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -339,37 +339,37 @@ void __init leon_init_timers(void) =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/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index de98c6ddf136..2343126c4ad2 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c @@ -110,7 +110,7 @@ static int tile_gpr_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { int ret; - struct pt_regs regs; + struct pt_regs regs =3D *task_pt_regs(target); =20 ret =3D user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s, 0, sizeof(regs)); diff --git a/arch/x86/boot/string.c b/arch/x86/boot/string.c index 493f3fd9f139..847f56c734b4 100644 --- a/arch/x86/boot/string.c +++ b/arch/x86/boot/string.c @@ -14,6 +14,7 @@ =20 #include #include "ctype.h" +#include "string.h" =20 int memcmp(const void *s1, const void *s2, size_t len) { diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h index 725e820602b1..113588ddb43f 100644 --- a/arch/x86/boot/string.h +++ b/arch/x86/boot/string.h @@ -18,4 +18,13 @@ int memcmp(const void *s1, const void *s2, size_t len); #define memset(d,c,l) __builtin_memset(d,c,l) #define memcmp __builtin_memcmp =20 +extern int strcmp(const char *str1, const char *str2); +extern int strncmp(const char *cs, const char *ct, size_t count); +extern size_t strlen(const char *s); +extern char *strstr(const char *s1, const char *s2); +extern size_t strnlen(const char *s, size_t maxlen); +extern unsigned int atou(const char *s); +extern unsigned long long simple_strtoull(const char *cp, char **endp, + unsigned int base); + #endif /* BOOT_STRING_H */ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 3b12b4d1a560..b0f4cfef81c4 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1105,7 +1105,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/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 0d0c9d4ab6d5..2c123171944a 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -1086,8 +1086,8 @@ ftrace_graph_call: jmp ftrace_stub #endif =20 -.globl ftrace_stub -ftrace_stub: +/* This is weak to keep gas from relaxing the jumps */ +WEAK(ftrace_stub) ret END(ftrace_caller) =20 diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 1f4e8e4ea865..d03a88cb3129 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1941,3 +1941,9 @@ void kvm_lapic_init(void) jump_label_rate_limit(&apic_hw_disabled, HZ); jump_label_rate_limit(&apic_sw_disabled, HZ); } + +void kvm_lapic_exit(void) +{ + static_key_deferred_flush(&apic_hw_disabled); + static_key_deferred_flush(&apic_sw_disabled); +} diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 72051730caf1..776e9919e910 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -93,6 +93,7 @@ static inline bool kvm_hv_vapic_assist_page_enabled(struc= t kvm_vcpu *vcpu) =20 int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data); void kvm_lapic_init(void); +void kvm_lapic_exit(void); =20 static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off) { diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 7b16666d6ed4..dad945386800 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5954,14 +5954,20 @@ static int nested_vmx_check_vmptr(struct kvm_vcpu *= vcpu, int exit_reason, } =20 page =3D nested_get_page(vcpu, vmptr); - if (page =3D=3D NULL || - *(u32 *)kmap(page) !=3D VMCS12_REVISION) { + if (page =3D=3D NULL) { nested_vmx_failInvalid(vcpu); + skip_emulated_instruction(vcpu); + return 1; + } + if (*(u32 *)kmap(page) !=3D VMCS12_REVISION) { kunmap(page); + nested_release_page_clean(page); + nested_vmx_failInvalid(vcpu); skip_emulated_instruction(vcpu); return 1; } kunmap(page); + nested_release_page_clean(page); vmx->nested.vmxon_ptr =3D vmptr; break; case EXIT_REASON_VMCLEAR: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e0a27d684d29..7dcb958a8054 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -892,7 +892,7 @@ static u32 msrs_to_save[] =3D { MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, #endif MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA, - MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX, + MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS }; =20 static unsigned num_msrs_to_save; @@ -3994,17 +3994,16 @@ static void kvm_init_msr_list(void) =20 /* * Even MSRs that are valid in the host may not be exposed - * to the guests in some cases. + * to the guests in some cases. We could work around this + * in VMX with the generic MSR save/load machinery, but it + * is not really worthwhile since it will really only + * happen with nested virtualization. */ switch (msrs_to_save[i]) { case MSR_IA32_BNDCFGS: if (!kvm_x86_ops->mpx_supported()) continue; break; - case MSR_TSC_AUX: - if (!kvm_x86_ops->rdtscp_supported()) - continue; - break; default: break; } @@ -5677,6 +5676,7 @@ out: =20 void kvm_arch_exit(void) { + kvm_lapic_exit(); perf_unregister_guest_info_callbacks(&kvm_guest_cbs); =20 if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 0f8002ca2a5c..45bf431a06af 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -118,6 +118,16 @@ static const struct dmi_system_id pci_crs_quirks[] __i= nitconst =3D { DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"), }, }, + /* https://bugzilla.kernel.org/show_bug.cgi?id=3D42606 */ + { + .callback =3D set_nouse_crs, + .ident =3D "Supermicro X8DTH", + .matches =3D { + DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), + DMI_MATCH(DMI_PRODUCT_NAME, "X8DTH-i/6/iF/6F"), + DMI_MATCH(DMI_BIOS_VERSION, "2.0a"), + }, + }, =20 /* https://bugzilla.kernel.org/show_bug.cgi?id=3D15362 */ { diff --git a/crypto/algapi.c b/crypto/algapi.c index daf2f653b131..8ea7a5dc3839 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -337,6 +337,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 391cfda1e83f..8c3c4ea760fb 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4109,6 +4109,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 hpriv->clk =3D clk_get(&pdev->dev, NULL); diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c index 6cd08e145bfa..036a05b28eb5 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -107,13 +107,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 e210a6d1406a..6ac6b7c02ecf 100644 --- a/drivers/base/regmap/regcache-lzo.c +++ b/drivers/base/regmap/regcache-lzo.c @@ -236,15 +236,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 @@ -275,15 +273,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 7be44e464462..a1ecedfc9d39 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -239,9 +239,10 @@ static inline int sock_send_bvec(struct nbd_device *nb= d, struct bio_vec *bvec, /* always call with the tx_lock held */ static int nbd_send_req(struct nbd_device *nbd, struct request *req) { - int result, flags; + int result; struct nbd_request request; unsigned long size =3D blk_rq_bytes(req); + struct bio *bio; =20 memset(&request, 0, sizeof(request)); request.magic =3D htonl(NBD_REQUEST_MAGIC); @@ -266,17 +267,19 @@ static int nbd_send_req(struct nbd_device *nbd, struc= t 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; + struct bvec_iter iter; 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(bvec, iter)) - flags =3D MSG_MORE; + + bio_for_each_segment(bvec, bio, iter) { + bool is_last =3D !next && bio_iter_last(bvec, iter); + int flags =3D is_last ? 0 : MSG_MORE; + dprintk(DBG_TX, "%s: request %p: sending %d bytes data\n", nbd->disk->disk_name, req, bvec.bv_len); result =3D sock_send_bvec(nbd, &bvec, flags); @@ -286,7 +289,16 @@ static int nbd_send_req(struct nbd_device *nbd, 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/bus/vexpress-config.c b/drivers/bus/vexpress-config.c index a64763b6b5fd..a803e5d84baf 100644 --- a/drivers/bus/vexpress-config.c +++ b/drivers/bus/vexpress-config.c @@ -171,6 +171,7 @@ static int vexpress_config_populate(struct device_node = *node) { struct device_node *bridge; struct device *parent; + int ret; =20 bridge =3D of_parse_phandle(node, "arm,vexpress,config-bridge", 0); if (!bridge) @@ -181,7 +182,11 @@ static int vexpress_config_populate(struct device_node= *node) if (WARN_ON(!parent)) return -ENODEV; =20 - return of_platform_populate(node, NULL, NULL, parent); + ret =3D of_platform_populate(node, NULL, NULL, parent); + + put_device(parent); + + return ret; } =20 static int __init vexpress_config_init(void) diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c index b131041c8f48..093dfe159dfb 100644 --- a/drivers/clk/clk-wm831x.c +++ b/drivers/clk/clk-wm831x.c @@ -248,7 +248,7 @@ static int wm831x_clkout_is_prepared(struct clk_hw *hw) if (ret < 0) { dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_1: %d\n", ret); - return true; + return false; } =20 return (ret & WM831X_CLKOUT_ENA) !=3D 0; diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mst= p.c index 2d2fe773ac81..a9e02a38093e 100644 --- a/drivers/clk/shmobile/clk-mstp.c +++ b/drivers/clk/shmobile/clk-mstp.c @@ -31,12 +31,14 @@ * @smstpcr: module stop control register * @mstpsr: module stop status register (optional) * @lock: protects writes to SMSTPCR + * @width_8bit: registers are 8-bit, not 32-bit */ struct mstp_clock_group { struct clk_onecell_data data; void __iomem *smstpcr; void __iomem *mstpsr; spinlock_t lock; + bool width_8bit; }; =20 /** @@ -53,6 +55,18 @@ struct mstp_clock { =20 #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) =20 +static inline u32 cpg_mstp_read(struct mstp_clock_group *group, + u32 __iomem *reg) +{ + return group->width_8bit ? readb(reg) : clk_readl(reg); +} + +static inline void cpg_mstp_write(struct mstp_clock_group *group, u32 val, + u32 __iomem *reg) +{ + group->width_8bit ? writeb(val, reg) : clk_writel(val, reg); +} + static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) { struct mstp_clock *clock =3D to_mstp_clock(hw); @@ -64,12 +78,12 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, = bool enable) =20 spin_lock_irqsave(&group->lock, flags); =20 - value =3D clk_readl(group->smstpcr); + value =3D cpg_mstp_read(group, group->smstpcr); if (enable) value &=3D ~bitmask; else value |=3D bitmask; - clk_writel(value, group->smstpcr); + cpg_mstp_write(group, value, group->smstpcr); =20 spin_unlock_irqrestore(&group->lock, flags); =20 @@ -77,7 +91,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bo= ol enable) return 0; =20 for (i =3D 1000; i > 0; --i) { - if (!(clk_readl(group->mstpsr) & bitmask)) + if (!(cpg_mstp_read(group, group->mstpsr) & bitmask)) break; cpu_relax(); } @@ -108,9 +122,9 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) u32 value; =20 if (group->mstpsr) - value =3D clk_readl(group->mstpsr); + value =3D cpg_mstp_read(group, group->mstpsr); else - value =3D clk_readl(group->smstpcr); + value =3D cpg_mstp_read(group, group->smstpcr); =20 return !(value & BIT(clock->bit_index)); } @@ -182,6 +196,9 @@ static void __init cpg_mstp_clocks_init(struct device_n= ode *np) return; } =20 + if (of_device_is_compatible(np, "renesas,r7s72100-mstp-clocks")) + group->width_8bit =3D true; + for (i =3D 0; i < MSTP_MAX_CLOCKS; ++i) clks[i] =3D ERR_PTR(-ENOENT); =20 diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_= mct.c index 5d1b7f64947c..2163a5145518 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -458,10 +458,15 @@ static int exynos4_local_timer_setup(struct clock_eve= nt_device *evt) =20 static void exynos4_local_timer_stop(struct clock_event_device *evt) { + struct mct_clock_event_device *mevt; + + mevt =3D container_of(evt, struct mct_clock_event_device, evt); + evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); if (mct_int_type =3D=3D MCT_INT_SPI) { if (evt->irq !=3D -1) disable_irq_nosync(evt->irq); + exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET); } else { disable_percpu_irq(mct_irqs[MCT_L0_IRQ]); } diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index c09ce1f040d3..1690cc09f905 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -590,7 +590,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/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index ba850eb2d275..3ec5509b1433 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -502,22 +502,29 @@ struct devfreq *devfreq_add_device(struct device *dev, list_add(&devfreq->node, &devfreq_list); =20 governor =3D find_devfreq_governor(devfreq->governor_name); - if (!IS_ERR(governor)) - devfreq->governor =3D governor; - if (devfreq->governor) - err =3D devfreq->governor->event_handler(devfreq, - DEVFREQ_GOV_START, NULL); - mutex_unlock(&devfreq_list_lock); + if (IS_ERR(governor)) { + dev_err(dev, "%s: Unable to find governor for the device\n", + __func__); + err =3D PTR_ERR(governor); + goto err_init; + } + + devfreq->governor =3D governor; + err =3D devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START, + NULL); if (err) { dev_err(dev, "%s: Unable to start governor for the device\n", __func__); goto err_init; } + mutex_unlock(&devfreq_list_lock); =20 return devfreq; =20 err_init: list_del(&devfreq->node); + mutex_unlock(&devfreq_list_lock); + device_unregister(&devfreq->dev); err_dev: kfree(devfreq); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index cb6d626dad02..18152350b32f 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -178,7 +178,8 @@ static int ast_get_dram_info(struct drm_device *dev) ast_write32(ast, 0x10000, 0xfc600309); =20 do { - ; + if (pci_channel_offline(dev->pdev)) + return -EIO; } while (ast_read32(ast, 0x10000) !=3D 0x01); data =3D ast_read32(ast, 0x10004); =20 @@ -369,7 +370,9 @@ int ast_driver_load(struct drm_device *dev, unsigned lo= ng flags) ast_detect_chip(dev); =20 if (ast->chip !=3D AST1180) { - ast_get_dram_info(dev); + ret =3D ast_get_dram_info(dev); + if (ret) + goto out_free; ast->vram_size =3D ast_get_vram_info(dev); DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bu= s_width, ast->vram_size); } diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_= drv.c index 6e8fe9ec02b5..efe5c3c7e8e2 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -464,6 +464,9 @@ static const struct file_operations psb_gem_fops =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, .read =3D drm_read, diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_= crt.c index bb3a6209b245..a0e7a2e20111 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -477,6 +477,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *= connector) struct drm_i915_private *dev_priv =3D crt->base.base.dev->dev_private; struct edid *edid; struct i2c_adapter *i2c; + bool ret =3D false; =20 BUG_ON(crt->base.type !=3D INTEL_OUTPUT_ANALOG); =20 @@ -493,17 +494,17 @@ static bool intel_crt_detect_ddc(struct drm_connector= *connector) */ if (!is_digital) { DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); - return true; + ret =3D true; + } else { + DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital pa= nel]\n"); } - - DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital pan= el]\n"); } else { DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [no valid EDID found]\n"); } =20 kfree(edid); =20 - return false; + return ret; } =20 static enum drm_connector_status diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/in= tel_display.c index 2041c5bbb929..03c76d17f0de 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8913,9 +8913,9 @@ static void do_intel_finish_page_flip(struct drm_devi= ce *dev, =20 wake_up_all(&dev_priv->pending_flip_queue); =20 - queue_work(dev_priv->wq, &work->work); - trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); + + queue_work(dev_priv->wq, &work->work); } =20 void intel_finish_page_flip(struct drm_device *dev, int pipe) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_p= m.c index 5010e2c32c23..aa83a835965c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5346,7 +5346,16 @@ static void valleyview_init_clock_gating(struct drm_= device *dev) DRM_DEBUG_DRIVER("Current CD clock rate: %d MHz", dev_priv->vlv_cdclk_freq); =20 - I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE); + /* + * On driver load, a pipe may be active and driving a DSI display. + * Preserve DPOUNIT_CLOCK_GATE_DISABLE to avoid the pipe getting stuck + * (and never recovering) in this case. intel_dsi_post_disable() will + * clear it when we turn off the display. + */ + val =3D I915_READ(DSPCLK_GATE_D); + val &=3D DPOUNIT_CLOCK_GATE_DISABLE; + val |=3D VRHUNIT_CLOCK_GATE_DISABLE; + I915_WRITE(DSPCLK_GATE_D, val); =20 /* WaDisableEarlyCull:vlv */ I915_WRITE(_3D_CHICKEN3, diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.c b/drivers/gpu/drm/nouvea= u/dispnv04/hw.c index aca76af115b3..1ddb10b32bbe 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/hw.c +++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c @@ -225,6 +225,7 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbio= s_pll_type plltype) uint32_t mpllP; =20 pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP); + mpllP =3D (mpllP >> 8) & 0xf; if (!mpllP) mpllP =3D 4; =20 @@ -235,7 +236,7 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbio= s_pll_type plltype) uint32_t clock; =20 pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock); - return clock; + return clock / 1000; } =20 ret =3D nouveau_hw_get_pllvals(dev, plltype, &pllvals); diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeo= n/radeon_cursor.c index 9630e8d95fb4..faacc400d6fa 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -90,6 +90,9 @@ static void radeon_show_cursor(struct drm_crtc *crtc) struct radeon_crtc *radeon_crtc =3D to_radeon_crtc(crtc); struct radeon_device *rdev =3D crtc->dev->dev_private; =20 + if (radeon_crtc->cursor_out_of_bounds) + return; + if (ASIC_IS_DCE4(rdev)) { WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset= ); WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | @@ -228,16 +231,17 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, x +=3D crtc->x; y +=3D crtc->y; } - DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); =20 - if (x < 0) { + if (x < 0) xorigin =3D min(-x, radeon_crtc->max_cursor_width - 1); - x =3D 0; - } - if (y < 0) { + if (y < 0) yorigin =3D min(-y, radeon_crtc->max_cursor_height - 1); - y =3D 0; + + if (!ASIC_IS_AVIVO(rdev)) { + x +=3D crtc->x; + y +=3D crtc->y; } + DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); =20 /* fixed on DCE6 and newer */ if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE6(rdev)) { @@ -260,27 +264,31 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, if (i > 1) { int cursor_end, frame_end; =20 - cursor_end =3D x - xorigin + w; + cursor_end =3D x + w; frame_end =3D crtc->x + crtc->mode.crtc_hdisplay; if (cursor_end >=3D frame_end) { w =3D w - (cursor_end - frame_end); if (!(frame_end & 0x7f)) w--; - } else { - if (!(cursor_end & 0x7f)) - w--; + } else if (cursor_end <=3D 0) { + goto out_of_bounds; + } else if (!(cursor_end & 0x7f)) { + w--; } if (w <=3D 0) { - w =3D 1; - cursor_end =3D x - xorigin + w; - if (!(cursor_end & 0x7f)) { - x--; - WARN_ON_ONCE(x < 0); - } + goto out_of_bounds; } } } =20 + if (x <=3D (crtc->x - w) || y <=3D (crtc->y - radeon_crtc->cursor_height)= || + x >=3D (crtc->x + crtc->mode.hdisplay) || + y >=3D (crtc->y + crtc->mode.vdisplay)) + goto out_of_bounds; + + x +=3D xorigin; + y +=3D yorigin; + radeon_lock_cursor(crtc, true); if (ASIC_IS_DCE4(rdev)) { WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y); @@ -293,6 +301,9 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset, ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); } else { + x -=3D crtc->x; + y -=3D crtc->y; + if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN) y *=3D 2; =20 @@ -310,5 +321,18 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, } radeon_lock_cursor(crtc, false); =20 + if (radeon_crtc->cursor_out_of_bounds) { + radeon_crtc->cursor_out_of_bounds =3D false; + if (radeon_crtc->cursor_bo) + radeon_show_cursor(crtc); + } + + return 0; + + out_of_bounds: + if (!radeon_crtc->cursor_out_of_bounds) { + radeon_hide_cursor(crtc); + radeon_crtc->cursor_out_of_bounds =3D true; + } return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/= radeon_mode.h index 0592ddb0904b..43c4fd754cbd 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -318,6 +318,7 @@ struct radeon_crtc { u16 lut_r[256], lut_g[256], lut_b[256]; bool enabled; bool can_tile; + bool cursor_out_of_bounds; uint32_t crtc_offset; struct drm_gem_object *cursor_bo; uint64_t cursor_addr; diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dp= m.c index c9b290b5b52b..2b04749ad314 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -2953,24 +2953,12 @@ static void si_apply_state_adjust_rules(struct rade= on_device *rdev, (rdev->pdev->device =3D=3D 0x6817) || (rdev->pdev->device =3D=3D 0x6806)) max_mclk =3D 120000; - } else if (rdev->family =3D=3D CHIP_VERDE) { - if ((rdev->pdev->revision =3D=3D 0x81) || - (rdev->pdev->revision =3D=3D 0x83) || - (rdev->pdev->revision =3D=3D 0x87) || - (rdev->pdev->device =3D=3D 0x6820) || - (rdev->pdev->device =3D=3D 0x6821) || - (rdev->pdev->device =3D=3D 0x6822) || - (rdev->pdev->device =3D=3D 0x6823) || - (rdev->pdev->device =3D=3D 0x682A) || - (rdev->pdev->device =3D=3D 0x682B)) { - max_sclk =3D 75000; - max_mclk =3D 80000; - } } else if (rdev->family =3D=3D CHIP_OLAND) { if ((rdev->pdev->revision =3D=3D 0xC7) || (rdev->pdev->revision =3D=3D 0x80) || (rdev->pdev->revision =3D=3D 0x81) || (rdev->pdev->revision =3D=3D 0x83) || + (rdev->pdev->revision =3D=3D 0x87) || (rdev->pdev->device =3D=3D 0x6604) || (rdev->pdev->device =3D=3D 0x6605)) { max_sclk =3D 75000; diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c index c4ef3bc726e3..e299576004ce 100644 --- a/drivers/hid/hid-cypress.c +++ b/drivers/hid/hid-cypress.c @@ -39,6 +39,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 0918b9136588..2a50ab613238 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/hwmon/g762.c b/drivers/hwmon/g762.c index 98a8618d8fbf..2811db085366 100644 --- a/drivers/hwmon/g762.c +++ b/drivers/hwmon/g762.c @@ -193,14 +193,17 @@ static inline unsigned int rpm_from_cnt(u8 cnt, u32 c= lk_freq, u16 p, * Convert fan RPM value from sysfs into count value for fan controller * register (FAN_SET_CNT). */ -static inline unsigned char cnt_from_rpm(u32 rpm, u32 clk_freq, u16 p, +static inline unsigned char cnt_from_rpm(unsigned long rpm, u32 clk_freq, = u16 p, u8 clk_div, u8 gear_mult) { - if (!rpm) /* to stop the fan, set cnt to 255 */ + unsigned long f1 =3D clk_freq * 30 * gear_mult; + unsigned long f2 =3D p * clk_div; + + if (!rpm) /* to stop the fan, set cnt to 255 */ return 0xff; =20 - return clamp_val(((clk_freq * 30 * gear_mult) / (rpm * p * clk_div)), - 0, 255); + rpm =3D clamp_val(rpm, f1 / (255 * f2), ULONG_MAX / f2); + return DIV_ROUND_CLOSEST(f1, rpm * f2); } =20 /* helper to grab and cache data, at most one time per second */ diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 80b47e8ce030..3baf4af1413a 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -334,7 +334,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/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mu= x-pca954x.c index f1b945509477..5419a356bfdd 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -133,6 +133,9 @@ static int pca954x_reg_write(struct i2c_adapter *adap, buf[0] =3D val; msg.buf =3D buf; ret =3D adap->algo->master_xfer(adap, &msg, 1); + + if (ret >=3D 0 && ret !=3D 1) + ret =3D -EREMOTEIO; } else { union i2c_smbus_data data; ret =3D adap->algo->smbus_xfer(adap, client->addr, @@ -161,7 +164,7 @@ static int pca954x_select_chan(struct i2c_adapter *adap, /* Only select the channel if its different from the last channel */ if (data->last_chan !=3D regval) { ret =3D pca954x_reg_write(adap, client, regval); - data->last_chan =3D ret ? 0 : regval; + data->last_chan =3D ret < 0 ? 0 : regval; } =20 return ret; diff --git a/drivers/iio/humidity/dht11.c b/drivers/iio/humidity/dht11.c index d8771f546bf2..bd7c386d5878 100644 --- a/drivers/iio/humidity/dht11.c +++ b/drivers/iio/humidity/dht11.c @@ -44,7 +44,8 @@ #define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE= + 1) =20 /* Data transmission timing (nano seconds) */ -#define DHT11_START_TRANSMISSION 18 /* ms */ +#define DHT11_START_TRANSMISSION_MIN 18000 /* us */ +#define DHT11_START_TRANSMISSION_MAX 20000 /* us */ #define DHT11_SENSOR_RESPONSE 80000 #define DHT11_START_BIT 50000 #define DHT11_DATA_BIT_LOW 27000 @@ -152,7 +153,8 @@ static int dht11_read_raw(struct iio_dev *iio_dev, ret =3D gpio_direction_output(dht11->gpio, 0); if (ret) goto err; - msleep(DHT11_START_TRANSMISSION); + usleep_range(DHT11_START_TRANSMISSION_MIN, + DHT11_START_TRANSMISSION_MAX); ret =3D gpio_direction_input(dht11->gpio); if (ret) goto err; diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index ab31f136d04b..5b66fedaacc3 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1607,7 +1607,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/core/uverbs_cmd.c b/drivers/infiniband/core= /uverbs_cmd.c index 5e66eab292d8..ce649a7ffa56 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -2764,7 +2764,6 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *f= ile, err =3D PTR_ERR(flow_id); goto err_free; } - flow_id->qp =3D qp; flow_id->uobject =3D uobj; uobj->object =3D flow_id; =20 diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verb= s.c index c2b89cc5dbca..0c859f7fb7a4 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1420,8 +1420,10 @@ struct ib_flow *ib_create_flow(struct ib_qp *qp, return ERR_PTR(-ENOSYS); =20 flow_id =3D qp->device->create_flow(qp, flow_attr, domain); - if (!IS_ERR(flow_id)) + if (!IS_ERR(flow_id)) { atomic_inc(&qp->usecnt); + flow_id->qp =3D qp; + } return flow_id; } EXPORT_SYMBOL(ib_create_flow); diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/c= xgb4/device.c index 7db82b24302b..ea8ce383e57d 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -694,6 +694,7 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) __get_free_page(GFP_KERNEL); if (!rdev->status_page) { pr_err(MOD "error allocating status page\n"); + err =3D -ENOMEM; goto err4; } rdev->status_page->db_off =3D 0; diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/a= h.c index 4c2686514ced..62aa7d9422a4 100644 --- a/drivers/infiniband/hw/mlx4/ah.c +++ b/drivers/infiniband/hw/mlx4/ah.c @@ -97,7 +97,9 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, str= uct ib_ah_attr *ah_attr !(1 << ah->av.eth.stat_rate & dev->caps.stat_rate_support)) --ah->av.eth.stat_rate; } - + ah->av.eth.sl_tclass_flowlabel |=3D + cpu_to_be32((ah_attr->grh.traffic_class << 20) | + ah_attr->grh.flow_label); /* * HW requires multicast LID so we just choose one. */ @@ -105,7 +107,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, s= truct ib_ah_attr *ah_attr ah->av.ib.dlid =3D cpu_to_be16(0xc000); =20 memcpy(ah->av.eth.dgid, ah_attr->grh.dgid.raw, 16); - ah->av.eth.sl_tclass_flowlabel =3D cpu_to_be32(ah_attr->sl << 29); + ah->av.eth.sl_tclass_flowlabel |=3D cpu_to_be32(ah_attr->sl << 29); =20 return &ah->ibah; } diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4= /main.c index 85c47a0e524c..1397da73f636 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -212,6 +212,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 dev->dev->caps.max_fmr_maps; + props->max_ah =3D INT_MAX; =20 out: kfree(in_mad); @@ -345,9 +346,11 @@ static int eth_link_query_port(struct ib_device *ibdev= , u8 port, if (err) goto out; =20 - props->active_width =3D (((u8 *)mailbox->buf)[5] =3D=3D 0x40) ? - IB_WIDTH_4X : IB_WIDTH_1X; - props->active_speed =3D IB_SPEED_QDR; + props->active_width =3D (((u8 *)mailbox->buf)[5] =3D=3D 0x40) || + (((u8 *)mailbox->buf)[5] =3D=3D 0x20 /*56Gb*/) ? + IB_WIDTH_4X : IB_WIDTH_1X; + props->active_speed =3D (((u8 *)mailbox->buf)[5] =3D=3D 0x20 /*56Gb*/) ? + IB_SPEED_FDR : IB_SPEED_QDR; props->port_cap_flags =3D IB_PORT_CM_SUP | IB_PORT_IP_BASED_GIDS; props->gid_tbl_len =3D mdev->dev->caps.gid_table_len[port]; props->max_msg_sz =3D mdev->dev->caps.max_msg_sz; @@ -2156,14 +2159,19 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) goto err_steer_qp_release; } =20 - bitmap_zero(ibdev->ib_uc_qpns_bitmap, ibdev->steer_qpn_count); - - err =3D mlx4_FLOW_STEERING_IB_UC_QP_RANGE( - dev, ibdev->steer_qpn_base, - ibdev->steer_qpn_base + - ibdev->steer_qpn_count - 1); - if (err) - goto err_steer_free_bitmap; + if (dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_DMFS_IPOIB) { + bitmap_zero(ibdev->ib_uc_qpns_bitmap, + ibdev->steer_qpn_count); + err =3D mlx4_FLOW_STEERING_IB_UC_QP_RANGE( + dev, ibdev->steer_qpn_base, + ibdev->steer_qpn_base + + ibdev->steer_qpn_count - 1); + if (err) + goto err_steer_free_bitmap; + } else { + bitmap_fill(ibdev->ib_uc_qpns_bitmap, + ibdev->steer_qpn_count); + } } =20 if (ib_register_device(&ibdev->ib_dev, NULL)) diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/q= p.c index 6f50a21331ed..3e1ea0323983 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1153,7 +1153,8 @@ int mlx4_ib_destroy_qp(struct ib_qp *qp) if (is_qp0(dev, mqp)) mlx4_CLOSE_PORT(dev->dev, mqp->port); =20 - if (dev->qp1_proxy[mqp->port - 1] =3D=3D mqp) { + if (mqp->mlx4_ib_qp_type =3D=3D MLX4_IB_QPT_PROXY_GSI && + dev->qp1_proxy[mqp->port - 1] =3D=3D mqp) { mutex_lock(&dev->qp1_proxy_lock[mqp->port - 1]); dev->qp1_proxy[mqp->port - 1] =3D NULL; mutex_unlock(&dev->qp1_proxy_lock[mqp->port - 1]); diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5= /main.c index cad8cab43559..cb938822a91c 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -319,6 +319,7 @@ static int mlx5_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 INT_MAX; /* no limit in ConnectIB */ + props->max_ah =3D INT_MAX; =20 out: kfree(in_mad); diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/m= r.c index bf75b943bc31..d1fd8b8f65f0 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -590,6 +590,33 @@ int mlx5_mr_cache_init(struct mlx5_ib_dev *dev) return 0; } =20 +static void wait_for_async_commands(struct mlx5_ib_dev *dev) +{ + struct mlx5_mr_cache *cache =3D &dev->cache; + struct mlx5_cache_ent *ent; + int total =3D 0; + int i; + int j; + + for (i =3D 0; i < MAX_MR_CACHE_ENTRIES; i++) { + ent =3D &cache->ent[i]; + for (j =3D 0 ; j < 1000; j++) { + if (!ent->pending) + break; + msleep(50); + } + } + for (i =3D 0; i < MAX_MR_CACHE_ENTRIES; i++) { + ent =3D &cache->ent[i]; + total +=3D ent->pending; + } + + if (total) + mlx5_ib_warn(dev, "aborted while there are %d pending mr requests\n", to= tal); + else + mlx5_ib_warn(dev, "done with all pending requests\n"); +} + int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev) { int i; @@ -603,6 +630,7 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev) clean_keys(dev, i); =20 destroy_workqueue(dev->cache.wq); + wait_for_async_commands(dev); del_timer_sync(&dev->delay_timer); =20 return 0; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/u= lp/ipoib/ipoib_cm.c index 9bf0c8f59d54..6f29bd05441f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -1038,8 +1038,6 @@ static struct ib_qp *ipoib_cm_create_tx_qp(struct net= _device *dev, struct ipoib_ =20 tx_qp =3D ib_create_qp(priv->pd, &attr); if (PTR_ERR(tx_qp) =3D=3D -EINVAL) { - ipoib_warn(priv, "can't use GFP_NOIO for QPs on device %s, using GFP_KER= NEL\n", - priv->ca->name); attr.create_flags &=3D ~IB_QP_CREATE_USE_GFP_NOIO; tx_qp =3D ib_create_qp(priv->pd, &attr); } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infin= iband/ulp/ipoib/ipoib_multicast.c index d4e005720d01..0b0f2c77d74d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -523,8 +523,11 @@ void ipoib_mcast_join_task(struct work_struct *work) if (!test_bit(IPOIB_MCAST_RUN, &priv->flags)) return; =20 - if (ib_query_port(priv->ca, priv->port, &port_attr) || - port_attr.state !=3D IB_PORT_ACTIVE) { + if (ib_query_port(priv->ca, priv->port, &port_attr)) { + ipoib_dbg(priv, "ib_query_port() failed\n"); + return; + } + if (port_attr.state !=3D IB_PORT_ACTIVE) { ipoib_dbg(priv, "port state is not ACTIVE (state =3D %d) suspending join= task\n", port_attr.state); return; diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8= 042-x86ia64io.h index ccb36fb565de..3f3c517f2039 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 76c71ecba656..07af55cc2dcc 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1044,7 +1044,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/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/= eicon/message.c index a82e542ffc21..fecbf1d2f60b 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c @@ -11304,7 +11304,8 @@ static void mixer_notify_update(PLCI *plci, byte ot= hers) ((CAPI_MSG *) msg)->header.ncci =3D 0; ((CAPI_MSG *) msg)->info.facility_req.Selector =3D SELECTOR_LINE_INTER= CONNECT; ((CAPI_MSG *) msg)->info.facility_req.structs[0] =3D 3; - PUT_WORD(&(((CAPI_MSG *) msg)->info.facility_req.structs[1]), LI_REQ_S= ILENT_UPDATE); + ((CAPI_MSG *) msg)->info.facility_req.structs[1] =3D LI_REQ_SILENT_UPD= ATE & 0xff; + ((CAPI_MSG *) msg)->info.facility_req.structs[2] =3D LI_REQ_SILENT_UPD= ATE >> 8; ((CAPI_MSG *) msg)->info.facility_req.structs[3] =3D 0; w =3D api_put(notify_plci->appl, (CAPI_MSG *) msg); if (w !=3D _QUEUE_FULL) diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 34e7db1e7304..c43187b4dc0e 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -1449,12 +1449,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/md/dm.c b/drivers/md/dm.c index 35caa4c17c3d..d043e50ebea7 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -868,6 +868,9 @@ static void end_clone_bio(struct bio *clone, int error) */ static void rq_completed(struct mapped_device *md, int rw, int run_queue) { + struct request_queue *q =3D md->queue; + unsigned long flags; + atomic_dec(&md->pending[rw]); =20 /* nudge anyone waiting on suspend queue */ @@ -880,8 +883,11 @@ static void rq_completed(struct mapped_device *md, int= rw, int run_queue) * back into ->request_fn() could deadlock attempting to grab the * queue lock again. */ - if (run_queue) - blk_run_queue_async(md->queue); + if (run_queue) { + spin_lock_irqsave(q->queue_lock, flags); + blk_run_queue_async(q); + spin_unlock_irqrestore(q->queue_lock, flags); + } =20 /* * dm_put() must be at the end of this function. See the comment above diff --git a/drivers/md/md.c b/drivers/md/md.c index 60d57bad30bb..4db092cf3a1d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6453,7 +6453,7 @@ static int md_ioctl(struct block_device *bdev, fmode_= t mode, /* need to ensure recovery thread has run */ wait_event_interruptible_timeout(mddev->sb_wait, !test_bit(MD_RECOVERY_NEEDED, - &mddev->flags), + &mddev->recovery), msecs_to_jiffies(5000)); if (cmd =3D=3D STOP_ARRAY || cmd =3D=3D STOP_ARRAY_RO) { /* Need to flush page cache, and ensure no-one else opens diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/m= d/persistent-data/dm-space-map-metadata.c index 032ee39a0e9b..8114a29839c4 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.c +++ b/drivers/md/persistent-data/dm-space-map-metadata.c @@ -773,17 +773,15 @@ int dm_sm_metadata_create(struct dm_space_map *sm, memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm)); =20 r =3D sm_ll_new_metadata(&smm->ll, tm); + if (!r) { + if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS) + nr_blocks =3D DM_SM_METADATA_MAX_BLOCKS; + r =3D sm_ll_extend(&smm->ll, nr_blocks); + } + memcpy(&smm->sm, &ops, sizeof(smm->sm)); if (r) return r; =20 - if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS) - nr_blocks =3D DM_SM_METADATA_MAX_BLOCKS; - r =3D sm_ll_extend(&smm->ll, nr_blocks); - if (r) - return r; - - memcpy(&smm->sm, &ops, sizeof(smm->sm)); - /* * Now we need to update the newly created data structures with the * allocated blocks that they were built from. diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 9d9d757a3488..63a094166138 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6222,6 +6222,15 @@ static int run(struct mddev *mddev) stripe =3D (stripe | (stripe-1)) + 1; mddev->queue->limits.discard_alignment =3D stripe; mddev->queue->limits.discard_granularity =3D stripe; + + /* + * We use 16-bit counter of active stripes in bi_phys_segments + * (minus one for over-loaded initialization) + */ + blk_queue_max_hw_sectors(mddev->queue, 0xfffe * STRIPE_SECTORS); + blk_queue_max_discard_sectors(mddev->queue, + 0xfffe * STRIPE_SECTORS); + /* * unaligned part of discard request will be ignored, so can't * guarantee discard_zeroes_data diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 441053be7f55..42be1e944b88 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -590,6 +590,7 @@ config VIDEO_S5K6A3 config VIDEO_S5K4ECGX tristate "Samsung S5K4ECGX sensor support" depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + select CRC32 ---help--- This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M camera sensor with an embedded SoC image signal processor. diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/= platform/davinci/vpfe_capture.c index a51bda2fb637..ff10c2e90a5a 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1967,6 +1967,7 @@ static 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/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index ab24cc6d3655..65740093403e 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/usb/siano/smsusb.c b/drivers/media/usb/siano/sms= usb.c index 89c86ee2b225..dcb8d14e5bf5 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -206,22 +206,30 @@ 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; - struct sms_msg_hdr *phdr =3D (struct sms_msg_hdr *) buffer; - int dummy; + struct sms_msg_hdr *phdr; + int dummy, ret; =20 if (dev->state !=3D SMSUSB_ACTIVE) { sms_debug("Device not active yet"); return -ENOENT; } =20 + phdr =3D kmalloc(size, GFP_KERNEL); + if (!phdr) + return -ENOMEM; + memcpy(phdr, buffer, size); + sms_debug("sending %s(%d) size: %d", smscore_translate_msg(phdr->msg_type), phdr->msg_type, phdr->msg_length); =20 smsendian_handle_tx_message((struct sms_msg_data *) phdr); - smsendian_handle_message_header((struct sms_msg_hdr *)buffer); - return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), - buffer, size, &dummy, 1000); + smsendian_handle_message_header((struct sms_msg_hdr *)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/misc/mei/client.c b/drivers/misc/mei/client.c index a4afa996d413..ed845efa8fd4 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -819,7 +819,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_c= b *cb, =20 rets =3D mei_cl_flow_ctrl_creds(cl); if (rets < 0) - return rets; + goto err; =20 if (rets =3D=3D 0) { cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); @@ -853,23 +853,27 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl= _cb *cb, cb->request_buffer.size, cb->buf_idx); =20 rets =3D mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx); - if (rets) { - cl->status =3D rets; - list_move_tail(&cb->list, &cmpl_list->list); - return rets; - } + if (rets) + goto err; =20 cl->status =3D 0; cl->writing_state =3D MEI_WRITING; cb->buf_idx +=3D mei_hdr.length; =20 if (mei_hdr.msg_complete) { - if (mei_cl_flow_ctrl_reduce(cl)) - return -EIO; + if (mei_cl_flow_ctrl_reduce(cl)) { + rets =3D -EIO; + goto err; + } list_move_tail(&cb->list, &dev->write_waiting_list.list); } =20 return 0; + +err: + cl->status =3D rets; + list_move_tail(&cb->list, &cmpl_list->list); + return rets; } =20 /** diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 094ba8b8dc3a..d87f81f3eae4 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1391,10 +1391,10 @@ static int mmc_init_card(struct mmc_host *host, u32= ocr, err =3D mmc_select_hs400(card); if (err) goto err; - } else if (mmc_card_hs(card)) { + } else { /* Select the desired bus width optionally */ err =3D mmc_select_bus_width(card); - if (!IS_ERR_VALUE(err)) { + if (!IS_ERR_VALUE(err) && mmc_card_hs(card)) { err =3D mmc_select_hs_ddr(card); if (err) goto err; diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index ad32f235bdb8..5bbc0e64bab5 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -308,6 +308,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; @@ -416,8 +419,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) ssp->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/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 5114206df053..79d7a10028be 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1959,7 +1959,27 @@ static int sdhci_execute_tuning(struct mmc_host *mmc= , u32 opcode) ctrl &=3D ~SDHCI_CTRL_EXEC_TUNING; sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); =20 + sdhci_do_reset(host, SDHCI_RESET_CMD); + sdhci_do_reset(host, SDHCI_RESET_DATA); + err =3D -EIO; + + if (cmd.opcode !=3D MMC_SEND_TUNING_BLOCK_HS200) + goto out; + + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); + + spin_unlock_irqrestore(&host->lock, flags); + + memset(&cmd, 0, sizeof(cmd)); + cmd.opcode =3D MMC_STOP_TRANSMISSION; + cmd.flags =3D MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + cmd.busy_timeout =3D 50; + mmc_wait_for_cmd(mmc, &cmd, 0); + + spin_lock_irqsave(&host->lock, flags); + goto out; } =20 @@ -2465,7 +2485,8 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) pr_err("%s: Card is consuming too much power!\n", mmc_hostname(host->mmc)); =20 - if (intmask & SDHCI_INT_CARD_INT) { + if ((intmask & SDHCI_INT_CARD_INT) && + (host->ier & SDHCI_INT_CARD_INT)) { sdhci_enable_sdio_irq_nolock(host, false); host->thread_isr |=3D SDHCI_INT_CARD_INT; result =3D IRQ_WAKE_THREAD; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index f1cf503517fd..fa1bb0223a02 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -506,7 +506,7 @@ config MTD_NAND_FSMC Flexible Static Memory Controller (FSMC) =20 config MTD_NAND_XWAY - tristate "Support for NAND on Lantiq XWAY SoC" + bool "Support for NAND on Lantiq XWAY SoC" depends on LANTIQ && SOC_TYPE_XWAY select MTD_NAND_PLATFORM help diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_= netlink.c index 8626bc0cb2af..1b7545680eae 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c @@ -365,7 +365,11 @@ static int bond_newlink(struct net *src_net, struct ne= t_device *bond_dev, if (err < 0) return err; =20 - return register_netdevice(bond_dev); + err =3D register_netdevice(bond_dev); + + netif_carrier_off(bond_dev); + + return err; } =20 static size_t bond_get_size(const struct net_device *bond_dev) diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_ca= n_pci.c index 5d11e0e4225b..b997508ea7c6 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c @@ -161,6 +161,7 @@ static int c_can_pci_probe(struct pci_dev *pdev, =20 dev->irq =3D pdev->irq; priv->base =3D addr; + priv->device =3D &pdev->dev; =20 if (!c_can_pci_data->freq) { dev_err(&pdev->dev, "no clock frequency defined\n"); diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 258b9c4856ec..386d2c02e18f 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -950,7 +950,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"); @@ -983,7 +988,7 @@ static int ti_hecc_remove(struct platform_device *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); @@ -1008,7 +1013,7 @@ static int ti_hecc_suspend(struct platform_device *pd= ev, 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; } @@ -1017,8 +1022,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/atheros/alx/main.c b/drivers/net/ethernet= /atheros/alx/main.c index e751b5db0132..04c85b94754f 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -86,9 +86,14 @@ static int alx_refill_rx_ring(struct alx_priv *alx, gfp_= t gfp) while (!cur_buf->skb && next !=3D rxq->read_idx) { struct alx_rfd *rfd =3D &rxq->rfd[cur]; =20 - skb =3D __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp); + skb =3D __netdev_alloc_skb(alx->dev, alx->rxbuf_size + 64, gfp); if (!skb) break; + + /* Workround for the HW RX DMA overflow issue */ + if (((unsigned long)skb->data & 0xfff) =3D=3D 0xfc0) + skb_reserve(skb, 64); + dma =3D dma_map_single(&alx->hw.pdev->dev, skb->data, alx->rxbuf_size, DMA_FROM_DEVICE); diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ether= net/broadcom/bcmsysport.c index 3cca6047578b..4d762138eb39 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -587,11 +587,8 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bc= m_sysport_priv *priv, unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs; unsigned int pkts_compl =3D 0, bytes_compl =3D 0; struct bcm_sysport_cb *cb; - struct netdev_queue *txq; u32 hw_ind; =20 - txq =3D netdev_get_tx_queue(ndev, ring->index); - /* Compute how many descriptors have been processed since last call */ hw_ind =3D tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index)); c_index =3D (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK; @@ -622,9 +619,6 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm= _sysport_priv *priv, =20 ring->c_index =3D c_index; =20 - if (netif_tx_queue_stopped(txq) && pkts_compl) - netif_tx_wake_queue(txq); - netif_dbg(priv, tx_done, ndev, "ring=3D%d c_index=3D%d pkts_compl=3D%d, bytes_compl=3D%d\n", ring->index, ring->c_index, pkts_compl, bytes_compl); @@ -636,16 +630,33 @@ static unsigned int __bcm_sysport_tx_reclaim(struct b= cm_sysport_priv *priv, static unsigned int bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv, struct bcm_sysport_tx_ring *ring) { + struct netdev_queue *txq; unsigned int released; unsigned long flags; =20 + txq =3D netdev_get_tx_queue(priv->netdev, ring->index); + spin_lock_irqsave(&ring->lock, flags); released =3D __bcm_sysport_tx_reclaim(priv, ring); + if (released) + netif_tx_wake_queue(txq); + spin_unlock_irqrestore(&ring->lock, flags); =20 return released; } =20 +/* Locked version of the per-ring TX reclaim, but does not wake the queue = */ +static void bcm_sysport_tx_clean(struct bcm_sysport_priv *priv, + struct bcm_sysport_tx_ring *ring) +{ + unsigned long flags; + + spin_lock_irqsave(&ring->lock, flags); + __bcm_sysport_tx_reclaim(priv, ring); + spin_unlock_irqrestore(&ring->lock, flags); +} + static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget) { struct bcm_sysport_tx_ring *ring =3D @@ -843,15 +854,6 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *sk= b, goto out; } =20 - /* Insert TSB and checksum infos */ - if (priv->tsb_en) { - skb =3D bcm_sysport_insert_tsb(skb, dev); - if (!skb) { - ret =3D NETDEV_TX_OK; - goto out; - } - } - /* The Ethernet switch we are interfaced with needs packets to be at * least 64 bytes (including FCS) otherwise they will be discarded when * they enter the switch port logic. When Broadcom tags are enabled, we @@ -864,6 +866,15 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *sk= b, goto out; } =20 + /* Insert TSB and checksum infos */ + if (priv->tsb_en) { + skb =3D bcm_sysport_insert_tsb(skb, dev); + if (!skb) { + ret =3D NETDEV_TX_OK; + goto out; + } + } + skb_len =3D skb->len < ETH_ZLEN + ENET_BRCM_TAG_LEN ? ETH_ZLEN + ENET_BRCM_TAG_LEN : skb->len; =20 @@ -1072,7 +1083,7 @@ static void bcm_sysport_fini_tx_ring(struct bcm_syspo= rt_priv *priv, napi_disable(&ring->napi); netif_napi_del(&ring->napi); =20 - bcm_sysport_tx_reclaim(priv, ring); + bcm_sysport_tx_clean(priv, ring); =20 kfree(ring->cbs); ring->cbs =3D NULL; diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethe= rnet/cisco/enic/enic_main.c index fb9708d4b8b5..720eed57d255 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -1033,12 +1033,18 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, skb->protocol =3D eth_type_trans(skb, netdev); skb_record_rx_queue(skb, q_number); if (netdev->features & NETIF_F_RXHASH) { - skb_set_hash(skb, rss_hash, - (rss_type & - (NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX | - NIC_CFG_RSS_HASH_TYPE_TCP_IPV6 | - NIC_CFG_RSS_HASH_TYPE_TCP_IPV4)) ? - PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); + switch (rss_type) { + case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv4: + case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6: + case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6_EX: + skb_set_hash(skb, rss_hash, PKT_HASH_TYPE_L4); + break; + case CQ_ENET_RQ_DESC_RSS_TYPE_IPv4: + case CQ_ENET_RQ_DESC_RSS_TYPE_IPv6: + case CQ_ENET_RQ_DESC_RSS_TYPE_IPv6_EX: + skb_set_hash(skb, rss_hash, PKT_HASH_TYPE_L3); + break; + } } =20 /* Hardware does not provide whole packet checksum. It only diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethe= rnet/emulex/benet/be_cmds.c index f4ea3490f446..8dc7f7221fa1 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -1008,7 +1008,7 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *m= ac_addr, err: spin_unlock_bh(&adapter->mcc_lock); =20 - if (status =3D=3D MCC_STATUS_UNAUTHORIZED_REQUEST) + if (base_status(status) =3D=3D MCC_STATUS_UNAUTHORIZED_REQUEST) status =3D -EPERM; =20 return status; diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c index d74f5f4e5782..07eabf72c480 100644 --- a/drivers/net/ethernet/korina.c +++ b/drivers/net/ethernet/korina.c @@ -900,10 +900,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; @@ -1064,12 +1064,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 69693384b58c..d72c33cbaeeb 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -5211,6 +5211,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 56022d647837..6bb0521b09a3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/cq.c @@ -56,13 +56,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_dbg(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); @@ -73,23 +79,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int e= vent_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, @@ -256,9 +258,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, if (err) return err; =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_icm; =20 @@ -297,9 +299,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, 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_icm: mlx4_cq_free_icm(dev, cq->cqn); @@ -318,11 +320,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 76879a1cca6f..b07f4c0d617b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -437,8 +437,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; @@ -500,8 +506,11 @@ void mlx4_en_recover_from_oom(struct mlx4_en_priv *pri= v) return; =20 for (ring =3D 0; ring < priv->rx_ring_num; ring++) { - if (mlx4_en_is_ring_empty(priv->rx_ring[ring])) + if (mlx4_en_is_ring_empty(priv->rx_ring[ring])) { + local_bh_disable(); napi_reschedule(&priv->rx_cq[ring]->napi); + local_bh_enable(); + } } } =20 diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet= /mellanox/mlx4/eq.c index c26eec5f33c3..e79dbd9ff066 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -506,8 +506,9 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx= 4_eq *eq) break; =20 case MLX4_EVENT_TYPE_SRQ_LIMIT: - mlx4_dbg(dev, "%s: MLX4_EVENT_TYPE_SRQ_LIMIT\n", - __func__); + mlx4_dbg(dev, "%s: MLX4_EVENT_TYPE_SRQ_LIMIT. srq_no=3D0x%x, eq 0x%x\n", + __func__, be32_to_cpu(eqe->event.srq.srqn), + eq->eqn); case MLX4_EVENT_TYPE_SRQ_CATAS_ERROR: if (mlx4_is_master(dev)) { /* forward only to slave owning the SRQ */ @@ -522,15 +523,19 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct m= lx4_eq *eq) eq->eqn, eq->cons_index, ret); break; } - mlx4_warn(dev, "%s: slave:%d, srq_no:0x%x, event: %02x(%02x)\n", - __func__, slave, - be32_to_cpu(eqe->event.srq.srqn), - eqe->type, eqe->subtype); + if (eqe->type =3D=3D + MLX4_EVENT_TYPE_SRQ_CATAS_ERROR) + mlx4_warn(dev, "%s: slave:%d, srq_no:0x%x, event: %02x(%02x)\n", + __func__, slave, + be32_to_cpu(eqe->event.srq.srqn), + eqe->type, eqe->subtype); =20 if (!ret && slave !=3D dev->caps.function) { - mlx4_warn(dev, "%s: sending event %02x(%02x) to slave:%d\n", - __func__, eqe->type, - eqe->subtype, slave); + if (eqe->type =3D=3D + MLX4_EVENT_TYPE_SRQ_CATAS_ERROR) + mlx4_warn(dev, "%s: sending event %02x(%02x) to slave:%d\n", + __func__, eqe->type, + eqe->subtype, slave); mlx4_slave_event(dev, slave, eqe); break; } diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/etherne= t/mellanox/mlx4/icm.c index 97c9b1db1d27..27f22cd3b071 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.c +++ b/drivers/net/ethernet/mellanox/mlx4/icm.c @@ -117,8 +117,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/mellanox/mlx4/resource_tracker.c b/driver= s/net/ethernet/mellanox/mlx4/resource_tracker.c index 90269b3013b6..bee566803b5d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -2733,6 +2733,9 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, in= t slave, put_res(dev, slave, srqn, RES_SRQ); qp->srq =3D srq; } + + /* Save param3 for dynamic changes from VST back to VGT */ + qp->param3 =3D qpc->param3; put_res(dev, slave, rcqn, RES_CQ); put_res(dev, slave, mtt_base, RES_MTT); res_end_move(dev, slave, RES_QP, qpn); @@ -3495,7 +3498,6 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, in= t slave, int qpn =3D vhcr->in_modifier & 0x7fffff; struct res_qp *qp; u8 orig_sched_queue; - __be32 orig_param3 =3D qpc->param3; u8 orig_vlan_control =3D qpc->pri_path.vlan_control; u8 orig_fvl_rx =3D qpc->pri_path.fvl_rx; u8 orig_pri_path_fl =3D qpc->pri_path.fl; @@ -3536,7 +3538,6 @@ out: */ if (!err) { qp->sched_queue =3D orig_sched_queue; - qp->param3 =3D orig_param3; qp->vlan_control =3D orig_vlan_control; qp->fvl_rx =3D orig_fvl_rx; qp->pri_path_fl =3D orig_pri_path_fl; @@ -4091,6 +4092,7 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_= dev *dev, int slave, int err; struct res_qp *rqp; struct res_fs_rule *rrule; + int qpn; =20 if (dev->caps.steering_mode !=3D MLX4_STEERING_MODE_DEVICE_MANAGED) @@ -4099,9 +4101,10 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4= _dev *dev, int slave, err =3D get_res(dev, slave, vhcr->in_param, RES_FS_RULE, &rrule); if (err) return err; + qpn =3D rrule->qpn; /* Release the rule form busy state before removal */ put_res(dev, slave, vhcr->in_param, RES_FS_RULE); - err =3D get_res(dev, slave, rrule->qpn, RES_QP, &rqp); + err =3D get_res(dev, slave, qpn, RES_QP, &rqp); if (err) return err; =20 @@ -4117,7 +4120,7 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_= dev *dev, int slave, if (!err) atomic_dec(&rqp->ref_count); out: - put_res(dev, slave, rrule->qpn, RES_QP); + put_res(dev, slave, qpn, RES_QP); return err; } =20 diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/r= enesas/sh_eth.c index f1ebb1f50f1c..9a03bfd51397 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -696,7 +696,7 @@ static struct sh_eth_cpu_data sh7734_data =3D { =20 .ecsr_value =3D ECSR_ICD | ECSR_MPD, .ecsipr_value =3D ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, - .eesipr_value =3D DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, + .eesipr_value =3D DMAC_M_RFRMER | DMAC_M_ECI | 0x003f07ff, =20 .tx_check =3D EESR_TC1 | EESR_FTC, .eesr_err_check =3D EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | @@ -713,6 +713,7 @@ static struct sh_eth_cpu_data sh7734_data =3D { .tsu =3D 1, .hw_crc =3D 1, .select_mii =3D 1, + .shift_rd0 =3D 1, }; =20 /* SH7763 */ @@ -725,7 +726,7 @@ static struct sh_eth_cpu_data sh7763_data =3D { =20 .ecsr_value =3D ECSR_ICD | ECSR_MPD, .ecsipr_value =3D ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, - .eesipr_value =3D DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, + .eesipr_value =3D DMAC_M_RFRMER | DMAC_M_ECI | 0x003f07ff, =20 .tx_check =3D EESR_TC1 | EESR_FTC, .eesr_err_check =3D EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | @@ -781,6 +782,7 @@ static struct sh_eth_cpu_data r8a7740_data =3D { .rpadir_value =3D 2 << 16, .no_trimd =3D 1, .no_ade =3D 1, + .hw_crc =3D 1, .tsu =3D 1, .select_mii =3D 1, .shift_rd0 =3D 1, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/ne= t/ethernet/stmicro/stmmac/stmmac_main.c index 641086fc14b5..76fd3a2fa742 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2769,12 +2769,6 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *= device, spin_lock_init(&priv->lock); spin_lock_init(&priv->tx_lock); =20 - ret =3D register_netdev(ndev); - if (ret) { - pr_err("%s: ERROR %i registering the device\n", __func__, ret); - goto error_netdev_register; - } - /* If a specific clk_csr value is passed from the platform * this means that the CSR Clock Range selection cannot be * changed at run-time and it is fixed. Viceversa the driver'll try to @@ -2799,11 +2793,21 @@ struct stmmac_priv *stmmac_dvr_probe(struct device = *device, } } =20 + ret =3D register_netdev(ndev); + if (ret) { + netdev_err(priv->dev, "%s: ERROR %i registering the device\n", + __func__, ret); + goto error_netdev_register; + } + return priv; =20 -error_mdio_register: - unregister_netdev(ndev); error_netdev_register: + if (priv->pcs !=3D STMMAC_PCS_RGMII && + priv->pcs !=3D STMMAC_PCS_TBI && + priv->pcs !=3D STMMAC_PCS_RTBI) + stmmac_mdio_unregister(ndev); +error_mdio_register: netif_napi_del(&priv->napi); error_hw_init: clk_disable_unprepare(priv->stmmac_clk); diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/et= hernet/xilinx/xilinx_emaclite.c index 8c4aed3053eb..06b5e4132040 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -100,6 +100,14 @@ /* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment.= */ #define BUFFER_ALIGN(adr) ((ALIGNMENT - ((u32) adr)) % ALIGNMENT) =20 +#ifdef __BIG_ENDIAN +#define xemaclite_readl ioread32be +#define xemaclite_writel iowrite32be +#else +#define xemaclite_readl ioread32 +#define xemaclite_writel iowrite32 +#endif + /** * struct net_local - Our private per device data * @ndev: instance of the network device @@ -158,15 +166,15 @@ static void xemaclite_enable_interrupts(struct net_lo= cal *drvdata) u32 reg_data; =20 /* Enable the Tx interrupts for the first Buffer */ - reg_data =3D __raw_readl(drvdata->base_addr + XEL_TSR_OFFSET); - __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, - drvdata->base_addr + XEL_TSR_OFFSET); + reg_data =3D xemaclite_readl(drvdata->base_addr + XEL_TSR_OFFSET); + xemaclite_writel(reg_data | XEL_TSR_XMIT_IE_MASK, + drvdata->base_addr + XEL_TSR_OFFSET); =20 /* Enable the Rx interrupts for the first buffer */ - __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET); + xemaclite_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSE= T); =20 /* Enable the Global Interrupt Enable */ - __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); + xemaclite_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); } =20 /** @@ -181,17 +189,17 @@ static void xemaclite_disable_interrupts(struct net_l= ocal *drvdata) u32 reg_data; =20 /* Disable the Global Interrupt Enable */ - __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); + xemaclite_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); =20 /* Disable the Tx interrupts for the first buffer */ - reg_data =3D __raw_readl(drvdata->base_addr + XEL_TSR_OFFSET); - __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), - drvdata->base_addr + XEL_TSR_OFFSET); + reg_data =3D xemaclite_readl(drvdata->base_addr + XEL_TSR_OFFSET); + xemaclite_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), + drvdata->base_addr + XEL_TSR_OFFSET); =20 /* Disable the Rx interrupts for the first buffer */ - reg_data =3D __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET); - __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), - drvdata->base_addr + XEL_RSR_OFFSET); + reg_data =3D xemaclite_readl(drvdata->base_addr + XEL_RSR_OFFSET); + xemaclite_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), + drvdata->base_addr + XEL_RSR_OFFSET); } =20 /** @@ -323,7 +331,7 @@ static int xemaclite_send_data(struct net_local *drvdat= a, u8 *data, byte_count =3D ETH_FRAME_LEN; =20 /* Check if the expected buffer is available */ - reg_data =3D __raw_readl(addr + XEL_TSR_OFFSET); + reg_data =3D xemaclite_readl(addr + XEL_TSR_OFFSET); if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK)) =3D=3D 0) { =20 @@ -336,7 +344,7 @@ static int xemaclite_send_data(struct net_local *drvdat= a, u8 *data, =20 addr =3D (void __iomem __force *)((u32 __force)addr ^ XEL_BUFFER_OFFSET); - reg_data =3D __raw_readl(addr + XEL_TSR_OFFSET); + reg_data =3D xemaclite_readl(addr + XEL_TSR_OFFSET); =20 if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK)) !=3D 0) @@ -347,16 +355,16 @@ static int xemaclite_send_data(struct net_local *drvd= ata, u8 *data, /* Write the frame to the buffer */ xemaclite_aligned_write(data, (u32 __force *) addr, byte_count); =20 - __raw_writel((byte_count & XEL_TPLR_LENGTH_MASK), - addr + XEL_TPLR_OFFSET); + xemaclite_writel((byte_count & XEL_TPLR_LENGTH_MASK), + addr + XEL_TPLR_OFFSET); =20 /* Update the Tx Status Register to indicate that there is a * frame to send. Set the XEL_TSR_XMIT_ACTIVE_MASK flag which * is used by the interrupt handler to check whether a frame * has been transmitted */ - reg_data =3D __raw_readl(addr + XEL_TSR_OFFSET); + reg_data =3D xemaclite_readl(addr + XEL_TSR_OFFSET); reg_data |=3D (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK); - __raw_writel(reg_data, addr + XEL_TSR_OFFSET); + xemaclite_writel(reg_data, addr + XEL_TSR_OFFSET); =20 return 0; } @@ -371,7 +379,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; @@ -381,7 +389,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdat= a, u8 *data) addr =3D (drvdata->base_addr + drvdata->next_rx_buf_to_use); =20 /* Verify which buffer has valid data */ - reg_data =3D __raw_readl(addr + XEL_RSR_OFFSET); + reg_data =3D xemaclite_readl(addr + XEL_RSR_OFFSET); =20 if ((reg_data & XEL_RSR_RECV_DONE_MASK) =3D=3D XEL_RSR_RECV_DONE_MASK) { if (drvdata->rx_ping_pong !=3D 0) @@ -398,27 +406,28 @@ static u16 xemaclite_recv_data(struct net_local *drvd= ata, u8 *data) return 0; /* No data was available */ =20 /* Verify that buffer has valid data */ - reg_data =3D __raw_readl(addr + XEL_RSR_OFFSET); + reg_data =3D xemaclite_readl(addr + XEL_RSR_OFFSET); if ((reg_data & XEL_RSR_RECV_DONE_MASK) !=3D XEL_RSR_RECV_DONE_MASK) return 0; /* No data was available */ } =20 /* Get the protocol type of the ethernet frame that arrived */ - proto_type =3D ((ntohl(__raw_readl(addr + XEL_HEADER_OFFSET + + proto_type =3D ((ntohl(xemaclite_readl(addr + XEL_HEADER_OFFSET + XEL_RXBUFF_OFFSET)) >> XEL_HEADER_SHIFT) & XEL_RPLR_LENGTH_MASK); =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(__raw_readl(addr + + length =3D ((ntohl(xemaclite_readl(addr + XEL_HEADER_IP_LENGTH_OFFSET + 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) @@ -431,14 +440,17 @@ static u16 xemaclite_recv_data(struct net_local *drvd= ata, 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); =20 /* Acknowledge the frame */ - reg_data =3D __raw_readl(addr + XEL_RSR_OFFSET); + reg_data =3D xemaclite_readl(addr + XEL_RSR_OFFSET); reg_data &=3D ~XEL_RSR_RECV_DONE_MASK; - __raw_writel(reg_data, addr + XEL_RSR_OFFSET); + xemaclite_writel(reg_data, addr + XEL_RSR_OFFSET); =20 return length; } @@ -465,14 +477,14 @@ static void xemaclite_update_address(struct net_local= *drvdata, =20 xemaclite_aligned_write(address_ptr, (u32 __force *) addr, ETH_ALEN); =20 - __raw_writel(ETH_ALEN, addr + XEL_TPLR_OFFSET); + xemaclite_writel(ETH_ALEN, addr + XEL_TPLR_OFFSET); =20 /* Update the MAC address in the EmacLite */ - reg_data =3D __raw_readl(addr + XEL_TSR_OFFSET); - __raw_writel(reg_data | XEL_TSR_PROG_MAC_ADDR, addr + XEL_TSR_OFFSET); + reg_data =3D xemaclite_readl(addr + XEL_TSR_OFFSET); + xemaclite_writel(reg_data | XEL_TSR_PROG_MAC_ADDR, addr + XEL_TSR_OFFSET); =20 /* Wait for EmacLite to finish with the MAC address update */ - while ((__raw_readl(addr + XEL_TSR_OFFSET) & + while ((xemaclite_readl(addr + XEL_TSR_OFFSET) & XEL_TSR_PROG_MAC_ADDR) !=3D 0) ; } @@ -605,7 +617,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++; @@ -642,32 +654,32 @@ static irqreturn_t xemaclite_interrupt(int irq, void = *dev_id) u32 tx_status; =20 /* Check if there is Rx Data available */ - if ((__raw_readl(base_addr + XEL_RSR_OFFSET) & + if ((xemaclite_readl(base_addr + XEL_RSR_OFFSET) & XEL_RSR_RECV_DONE_MASK) || - (__raw_readl(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET) + (xemaclite_readl(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET) & XEL_RSR_RECV_DONE_MASK)) =20 xemaclite_rx_handler(dev); =20 /* Check if the Transmission for the first buffer is completed */ - tx_status =3D __raw_readl(base_addr + XEL_TSR_OFFSET); + tx_status =3D xemaclite_readl(base_addr + XEL_TSR_OFFSET); if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) =3D=3D 0) && (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) !=3D 0) { =20 tx_status &=3D ~XEL_TSR_XMIT_ACTIVE_MASK; - __raw_writel(tx_status, base_addr + XEL_TSR_OFFSET); + xemaclite_writel(tx_status, base_addr + XEL_TSR_OFFSET); =20 tx_complete =3D true; } =20 /* Check if the Transmission for the second buffer is completed */ - tx_status =3D __raw_readl(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); + tx_status =3D xemaclite_readl(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFF= SET); if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) =3D=3D 0) && (tx_status & XEL_TSR_XMIT_ACTIVE_MASK) !=3D 0) { =20 tx_status &=3D ~XEL_TSR_XMIT_ACTIVE_MASK; - __raw_writel(tx_status, base_addr + XEL_BUFFER_OFFSET + - XEL_TSR_OFFSET); + xemaclite_writel(tx_status, base_addr + XEL_BUFFER_OFFSET + + XEL_TSR_OFFSET); =20 tx_complete =3D true; } @@ -700,7 +712,7 @@ static int xemaclite_mdio_wait(struct net_local *lp) /* wait for the MDIO interface to not be busy or timeout after some time. */ - while (__raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) & + while (xemaclite_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET) & XEL_MDIOCTRL_MDIOSTS_MASK) { if (time_before_eq(end, jiffies)) { WARN_ON(1); @@ -736,17 +748,17 @@ static int xemaclite_mdio_read(struct mii_bus *bus, i= nt phy_id, int reg) * MDIO Address register. Set the Status bit in the MDIO Control * register to start a MDIO read transaction. */ - ctrl_reg =3D __raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); - __raw_writel(XEL_MDIOADDR_OP_MASK | - ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), - lp->base_addr + XEL_MDIOADDR_OFFSET); - __raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, - lp->base_addr + XEL_MDIOCTRL_OFFSET); + ctrl_reg =3D xemaclite_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); + xemaclite_writel(XEL_MDIOADDR_OP_MASK | + ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), + lp->base_addr + XEL_MDIOADDR_OFFSET); + xemaclite_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, + lp->base_addr + XEL_MDIOCTRL_OFFSET); =20 if (xemaclite_mdio_wait(lp)) return -ETIMEDOUT; =20 - rc =3D __raw_readl(lp->base_addr + XEL_MDIORD_OFFSET); + rc =3D xemaclite_readl(lp->base_addr + XEL_MDIORD_OFFSET); =20 dev_dbg(&lp->ndev->dev, "xemaclite_mdio_read(phy_id=3D%i, reg=3D%x) =3D=3D %x\n", @@ -783,13 +795,13 @@ static int xemaclite_mdio_write(struct mii_bus *bus, = int phy_id, int reg, * Data register. Finally, set the Status bit in the MDIO Control * register to start a MDIO write transaction. */ - ctrl_reg =3D __raw_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); - __raw_writel(~XEL_MDIOADDR_OP_MASK & - ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), - lp->base_addr + XEL_MDIOADDR_OFFSET); - __raw_writel(val, lp->base_addr + XEL_MDIOWR_OFFSET); - __raw_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, - lp->base_addr + XEL_MDIOCTRL_OFFSET); + ctrl_reg =3D xemaclite_readl(lp->base_addr + XEL_MDIOCTRL_OFFSET); + xemaclite_writel(~XEL_MDIOADDR_OP_MASK & + ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg), + lp->base_addr + XEL_MDIOADDR_OFFSET); + xemaclite_writel(val, lp->base_addr + XEL_MDIOWR_OFFSET); + xemaclite_writel(ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK, + lp->base_addr + XEL_MDIOCTRL_OFFSET); =20 return 0; } @@ -834,8 +846,8 @@ static int xemaclite_mdio_setup(struct net_local *lp, s= truct device *dev) /* Enable the MDIO bus by asserting the enable bit in MDIO Control * register. */ - __raw_writel(XEL_MDIOCTRL_MDIOEN_MASK, - lp->base_addr + XEL_MDIOCTRL_OFFSET); + xemaclite_writel(XEL_MDIOCTRL_MDIOEN_MASK, + lp->base_addr + XEL_MDIOCTRL_OFFSET); =20 bus =3D mdiobus_alloc(); if (!bus) { @@ -1138,8 +1150,8 @@ static int xemaclite_of_probe(struct platform_device = *ofdev) dev_warn(dev, "No MAC address found\n"); =20 /* Clear the Tx CSR's in case this is a restart */ - __raw_writel(0, lp->base_addr + XEL_TSR_OFFSET); - __raw_writel(0, lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); + xemaclite_writel(0, lp->base_addr + XEL_TSR_OFFSET); + xemaclite_writel(0, lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); =20 /* Set the MAC address in the EmacLite device */ xemaclite_update_address(lp, ndev->dev_addr); diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_dr= v.c index 7e3331821200..ab68d940a2c7 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -47,6 +47,9 @@ struct net_device_context { struct work_struct work; }; =20 +/* Restrict GSO size to account for NVGRE */ +#define NETVSC_GSO_MAX_SIZE 62768 + #define RING_SIZE_MIN 64 static int ring_size =3D 128; module_param(ring_size, int, S_IRUGO); @@ -839,6 +842,7 @@ static int netvsc_probe(struct hv_device *dev, nvdev =3D hv_get_drvdata(dev); netif_set_real_num_tx_queues(net, nvdev->num_chn); netif_set_real_num_rx_queues(net, nvdev->num_chn); + netif_set_gso_max_size(net, NETVSC_GSO_MAX_SIZE); =20 ret =3D register_netdev(net); if (ret !=3D 0) { diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index faa79040d336..b787d1ceeba6 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -657,7 +657,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) @@ -793,7 +793,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 343a71ad865b..1c843a4ac7a4 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1037,9 +1037,11 @@ static ssize_t tun_get_user(struct tun_struct *tun, = struct tun_file *tfile, } =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; @@ -1050,7 +1052,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, s= truct tun_file *tfile, =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) { @@ -1227,15 +1229,19 @@ static ssize_t tun_put_user(struct tun_struct *tun, ssize_t total =3D 0; int vlan_offset =3D 0, copied; int vlan_hlen =3D 0; + int vnet_hdr_sz =3D 0; =20 if (vlan_tx_tag_present(skb)) vlan_hlen =3D VLAN_HLEN; =20 + if (tun->flags & TUN_VNET_HDR) + vnet_hdr_sz =3D ACCESS_ONCE(tun->vnet_hdr_sz); + if (!(tun->flags & TUN_NO_PI)) { if ((len -=3D sizeof(pi)) < 0) return -EINVAL; =20 - if (len < skb->len) { + if (len < skb->len + vlan_hlen + vnet_hdr_sz) { /* Packet will be striped */ pi.flags |=3D TUN_PKT_STRIP; } @@ -1245,9 +1251,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)) { @@ -1291,7 +1297,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 copied =3D total; diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 8cfc3bb0c6a6..436da0c3ce3b 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -777,7 +777,7 @@ static int catc_probe(struct usb_interface *intf, const= struct usb_device_id *id struct net_device *netdev; struct catc *catc; u8 broadcast[ETH_ALEN]; - int i, pktsz; + int pktsz, ret; =20 if (usb_set_interface(usbdev, intf->altsetting->desc.bInterfaceNumber, 1)) { @@ -812,12 +812,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)) { dev_err(&intf->dev, "No free urbs available.\n"); - 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 */ @@ -845,15 +841,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; + dev_dbg(dev, "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); @@ -868,6 +873,8 @@ static int catc_probe(struct usb_interface *intf, const= struct usb_device_id *id dev_dbg(dev, "32k Memory\n"); break; } + + kfree(buf); =20 dev_dbg(dev, "Getting MAC from SEEROM.\n"); =20 @@ -914,16 +921,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/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 2a32d9167d3b..610b2858c5c3 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -502,6 +502,7 @@ static const struct driver_info wwan_info =3D { #define DELL_VENDOR_ID 0x413C #define REALTEK_VENDOR_ID 0x0bda #define SAMSUNG_VENDOR_ID 0x04e8 +#define HP_VENDOR_ID 0x03f0 =20 static const struct usb_device_id products[] =3D { /* BLACKLIST !! @@ -648,6 +649,13 @@ static const struct usb_device_id products[] =3D { .driver_info =3D 0, }, =20 +/* HP lt2523 (Novatel E371) - handled by qmi_wwan */ +{ + USB_DEVICE_AND_INTERFACE_INFO(HP_VENDOR_ID, 0x421d, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info =3D 0, +}, + /* AnyDATA ADU960S - handled by qmi_wwan */ { USB_DEVICE_AND_INTERFACE_INFO(0x16d5, 0x650a, USB_CLASS_COMM, diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 58990934f192..73c5b0976f65 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -830,6 +830,13 @@ advance: if (cdc_ncm_init(dev)) goto error2; =20 + /* Some firmwares need a pause here or they will silently fail + * to set up the interface properly. This value was decided + * empirically on a Sierra Wireless MC7455 running 02.08.02.00 + * firmware. + */ + usleep_range(10000, 20000); + /* configure data interface */ temp =3D usb_set_interface(dev->udev, iface_no, data_altsetting); if (temp) { diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index f84080215915..17fac0121e56 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -126,40 +126,61 @@ static void async_ctrl_callback(struct urb *urb) =20 static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void = *data) { + u8 *buf; int ret; =20 + buf =3D kmalloc(size, GFP_NOIO); + if (!buf) + return -ENOMEM; + ret =3D usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0), PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0, - indx, data, size, 1000); + indx, buf, size, 1000); if (ret < 0) netif_dbg(pegasus, drv, pegasus->net, "%s returned %d\n", __func__, ret); + else if (ret <=3D size) + memcpy(data, buf, ret); + kfree(buf); return ret; } =20 -static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void = *data) +static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, + const void *data) { + u8 *buf; int ret; =20 + buf =3D kmemdup(data, size, GFP_NOIO); + if (!buf) + return -ENOMEM; + ret =3D usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0, - indx, data, size, 100); + indx, buf, size, 100); if (ret < 0) netif_dbg(pegasus, drv, pegasus->net, "%s returned %d\n", __func__, ret); + kfree(buf); return ret; } =20 static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data) { + u8 *buf; int ret; =20 + buf =3D kmemdup(&data, 1, GFP_NOIO); + if (!buf) + return -ENOMEM; + ret =3D usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data, - indx, &data, 1, 1000); + indx, buf, 1, 1000); if (ret < 0) netif_dbg(pegasus, drv, pegasus->net, "%s returned %d\n", __func__, ret); + kfree(buf); return ret; } =20 diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index f6caedf0920c..f07777eb09b1 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -535,6 +535,13 @@ static const struct usb_device_id products[] =3D { USB_CDC_PROTO_NONE), .driver_info =3D (unsigned long)&qmi_wwan_info, }, + { /* HP lt2523 (Novatel E371) */ + USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x421d, + USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info =3D (unsigned long)&qmi_wwan_info, + }, { /* HP lt4112 LTE/HSPA+ Gobi 4G Module (Huawei me906e) */ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, = 7), .driver_info =3D (unsigned long)&qmi_wwan_info, diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 3eab74c7c554..580793a8190e 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1596,7 +1596,7 @@ static u8 r8152_rx_csum(struct r8152 *tp, struct rx_d= esc *rx_desc) u8 checksum =3D CHECKSUM_NONE; u32 opts2, opts3; =20 - if (tp->version =3D=3D RTL_VER_01) + if (!(tp->netdev->features & NETIF_F_RXCSUM)) goto return_result; =20 opts2 =3D le32_to_cpu(rx_desc->opts2); @@ -3454,6 +3454,11 @@ static int rtl8152_probe(struct usb_interface *intf, NETIF_F_TSO | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM | NETIF_F_TSO6; =20 + if (tp->version =3D=3D RTL_VER_01) { + netdev->features &=3D ~NETIF_F_RXCSUM; + netdev->hw_features &=3D ~NETIF_F_RXCSUM; + } + netdev->ethtool_ops =3D &ops; netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); =20 diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 6e87e5710048..eab8fba1f8c9 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -155,16 +155,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 async_set_reg_cb(struct urb *urb) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 74dccfa00a5c..7badf2aa3f61 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1146,7 +1146,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, stru= ct sk_buff *skb) =20 /* Need Vxlan and inner Ethernet header to be present */ if (!pskb_may_pull(skb, VXLAN_HLEN)) - goto error; + goto drop; =20 /* Return packets with reserved bits set */ vxh =3D (struct vxlanhdr *)(udp_hdr(skb) + 1); @@ -1154,7 +1154,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, stru= ct sk_buff *skb) (vxh->vx_vni & htonl(0xff))) { netdev_dbg(skb->dev, "invalid vxlan flags=3D%#x vni=3D%#x\n", ntohl(vxh->vx_flags), ntohl(vxh->vx_vni)); - goto error; + goto drop; } =20 if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB))) @@ -1173,10 +1173,6 @@ drop: /* Consume bad packet */ kfree_skb(skb); return 0; - -error: - /* Return non vxlan pkt */ - return 1; } =20 static void vxlan_rcv(struct vxlan_sock *vs, diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 567d5c31dfd2..ea6b55abd42d 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1440,6 +1440,8 @@ static void xennet_disconnect_backend(struct netfront= _info *info) for (i =3D 0; i < num_queues; ++i) { struct netfront_queue *queue =3D &info->queues[i]; =20 + del_timer_sync(&queue->rx_refill_timer); + if (queue->tx_irq && (queue->tx_irq =3D=3D queue->rx_irq)) unbind_from_irqhandler(queue->tx_irq, queue); if (queue->tx_irq && (queue->tx_irq !=3D queue->rx_irq)) { @@ -2360,8 +2362,6 @@ static int xennet_remove(struct xenbus_device *dev) { struct netfront_info *info =3D dev_get_drvdata(&dev->dev); unsigned int num_queues =3D info->netdev->real_num_tx_queues; - struct netfront_queue *queue =3D NULL; - unsigned int i =3D 0; =20 dev_dbg(&dev->dev, "%s\n", dev->nodename); =20 @@ -2371,11 +2371,6 @@ static int xennet_remove(struct xenbus_device *dev) =20 unregister_netdev(info->netdev); =20 - for (i =3D 0; i < num_queues; ++i) { - queue =3D &info->queues[i]; - del_timer_sync(&queue->rx_refill_timer); - } - if (num_queues) { kfree(info->queues); info->queues =3D NULL; diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpad= lpar_core.c index 7660232ef460..6d82498f1e60 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -258,8 +258,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 @@ -335,6 +340,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 3e981329c7a9..2e54269f5458 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1982,6 +1982,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 8d6775266d66..04dc5ab2e30d 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c @@ -76,7 +76,7 @@ static int 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, IRQF_NO_SUSPEND, + error =3D request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND | = IRQF_ONESHOT, DRIVER_NAME, input); if (error) { dev_err(&pdev->dev, "Unable to request irq %d for mfld power" diff --git a/drivers/regulator/stw481x-vmmc.c b/drivers/regulator/stw481x-v= mmc.c index a7e152696a02..f140b42956a4 100644 --- a/drivers/regulator/stw481x-vmmc.c +++ b/drivers/regulator/stw481x-vmmc.c @@ -47,7 +47,8 @@ static struct regulator_desc vmmc_regulator =3D { .volt_table =3D stw481x_vmmc_voltages, .enable_time =3D 200, /* FIXME: look this up */ .enable_reg =3D STW_CONF1, - .enable_mask =3D STW_CONF1_PDN_VMMC, + .enable_mask =3D STW_CONF1_PDN_VMMC | STW_CONF1_MMC_LS_STATUS, + .enable_val =3D STW_CONF1_PDN_VMMC, .vsel_reg =3D STW_CONF1, .vsel_mask =3D STW_CONF1_VMMC_MASK, }; diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index a8848db7b09d..064ffed2589d 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -873,7 +873,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 7b1fbd303c29..598b577760ef 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -289,11 +289,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; @@ -319,11 +320,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 36d07584271d..db186d44cfaf 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 ac86ff90c897..acb0b8c3989d 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" @@ -1211,6 +1211,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; @@ -1221,6 +1277,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: @@ -1231,7 +1288,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 1f1fe41ecb97..0c8c8b8fc1de 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 @@ -35,6 +35,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 6065212fdeed..36cf11cafee7 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -1584,7 +1584,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); @@ -1613,7 +1613,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; } @@ -1639,7 +1639,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); @@ -1668,7 +1668,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 be1c04b334c5..ea3c76ac0de1 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 @@ -78,6 +78,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 7c2c6194dfca..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 Corp. 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/megaraid/megaraid_sas_fusion.c b/drivers/scsi/meg= araid/megaraid_sas_fusion.c index 560bbbd03788..5f335917f477 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2291,6 +2291,7 @@ int megasas_wait_for_outstanding_fusion(struct megasa= s_instance *instance, printk("megaraid_sas: pending commands remain after waiting, " "will reset adapter scsi%d.\n", instance->host->host_no); + *convert =3D 1; retval =3D 1; } out: diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index 9270d15ff1a4..7353ac8d0d39 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c @@ -621,7 +621,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/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 5072251cdb8b..c770ef886dc2 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3393,7 +3393,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t re= q_len, uint16_t rsp_len, sizeof(struct ct6_dsd), 0, SLAB_HWCACHE_ALIGN, NULL); if (!ctx_cachep) - goto fail_free_gid_list; + goto fail_free_srb_mempool; } ha->ctx_mempool =3D mempool_create_slab_pool(SRB_MIN_REQ, ctx_cachep); @@ -3546,7 +3546,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t re= q_len, uint16_t rsp_len, ha->loop_id_map =3D kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long), GFP_KERNEL); if (!ha->loop_id_map) - goto fail_async_pd; + goto fail_loop_id_map; else { qla2x00_set_reserved_loop_ids(ha); ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123, @@ -3555,6 +3555,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t re= q_len, uint16_t rsp_len, =20 return 0; =20 +fail_loop_id_map: + dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); fail_async_pd: dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); fail_ex_init_cb: @@ -3582,6 +3584,10 @@ fail_free_ms_iocb: dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); ha->ms_iocb =3D NULL; ha->ms_iocb_dma =3D 0; + + if (ha->sns_cmd) + dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), + ha->sns_cmd, ha->sns_cmd_dma); fail_dma_pool: if (IS_QLA82XX(ha) || ql2xenabledif) { dma_pool_destroy(ha->fcp_cmnd_dma_pool); @@ -3599,10 +3605,12 @@ fail_free_nvram: kfree(ha->nvram); ha->nvram =3D NULL; fail_free_ctx_mempool: - mempool_destroy(ha->ctx_mempool); + if (ha->ctx_mempool) + mempool_destroy(ha->ctx_mempool); ha->ctx_mempool =3D NULL; fail_free_srb_mempool: - mempool_destroy(ha->srb_mempool); + if (ha->srb_mempool) + mempool_destroy(ha->srb_mempool); ha->srb_mempool =3D NULL; fail_free_gid_list: dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 1b30a65554f9..ae280e7d3831 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1002,10 +1002,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 b4d50662fc6f..0206b495b65e 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1716,6 +1716,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 a8dc95ebf2d6..7700cef5e177 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -846,6 +846,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, if (err) { ssb_warn("WARNING: Using fallback SPROM failed (err %d)\n", err); + goto out_free; } else { ssb_dbg("Using SPROM revision %d provided by platform\n", sprom->revision); diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/ad= c/ad7606_core.c index f0f05f195d2c..d4598ef48543 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -186,7 +186,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/media/davinci_vpfe/vpfe_video.c b/drivers/stag= ing/media/davinci_vpfe/vpfe_video.c index d95c427043d4..3c1d1401522f 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -1351,7 +1351,7 @@ static int vpfe_reqbufs(struct file *file, void *priv, if (ret) { v4l2_err(&vpfe_dev->v4l2_dev, "vb2_queue_init() failed\n"); vb2_dma_contig_cleanup_ctx(vpfe_dev->pdev); - return ret; + goto unlock_out; } =20 fh->io_allowed =3D 1; diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi= /iscsi_target_tpg.c index c3cb5c15efda..48cd3cf741df 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -261,7 +261,6 @@ err_out: iscsi_release_param_list(tpg->param_list); tpg->param_list =3D NULL; } - kfree(tpg); return -ENOMEM; } =20 diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_= sbc.c index f4865901263f..a29fdfab0d3a 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -368,6 +368,7 @@ static sense_reason_t compare_and_write_post(struct se_= cmd *cmd, bool success, int *post_ret) { struct se_device *dev =3D cmd->se_dev; + sense_reason_t ret =3D TCM_NO_SENSE; =20 /* * Only set SCF_COMPARE_AND_WRITE_POST to force a response fall-through @@ -375,9 +376,12 @@ static sense_reason_t compare_and_write_post(struct se= _cmd *cmd, bool success, * sent to the backend driver. */ spin_lock_irq(&cmd->t_state_lock); - if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) { + if (cmd->transport_state & CMD_T_SENT) { cmd->se_cmd_flags |=3D SCF_COMPARE_AND_WRITE_POST; *post_ret =3D 1; + + if (cmd->scsi_status =3D=3D SAM_STAT_CHECK_CONDITION) + ret =3D TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } spin_unlock_irq(&cmd->t_state_lock); =20 @@ -387,7 +391,7 @@ static sense_reason_t compare_and_write_post(struct se_= cmd *cmd, bool success, */ up(&dev->caw_sem); =20 - return TCM_NO_SENSE; + return ret; } =20 static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool = success, diff --git a/drivers/target/target_core_transport.c b/drivers/target/target= _core_transport.c index d3f65523a19d..589f9df574f2 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -3093,7 +3093,6 @@ static void target_tmr_work(struct work_struct *work) spin_unlock_irqrestore(&cmd->t_state_lock, flags); goto check_stop; } - cmd->t_state =3D TRANSPORT_ISTATE_PROCESSING; spin_unlock_irqrestore(&cmd->t_state_lock, flags); =20 cmd->se_tfo->queue_tm_rsp(cmd); @@ -3106,11 +3105,25 @@ int transport_generic_handle_tmr( struct se_cmd *cmd) { unsigned long flags; + bool aborted =3D false; =20 spin_lock_irqsave(&cmd->t_state_lock, flags); - cmd->transport_state |=3D CMD_T_ACTIVE; + if (cmd->transport_state & CMD_T_ABORTED) { + aborted =3D true; + } else { + cmd->t_state =3D TRANSPORT_ISTATE_PROCESSING; + cmd->transport_state |=3D CMD_T_ACTIVE; + } spin_unlock_irqrestore(&cmd->t_state_lock, flags); =20 + if (aborted) { + pr_warn_ratelimited("handle_tmr caught CMD_T_ABORTED TMR %d" + "ref_tag: %u tag: %u\n", cmd->se_tmr_req->function, + cmd->se_tmr_req->ref_task_tag, cmd->se_tfo->get_task_tag(cmd)); + transport_cmd_check_stop_to_fabric(cmd); + return 0; + } + INIT_WORK(&cmd->work, target_tmr_work); queue_work(cmd->se_dev->tmr_wq, &cmd->work); return 0; diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_cor= e_xcopy.c index 60e611df4818..f9b28a5a52a4 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -881,7 +881,7 @@ out: " CHECK_CONDITION -> sending response\n", rc); ec_cmd->scsi_status =3D SAM_STAT_CHECK_CONDITION; } - target_complete_cmd(ec_cmd, SAM_STAT_CHECK_CONDITION); + target_complete_cmd(ec_cmd, ec_cmd->scsi_status); } =20 sense_reason_t target_do_xcopy(struct se_cmd *se_cmd) diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmo= n.c index 1967bee4f076..9035fbc5e98d 100644 --- a/drivers/thermal/thermal_hwmon.c +++ b/drivers/thermal/thermal_hwmon.c @@ -98,7 +98,7 @@ temp_crit_show(struct device *dev, struct device_attribut= e *attr, char *buf) 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 644ddb841d9f..6d1e2f746ab4 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -114,7 +114,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]; }; @@ -122,8 +122,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; }; @@ -136,7 +135,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 @@ -149,7 +147,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; @@ -159,7 +156,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); @@ -209,16 +207,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 { @@ -284,7 +275,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() */ @@ -403,13 +393,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", @@ -421,7 +405,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 */ @@ -436,10 +420,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 @@ -449,10 +430,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; } } @@ -750,7 +733,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); @@ -764,8 +748,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); @@ -777,8 +763,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; @@ -826,14 +814,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; @@ -853,11 +841,16 @@ static struct n_hdlc *n_hdlc_alloc(void) if (!n_hdlc) return NULL; =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/serial/atmel_serial.c b/drivers/tty/serial/atmel_s= erial.c index d806657ca53e..56a3cc42a4b0 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -734,6 +734,11 @@ static void atmel_complete_tx_dma(void *arg) /* Do we really need this? */ if (!uart_circ_empty(xmit)) tasklet_schedule(&atmel_port->tasklet); + else if ((atmel_port->rs485.flags & SER_RS485_ENABLED) && + !(atmel_port->rs485.flags & SER_RS485_RX_DURING_TX)) { + /* DMA done, stop TX, start RX for RS485 */ + atmel_start_rx(port); + } =20 spin_unlock_irqrestore(&port->lock, flags); } @@ -806,12 +811,6 @@ static void atmel_tx_dma(struct uart_port *port) desc->callback =3D atmel_complete_tx_dma; desc->callback_param =3D atmel_port; atmel_port->cookie_tx =3D dmaengine_submit(desc); - - } else { - if (atmel_port->rs485.flags & SER_RS485_ENABLED) { - /* DMA done, stop TX, start RX for RS485 */ - atmel_start_rx(port); - } } =20 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 0c79f95383c0..4317a19d60be 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -933,8 +933,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 8c779ee044d8..919dc6a1bdf3 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1721,6 +1721,7 @@ static const struct usb_device_id acm_ids[] =3D { { USB_DEVICE(0x20df, 0x0001), /* Simtec Electronics Entropy Key */ .driver_info =3D QUIRK_CONTROL_LINE_STATE, }, { 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 8de16f982f55..13d8c60c286a 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -205,6 +205,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/hub.c b/drivers/usb/core/hub.c index 554cc219ac34..624378404b37 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -106,6 +106,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); =20 static void hub_release(struct kref *kref); static int usb_reset_and_verify_device(struct usb_device *udev); +static int hub_port_disable(struct usb_hub *hub, int port1, int set_state); =20 static inline char *portspeed(struct usb_hub *hub, int portstatus) { @@ -876,88 +877,6 @@ static int hub_set_port_link_state(struct usb_hub *hub= , int port1, } =20 /* - * If USB 3.0 ports are placed into the Disabled state, they will no longer - * detect any device connects or disconnects. This is generally not what = the - * USB core wants, since it expects a disabled port to produce a port stat= us - * change event when a new device connects. - * - * Instead, set the link state to Disabled, wait for the link to settle in= to - * that state, clear any change bits, and then put the port into the RxDet= ect - * state. - */ -static int hub_usb3_port_disable(struct usb_hub *hub, int port1) -{ - int ret; - int total_time; - u16 portchange, portstatus; - - if (!hub_is_superspeed(hub->hdev)) - return -EINVAL; - - ret =3D hub_port_status(hub, port1, &portstatus, &portchange); - if (ret < 0) - return ret; - - /* - * USB controller Advanced Micro Devices, Inc. [AMD] FCH USB XHCI - * Controller [1022:7814] will have spurious result making the following - * usb 3.0 device hotplugging route to the 2.0 root hub and recognized - * as high-speed device if we set the usb 3.0 port link state to - * Disabled. Since it's already in USB_SS_PORT_LS_RX_DETECT state, we - * check the state here to avoid the bug. - */ - if ((portstatus & USB_PORT_STAT_LINK_STATE) =3D=3D - USB_SS_PORT_LS_RX_DETECT) { - dev_dbg(&hub->ports[port1 - 1]->dev, - "Not disabling port; link state is RxDetect\n"); - return ret; - } - - ret =3D hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_SS_DISABLED); - if (ret) - return ret; - - /* Wait for the link to enter the disabled state. */ - for (total_time =3D 0; ; total_time +=3D HUB_DEBOUNCE_STEP) { - ret =3D hub_port_status(hub, port1, &portstatus, &portchange); - if (ret < 0) - return ret; - - if ((portstatus & USB_PORT_STAT_LINK_STATE) =3D=3D - USB_SS_PORT_LS_SS_DISABLED) - break; - if (total_time >=3D HUB_DEBOUNCE_TIMEOUT) - break; - msleep(HUB_DEBOUNCE_STEP); - } - if (total_time >=3D HUB_DEBOUNCE_TIMEOUT) - dev_warn(&hub->ports[port1 - 1]->dev, - "Could not disable after %d ms\n", total_time); - - return hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_RX_DETECT); -} - -static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) -{ - struct usb_port *port_dev =3D hub->ports[port1 - 1]; - struct usb_device *hdev =3D hub->hdev; - int ret =3D 0; - - if (port_dev->child && set_state) - usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED); - if (!hub->error) { - if (hub_is_superspeed(hub->hdev)) - ret =3D hub_usb3_port_disable(hub, port1); - else - ret =3D usb_clear_port_feature(hdev, port1, - USB_PORT_FEAT_ENABLE); - } - if (ret && ret !=3D -ENODEV) - dev_err(&port_dev->dev, "cannot disable (err =3D %d)\n", ret); - return ret; -} - -/* * Disable a port and mark a logical connect-change event, so that some * time later khubd will disconnect() any existing usb_device on the port * and will re-enumerate if there actually is a device attached. @@ -4022,6 +3941,26 @@ void usb_unlocked_enable_lpm(struct usb_device *udev) } EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm); =20 +/* usb3 devices use U3 for disabled, make sure remote wakeup is disabled */ +static void hub_usb3_port_prepare_disable(struct usb_hub *hub, + struct usb_port *port_dev) +{ + struct usb_device *udev =3D port_dev->child; + int ret; + + if (udev && udev->port_is_suspended && udev->do_remote_wakeup) { + ret =3D hub_set_port_link_state(hub, port_dev->portnum, + USB_SS_PORT_LS_U0); + if (!ret) { + msleep(USB_RESUME_TIMEOUT); + ret =3D usb_disable_remote_wakeup(udev); + } + if (ret) + dev_warn(&udev->dev, + "Port disable: can't disable remote wake\n"); + udev->do_remote_wakeup =3D 0; + } +} =20 #else /* CONFIG_PM */ =20 @@ -4029,6 +3968,9 @@ EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm); #define hub_resume NULL #define hub_reset_resume NULL =20 +static inline void hub_usb3_port_prepare_disable(struct usb_hub *hub, + struct usb_port *port_dev) { } + int usb_disable_lpm(struct usb_device *udev) { return 0; @@ -4064,6 +4006,34 @@ static int hub_handle_remote_wakeup(struct usb_hub *= hub, unsigned int port, =20 #endif /* CONFIG_PM */ =20 +/* + * USB-3 does not have a similar link state as USB-2 that will avoid negot= iating + * a connection with a plugged-in cable but will signal the host when the = cable + * is unplugged. Disable remote wake and set link state to U3 for USB-3 de= vices + */ +static int hub_port_disable(struct usb_hub *hub, int port1, int set_state) +{ + struct usb_port *port_dev =3D hub->ports[port1 - 1]; + struct usb_device *hdev =3D hub->hdev; + int ret =3D 0; + + if (!hub->error) { + if (hub_is_superspeed(hub->hdev)) { + hub_usb3_port_prepare_disable(hub, port_dev); + ret =3D hub_set_port_link_state(hub, port_dev->portnum, + USB_SS_PORT_LS_U3); + } else { + ret =3D usb_clear_port_feature(hdev, port1, + USB_PORT_FEAT_ENABLE); + } + } + if (port_dev->child && set_state) + usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED); + if (ret && ret !=3D -ENODEV) + dev_err(&port_dev->dev, "cannot disable (err =3D %d)\n", ret); + return ret; +} + =20 /* USB 2.0 spec, 7.1.7.3 / fig 7-29: * diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 6c7e47f67dd4..3a010c19e0ec 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -37,6 +37,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/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index ba35201e19fe..096c9e91724e 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -54,20 +54,13 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_= state state) } } =20 -static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf= _dma, - u32 len, u32 type) +static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum, + dma_addr_t buf_dma, u32 len, u32 type) { - struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; struct dwc3_ep *dep; =20 - int ret; - dep =3D dwc->eps[epnum]; - if (dep->flags & DWC3_EP_BUSY) { - dev_vdbg(dwc->dev, "%s: still busy\n", dep->name); - return 0; - } =20 trb =3D dwc->ep0_trb; =20 @@ -80,6 +73,17 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epn= um, dma_addr_t buf_dma, | DWC3_TRB_CTRL_LST | DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI); +} + +static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum) +{ + struct dwc3_gadget_ep_cmd_params params; + struct dwc3_ep *dep; + int ret; + + dep =3D dwc->eps[epnum]; + if (dep->flags & DWC3_EP_BUSY) + return 0; =20 memset(¶ms, 0, sizeof(params)); params.param0 =3D upper_32_bits(dwc->ep0_trb_addr); @@ -280,8 +284,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) { int ret; =20 - ret =3D dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8, + dwc3_ep0_prepare_one_trb(dwc, 0, dwc->ctrl_req_addr, 8, DWC3_TRBCTL_CONTROL_SETUP); + ret =3D dwc3_ep0_start_trans(dwc, 0); WARN_ON(ret < 0); } =20 @@ -890,9 +895,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dw= c, req->direction =3D !!dep->number; =20 if (req->request.length =3D=3D 0) { - ret =3D dwc3_ep0_start_trans(dwc, dep->number, + dwc3_ep0_prepare_one_trb(dwc, dep->number, dwc->ctrl_req_addr, 0, DWC3_TRBCTL_CONTROL_DATA); + ret =3D dwc3_ep0_start_trans(dwc, dep->number); } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) && (dep->number =3D=3D 0)) { u32 transfer_size; @@ -920,9 +926,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dw= c, * DWC3_EP0_BOUNCE_SIZE we will need two chained * TRBs to handle the transfer. */ - ret =3D dwc3_ep0_start_trans(dwc, dep->number, + dwc3_ep0_prepare_one_trb(dwc, dep->number, dwc->ep0_bounce_addr, transfer_size, DWC3_TRBCTL_CONTROL_DATA); + ret =3D dwc3_ep0_start_trans(dwc, dep->number); } else { ret =3D usb_gadget_map_request(&dwc->gadget, &req->request, dep->number); @@ -931,8 +938,9 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, return; } =20 - ret =3D dwc3_ep0_start_trans(dwc, dep->number, req->request.dma, + dwc3_ep0_prepare_one_trb(dwc, dep->number, req->request.dma, req->request.length, DWC3_TRBCTL_CONTROL_DATA); + ret =3D dwc3_ep0_start_trans(dwc, dep->number); } =20 WARN_ON(ret < 0); @@ -946,8 +954,9 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep= *dep) type =3D dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 : DWC3_TRBCTL_CONTROL_STATUS2; =20 - return dwc3_ep0_start_trans(dwc, dep->number, + dwc3_ep0_prepare_one_trb(dwc, dep->number, dwc->ctrl_req_addr, 0, type); + return dwc3_ep0_start_trans(dwc, dep->number); } =20 static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep = *dep) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index ede2814702c4..e81cda1129a3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -257,11 +257,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct= dwc3_request *req, if (req->request.status =3D=3D -EINPROGRESS) req->request.status =3D status; =20 - if (dwc->ep0_bounced && dep->number =3D=3D 0) + if (dwc->ep0_bounced && dep->number <=3D 1) dwc->ep0_bounced =3D false; - else - usb_gadget_unmap_request(&dwc->gadget, &req->request, - req->direction); + + usb_gadget_unmap_request(&dwc->gadget, + &req->request, req->direction); =20 dev_dbg(dwc->dev, "request %p from %s completed %d/%d =3D=3D=3D> %d\n", req, dep->name, req->request.actual, @@ -863,6 +863,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, { struct dwc3 *dwc =3D dep->dwc; struct dwc3_trb *trb; + struct usb_gadget *gadget =3D &dwc->gadget; + enum usb_device_speed speed =3D gadget->speed; =20 dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n", dep->name, req, (unsigned long long) dma, @@ -895,10 +897,16 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, break; =20 case USB_ENDPOINT_XFER_ISOC: - if (!node) + if (!node) { trb->ctrl =3D DWC3_TRBCTL_ISOCHRONOUS_FIRST; - else + + if (speed =3D=3D USB_SPEED_HIGH) { + struct usb_ep *ep =3D &dep->endpoint; + trb->size |=3D DWC3_TRB_SIZE_PCM1(ep->mult - 1); + } + } else { trb->ctrl =3D DWC3_TRBCTL_ISOCHRONOUS; + } break; =20 case USB_ENDPOINT_XFER_BULK: diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 9536b6abf65b..b8a961ba1d2b 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -143,11 +143,16 @@ 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; - _ep->mult =3D 0; + _ep->mult =3D 1; + + if (g->speed =3D=3D USB_SPEED_HIGH && (usb_endpoint_xfer_isoc(_ep->desc) = || + usb_endpoint_xfer_int(_ep->desc))) + _ep->mult =3D usb_endpoint_maxp_mult(_ep->desc); + if (!want_comp_desc) return 0; =20 @@ -164,7 +169,7 @@ ep_found: switch (usb_endpoint_type(_ep->desc)) { case USB_ENDPOINT_XFER_ISOC: /* mult: bits 1:0 of bmAttributes */ - _ep->mult =3D comp_desc->bmAttributes & 0x3; + _ep->mult =3D (comp_desc->bmAttributes & 0x3) + 1; case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: _ep->maxburst =3D comp_desc->bMaxBurst + 1; @@ -1516,9 +1521,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; @@ -1527,7 +1530,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 2b54955d3166..b0da9552b3b0 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -266,7 +266,7 @@ static void nuke(struct dummy *dum, struct dummy_ep *ep) /* caller must hold lock */ static void stop_activity(struct dummy *dum) { - struct dummy_ep *ep; + int i; =20 /* prevent any more requests */ dum->address =3D 0; @@ -274,8 +274,8 @@ static void 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 1ceaf0e6a859..ac3c91c7e627 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -1200,7 +1200,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) { @@ -1842,10 +1842,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; @@ -1862,7 +1864,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 */ @@ -1886,7 +1889,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; @@ -1895,10 +1899,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/gadget/uvc_video.c b/drivers/usb/gadget/uvc_video.c index 71e896d4c5ae..43e8c65fd9ed 100644 --- a/drivers/usb/gadget/uvc_video.c +++ b/drivers/usb/gadget/uvc_video.c @@ -240,7 +240,7 @@ uvc_video_alloc_requests(struct uvc_video *video) =20 req_size =3D video->ep->maxpacket * max_t(unsigned int, video->ep->maxburst, 1) - * (video->ep->mult + 1); + * (video->ep->mult); =20 for (i =3D 0; i < UVC_NUM_REQUESTS; ++i) { video->req_buffer[i] =3D kmalloc(req_size, GFP_KERNEL); diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index 940304c33224..02260cfdedb1 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 e46c3b1414b9..0333ccc27b13 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -965,6 +965,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) { @@ -1828,8 +1862,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); @@ -2368,7 +2402,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)); @@ -2464,7 +2498,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_trace(xhci, trace_xhci_dbg_init, diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index e808d8078b2d..63d4f2897f00 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -150,7 +150,8 @@ static void xhci_pci_quirks(struct device *dev, struct = xhci_hcd *xhci) pdev->device =3D=3D PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || pdev->device =3D=3D PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || pdev->device =3D=3D PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI || - pdev->device =3D=3D PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) { + pdev->device =3D=3D PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI || + pdev->device =3D=3D PCI_DEVICE_ID_INTEL_APL_XHCI)) { xhci->quirks |=3D XHCI_PME_STUCK_QUIRK; } if (pdev->vendor =3D=3D PCI_VENDOR_ID_INTEL && diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 58edc5478d6e..6db00d804d0e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -878,13 +878,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_trace(xhci, trace_xhci_dbg_cancel_urb, - "Stop EP timer ran, but another timer marked " - "xHCI as DYING, exiting."); - spin_unlock_irqrestore(&xhci->lock, flags); - return; - } if (!(ep->stop_cmds_pending =3D=3D 0 && (ep->ep_state & EP_HALT_PENDING))= ) { xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Stop EP timer ran, but no command pending, " @@ -1292,33 +1285,44 @@ void xhci_handle_command_timeout(unsigned long data) struct xhci_command *cur_cmd =3D NULL; xhci =3D (struct xhci_hcd *) data; =20 - /* mark this command to be cancelled */ spin_lock_irqsave(&xhci->lock, flags); - if (xhci->current_cmd) { - cur_cmd =3D xhci->current_cmd; - cur_cmd->status =3D COMP_CMD_ABORT; + + /* + * If timeout work is pending, or current_cmd is NULL, it means we + * raced with command completion. Command is handled so just return. + */ + if (!xhci->current_cmd || timer_pending(&xhci->cmd_timer)) { + spin_unlock_irqrestore(&xhci->lock, flags); + return; } =20 + /* mark this command to be cancelled */ + cur_cmd =3D xhci->current_cmd; + cur_cmd->status =3D COMP_CMD_ABORT; =20 /* Make sure command ring is running before aborting it */ hw_ring_state =3D xhci_read_64(xhci, &xhci->op_regs->cmd_ring); if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) && (hw_ring_state & CMD_RING_RUNNING)) { - - spin_unlock_irqrestore(&xhci->lock, flags); xhci_dbg(xhci, "Command timeout\n"); ret =3D xhci_abort_cmd_ring(xhci); if (unlikely(ret =3D=3D -ESHUTDOWN)) { xhci_err(xhci, "Abort command ring failed\n"); xhci_cleanup_command_queue(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); xhci_dbg(xhci, "xHCI host controller is dead.\n"); + + return; } - return; + + goto time_out_completed; } /* command timeout on stopped ring, ring can't be aborted */ xhci_dbg(xhci, "Command timeout on stopped ring\n"); xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd); + +time_out_completed: spin_unlock_irqrestore(&xhci->lock, flags); return; } @@ -1377,8 +1381,11 @@ static void handle_cmd_completion(struct xhci_hcd *x= hci, */ if (cmd_comp_code =3D=3D COMP_CMD_ABORT) { xhci->cmd_ring_state =3D CMD_RING_STATE_STOPPED; - if (cmd->status =3D=3D COMP_CMD_ABORT) + if (cmd->status =3D=3D COMP_CMD_ABORT) { + if (xhci->current_cmd =3D=3D cmd) + xhci->current_cmd =3D NULL; goto event_handled; + } } =20 cmd_type =3D TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb->generic.field[3])); @@ -1440,6 +1447,8 @@ static void handle_cmd_completion(struct xhci_hcd *xh= ci, xhci->current_cmd =3D list_entry(cmd->cmd_list.next, struct xhci_command, cmd_list); mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT); + } else if (xhci->current_cmd =3D=3D cmd) { + xhci->current_cmd =3D NULL; } =20 event_handled: diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e89d09458789..c92869b3ab56 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1561,19 +1561,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_trace(xhci, trace_xhci_dbg_cancel_urb, - "Ep 0x%x: URB %p to be canceled on " - "non-responsive xHCI host.", - 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 ep_index =3D xhci_get_endpoint_index(&urb->ep->desc); ep =3D &xhci->devs[urb->dev->slot_id]->eps[ep_index]; diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h index f7b13fd25257..a3dcbd55e436 100644 --- a/drivers/usb/musb/musbhsdma.h +++ b/drivers/usb/musb/musbhsdma.h @@ -157,5 +157,5 @@ struct musb_dma_controller { void __iomem *base; u8 channel_count; u8 used_channels; - u8 irq; + int irq; }; diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am3= 35x-control.c index d5eca7b9c555..887ee660fa35 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -126,10 +126,12 @@ struct phy_control *am335x_get_phy_control(struct dev= ice *dev) return NULL; =20 dev =3D bus_find_device(&platform_bus_type, NULL, node, match); + of_node_put(node); if (!dev) return NULL; =20 ctrl_usb =3D dev_get_drvdata(dev); + put_device(dev); if (!ctrl_usb) return NULL; return &ctrl_usb->phy_ctrl; diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 2d72aa3564a3..6a8044291ab4 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -61,13 +61,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 const struct usb_device_id id_table[] =3D { { USB_DEVICE(0x4348, 0x5523) }, @@ -84,6 +97,10 @@ struct ch341_private { u8 line_status; /* active status of modem control inputs */ }; =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) { @@ -95,6 +112,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; } @@ -112,13 +131,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; @@ -138,43 +170,47 @@ 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; } =20 static int ch341_set_handshake(struct usb_device *dev, u8 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 buffer =3D kmalloc(size, GFP_KERNEL); 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; - 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; + spin_unlock_irqrestore(&priv->lock, flags); =20 out: kfree(buffer); return r; @@ -184,33 +220,29 @@ 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 buffer =3D kmalloc(size, GFP_KERNEL); if (!buffer) 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 @@ -219,11 +251,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 @@ -249,7 +277,6 @@ static int ch341_port_probe(struct usb_serial_port *por= t) =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(port->serial->dev, priv); if (r < 0) @@ -309,32 +336,31 @@ static int ch341_open(struct tty_struct *tty, struct = usb_serial_port *port) struct ch341_private *priv =3D usb_get_serial_port_data(port); int r; =20 - priv->baud_rate =3D DEFAULT_BAUD_RATE; - r =3D ch341_configure(serial->dev, priv); if (r) - goto out; - - r =3D ch341_set_handshake(serial->dev, priv->line_control); - if (r) - goto out; + return r; =20 - r =3D ch341_set_baudrate(serial->dev, priv); - if (r) - goto out; + if (tty) + ch341_set_termios(tty, port, NULL); =20 dev_dbg(&port->dev, "%s - submitting interrupt urb\n", __func__); r =3D usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (r) { dev_err(&port->dev, "%s - failed to submit interrupt urb: %d\n", __func__, r); - ch341_close(port); - goto out; + 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 @@ -346,23 +372,33 @@ 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 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] @@ -374,7 +410,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; @@ -395,12 +431,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) { dev_dbg(&port->dev, "%s - Enter break state requested\n", __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 { dev_dbg(&port->dev, "%s - Leave break state requested\n", __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; } dev_dbg(&port->dev, "%s - New ch341 break register contents - reg1: %x, r= eg2: %x\n", __func__, break_reg[0], break_reg[1]); @@ -543,14 +579,23 @@ static int ch341_tiocmget(struct tty_struct *tty) =20 static int ch341_reset_resume(struct usb_serial *serial) { - struct ch341_private *priv; - - priv =3D usb_get_serial_port_data(serial->port[0]); + 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(serial->dev, priv); =20 - return 0; + 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; + } + } + + return usb_serial_generic_resume(serial); } =20 static struct usb_serial_driver ch341_device =3D { diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 2916dea3ede8..8948f375e75d 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -50,6 +50,7 @@ #define CYBERJACK_PRODUCT_ID 0x0100 =20 /* Function prototypes */ +static int cyberjack_attach(struct usb_serial *serial); static int cyberjack_port_probe(struct usb_serial_port *port); static int cyberjack_port_remove(struct usb_serial_port *port); static int cyberjack_open(struct tty_struct *tty, @@ -77,6 +78,7 @@ static struct usb_serial_driver cyberjack_device =3D { .description =3D "Reiner SCT Cyberjack USB card reader", .id_table =3D id_table, .num_ports =3D 1, + .attach =3D cyberjack_attach, .port_probe =3D cyberjack_port_probe, .port_remove =3D cyberjack_port_remove, .open =3D cyberjack_open, @@ -100,6 +102,14 @@ struct cyberjack_private { short wrsent; /* Data already sent */ }; =20 +static int cyberjack_attach(struct usb_serial *serial) +{ + if (serial->num_bulk_out < serial->num_ports) + return -ENODEV; + + return 0; +} + static int cyberjack_port_probe(struct usb_serial_port *port) { struct cyberjack_private *priv; diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gp= s.c index db591d19d416..37d0e8cc7af6 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1044,6 +1044,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 1947ea0e0988..b63a6c3899c5 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -2761,6 +2761,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 c0a42e9e6777..eea16550e582 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -1376,7 +1376,7 @@ stayinbootmode: dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__); serial->product_info.TiMode =3D TI_MODE_BOOT; =20 - return 0; + return 1; } =20 =20 @@ -2383,6 +2383,13 @@ static int edge_startup(struct usb_serial *serial) struct edgeport_serial *edge_serial; int status; =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) @@ -2393,11 +2400,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 */ + return 0; } =20 diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoe= nix.c index 5ad4a0fb4b26..7ed7d33d6c10 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -68,6 +68,16 @@ struct iuu_private { u32 clk; }; =20 +static int iuu_attach(struct usb_serial *serial) +{ + unsigned char num_ports =3D serial->num_ports; + + if (serial->num_bulk_in < num_ports || serial->num_bulk_out < num_ports) + return -ENODEV; + + return 0; +} + static int iuu_port_probe(struct usb_serial_port *port) { struct iuu_private *priv; @@ -1196,6 +1206,7 @@ static struct usb_serial_driver iuu_device =3D { .tiocmset =3D iuu_tiocmset, .set_termios =3D iuu_set_termios, .init_termios =3D iuu_init_termios, + .attach =3D iuu_attach, .port_probe =3D iuu_port_probe, .port_remove =3D iuu_port_remove, }; diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_= pda.c index 4f7e072e4e00..930be98d59b3 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -699,6 +699,19 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw"); MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); #endif =20 +static int keyspan_pda_attach(struct usb_serial *serial) +{ + unsigned char num_ports =3D serial->num_ports; + + if (serial->num_bulk_out < num_ports || + serial->num_interrupt_in < num_ports) { + dev_err(&serial->interface->dev, "missing endpoints\n"); + return -ENODEV; + } + + return 0; +} + static int keyspan_pda_port_probe(struct usb_serial_port *port) { =20 @@ -776,6 +789,7 @@ static struct usb_serial_driver keyspan_pda_device =3D { .break_ctl =3D keyspan_pda_break_ctl, .tiocmget =3D keyspan_pda_tiocmget, .tiocmset =3D keyspan_pda_tiocmset, + .attach =3D keyspan_pda_attach, .port_probe =3D keyspan_pda_port_probe, .port_remove =3D keyspan_pda_port_remove, }; diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb10= 5.c index ca843033170c..85e074c34623 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -300,7 +300,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, @@ -315,21 +315,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 dev_dbg(&port->dev, "%s - enabled reading\n", __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); - dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __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); + + return 0; =20 -exit: +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 a31ff1503a99..95795ef7ecd5 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -51,6 +51,7 @@ =20 =20 /* Function prototypes */ +static int kobil_attach(struct usb_serial *serial); static int kobil_port_probe(struct usb_serial_port *probe); static int kobil_port_remove(struct usb_serial_port *probe); static int kobil_open(struct tty_struct *tty, struct usb_serial_port *por= t); @@ -86,6 +87,7 @@ static struct usb_serial_driver kobil_device =3D { .description =3D "KOBIL USB smart card terminal", .id_table =3D id_table, .num_ports =3D 1, + .attach =3D kobil_attach, .port_probe =3D kobil_port_probe, .port_remove =3D kobil_port_remove, .ioctl =3D kobil_ioctl, @@ -113,6 +115,16 @@ struct kobil_private { }; =20 =20 +static int kobil_attach(struct usb_serial *serial) +{ + if (serial->num_interrupt_out < serial->num_ports) { + dev_err(&serial->interface->dev, "missing interrupt-out endpoint\n"); + return -ENODEV; + } + + return 0; +} + static int kobil_port_probe(struct usb_serial_port *port) { struct usb_serial *serial =3D port->serial; diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index c3b8ae360424..56c4f6d074ca 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -65,8 +65,6 @@ struct moschip_port { struct urb *write_urb_pool[NUM_URBS]; }; =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 @@ -962,25 +960,6 @@ static void mos7720_bulk_out_data_callback(struct urb = *urb) tty_port_tty_wakeup(&mos7720_port->port->port); } =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); @@ -1901,6 +1880,11 @@ static int mos7720_startup(struct usb_serial *serial) u16 product; int ret_val; =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 @@ -1925,19 +1909,18 @@ static int mos7720_startup(struct usb_serial *seria= l) 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 /* setting configuration feature to one */ 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); @@ -1945,6 +1928,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); dev_dbg(&dev->dev, "LSR:%x\n", data); @@ -1954,6 +1944,8 @@ static int mos7720_startup(struct usb_serial *serial) =20 static void mos7720_release(struct usb_serial *serial) { + usb_kill_urb(serial->port[0]->interrupt_in_urb); + #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT /* close the parallel port */ =20 @@ -2036,7 +2028,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, .port_probe =3D mos7720_port_probe, @@ -2050,7 +2041,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 struct usb_serial_driver * const serial_drivers[] =3D { diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index f5f3b49ff9d5..7cb48d3af1f4 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1037,9 +1037,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); @@ -2179,6 +2177,17 @@ static int mos7840_calc_num_ports(struct usb_serial = *serial) return mos7840_num_ports; } =20 +static int mos7840_attach(struct usb_serial *serial) +{ + 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; + } + + return 0; +} + static int mos7840_port_probe(struct usb_serial_port *port) { struct usb_serial *serial =3D port->serial; @@ -2457,6 +2466,7 @@ static struct usb_serial_driver moschip7840_4port_dev= ice =3D { .tiocmset =3D mos7840_tiocmset, .tiocmiwait =3D usb_serial_generic_tiocmiwait, .get_icount =3D usb_serial_generic_get_icount, + .attach =3D mos7840_attach, .port_probe =3D mos7840_port_probe, .port_remove =3D mos7840_port_remove, .read_bulk_callback =3D mos7840_bulk_in_callback, diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index f6c6900bccf0..a180b17d2432 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -38,6 +38,7 @@ static int omninet_write(struct tty_struct *tty, struct = usb_serial_port *port, const unsigned char *buf, int count); static int omninet_write_room(struct tty_struct *tty); static void omninet_disconnect(struct usb_serial *serial); +static int omninet_attach(struct usb_serial *serial); static int omninet_port_probe(struct usb_serial_port *port); static int omninet_port_remove(struct usb_serial_port *port); =20 @@ -56,6 +57,7 @@ static struct usb_serial_driver zyxel_omninet_device =3D { .description =3D "ZyXEL - omni.net lcd plus usb", .id_table =3D id_table, .num_ports =3D 1, + .attach =3D omninet_attach, .port_probe =3D omninet_port_probe, .port_remove =3D omninet_port_remove, .open =3D omninet_open, @@ -104,6 +106,17 @@ struct omninet_data { __u8 od_outseq; /* Sequence number for bulk_out URBs */ }; =20 +static int omninet_attach(struct usb_serial *serial) +{ + /* 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; + } + + return 0; +} + static int omninet_port_probe(struct usb_serial_port *port) { struct omninet_data *od; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f243c734eb05..2c53775226c5 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -271,6 +271,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_LE922_USBCFG5 0x1045 @@ -1229,6 +1231,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_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5= , 0xff), @@ -2000,6 +2006,7 @@ static const struct usb_device_id option_ids[] =3D { { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158= */ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B= 1 */ .driver_info =3D (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D= -Link DWM-152/C1 */ @@ -2011,6 +2018,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 a4b88bc038b6..b8bf52bf7a94 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -134,6 +134,7 @@ static int oti6858_chars_in_buffer(struct tty_struct *t= ty); static int oti6858_tiocmget(struct tty_struct *tty); static int oti6858_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); +static int oti6858_attach(struct usb_serial *serial); static int oti6858_port_probe(struct usb_serial_port *port); static int oti6858_port_remove(struct usb_serial_port *port); =20 @@ -158,6 +159,7 @@ static struct usb_serial_driver oti6858_device =3D { .write_bulk_callback =3D oti6858_write_bulk_callback, .write_room =3D oti6858_write_room, .chars_in_buffer =3D oti6858_chars_in_buffer, + .attach =3D oti6858_attach, .port_probe =3D oti6858_port_probe, .port_remove =3D oti6858_port_remove, }; @@ -324,6 +326,20 @@ static void send_data(struct work_struct *work) usb_serial_port_softint(port); } =20 +static int oti6858_attach(struct usb_serial *serial) +{ + unsigned char num_ports =3D serial->num_ports; + + 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; + } + + return 0; +} + static int oti6858_port_probe(struct usb_serial_port *port) { struct oti6858_private *priv; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 521959370b66..4455b1fd8b70 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -49,6 +49,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) }, @@ -216,9 +217,17 @@ static int pl2303_probe(struct usb_serial *serial, static int pl2303_startup(struct usb_serial *serial) { struct pl2303_serial_private *spriv; + unsigned char num_ports =3D serial->num_ports; enum pl2303_type type =3D TYPE_01; unsigned char *buf; =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; + } + spriv =3D kzalloc(sizeof(*spriv), GFP_KERNEL); if (!spriv) 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/qcserial.c b/drivers/usb/serial/qcserial.c index f0a2ad15a992..e08ae0505ad2 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -124,6 +124,7 @@ static const struct usb_device_id id_table[] =3D { {USB_DEVICE(0x1410, 0xa021)}, /* Novatel Gobi 3000 Composite */ {USB_DEVICE(0x413c, 0x8193)}, /* Dell Gobi 3000 QDL */ {USB_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */ + {USB_DEVICE(0x413c, 0x81a6)}, /* Dell DW5570 QDL (MC8805) */ {USB_DEVICE(0x1199, 0x68a4)}, /* Sierra Wireless QDL */ {USB_DEVICE(0x1199, 0x68a5)}, /* Sierra Wireless Modem */ {USB_DEVICE(0x1199, 0x68a8)}, /* Sierra Wireless QDL */ diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index b18974cbd995..a3ed07c58754 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -408,16 +408,12 @@ static void qt2_close(struct usb_serial_port *port) { struct usb_serial *serial; struct qt2_port_private *port_priv; - unsigned long flags; int i; =20 serial =3D port->serial; port_priv =3D usb_get_serial_port_data(port); =20 - spin_lock_irqsave(&port_priv->urb_lock, flags); usb_kill_urb(port_priv->write_urb); - port_priv->urb_in_use =3D false; - spin_unlock_irqrestore(&port_priv->urb_lock, flags); =20 /* flush the port transmit buffer */ i =3D usb_control_msg(serial->dev, diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index ef0dbf0703c5..475e6c31b266 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -154,6 +154,19 @@ static int spcp8x5_probe(struct usb_serial *serial, return 0; } =20 +static int spcp8x5_attach(struct usb_serial *serial) +{ + 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; + } + + return 0; +} + static int spcp8x5_port_probe(struct usb_serial_port *port) { const struct usb_device_id *id =3D usb_get_serial_data(port->serial); @@ -477,6 +490,7 @@ static struct usb_serial_driver spcp8x5_device =3D { .tiocmget =3D spcp8x5_tiocmget, .tiocmset =3D spcp8x5_tiocmset, .probe =3D spcp8x5_probe, + .attach =3D spcp8x5_attach, .port_probe =3D spcp8x5_port_probe, .port_remove =3D spcp8x5_port_remove, }; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_= usb_3410_5052.c index 7a1f446ab204..f60a1c8f2e66 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -339,6 +339,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; + } + return 0; =20 free_tdev: diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusu= al_devs.h index 8a49c47657f4..96379e715d4b 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1990,6 +1990,13 @@ UNUSUAL_DEV( 0x152d, 0x2566, 0x0114, 0x0114, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_BROKEN_FUA ), =20 +/* Reported-by George Cherian */ +UNUSUAL_DEV(0x152d, 0x9561, 0x0000, 0x9999, + "JMicron", + "JMS56x", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_REPORT_OPCODES), + /* Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI) * and Mac USB Dock USB-SCSI */ UNUSUAL_DEV( 0x1645, 0x0007, 0x0100, 0x0133, diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_c= a91cx42.c index bfb2d3f06738..674b972216c2 100644 --- a/drivers/vme/bridges/vme_ca91cx42.c +++ b/drivers/vme/bridges/vme_ca91cx42.c @@ -468,7 +468,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/xen/gntdev.c b/drivers/xen/gntdev.c index 7ffbb9390628..1102fd09637d 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -765,7 +765,7 @@ static int gntdev_mmap(struct file *flip, struct vm_are= a_struct *vma) =20 vma->vm_ops =3D &gntdev_vmops; =20 - vma->vm_flags |=3D VM_DONTEXPAND | VM_DONTDUMP | VM_IO; + vma->vm_flags |=3D VM_DONTEXPAND | VM_DONTDUMP | VM_MIXEDMAP; =20 if (use_ptemod) vma->vm_flags |=3D VM_DONTCOPY; diff --git a/fs/block_dev.c b/fs/block_dev.c index 6d7274619bf9..ab8652b89577 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -698,7 +698,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) @@ -1731,6 +1731,7 @@ void iterate_bdevs(void (*func)(struct block_device *= , void *), void *arg) spin_lock(&inode_sb_list_lock); list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list) { struct address_space *mapping =3D inode->i_mapping; + struct block_device *bdev; =20 spin_lock(&inode->i_lock); if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW) || @@ -1751,8 +1752,12 @@ void iterate_bdevs(void (*func)(struct block_device = *, void *), void *arg) */ iput(old_inode); old_inode =3D inode; + bdev =3D I_BDEV(inode); =20 - func(I_BDEV(inode), arg); + mutex_lock(&bdev->bd_mutex); + if (bdev->bd_openers) + func(bdev, arg); + mutex_unlock(&bdev->bd_mutex); =20 spin_lock(&inode_sb_list_lock); } diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index fbd76ded9a34..f540d163586d 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c @@ -64,6 +64,20 @@ void btrfs_##name(struct work_struct *arg) \ normal_work_helper(work); \ } =20 +bool btrfs_workqueue_normal_congested(struct btrfs_workqueue *wq) +{ + /* + * We could compare wq->normal->pending with num_online_cpus() + * to support "thresh =3D=3D NO_THRESHOLD" case, but it requires + * moving up atomic_inc/dec in thresh_queue/exec_hook. Let's + * postpone it until someone needs the support of that case. + */ + if (wq->normal->thresh =3D=3D NO_THRESHOLD) + return false; + + return atomic_read(&wq->normal->pending) > wq->normal->thresh * 2; +} + BTRFS_WORK_HELPER(worker_helper); BTRFS_WORK_HELPER(delalloc_helper); BTRFS_WORK_HELPER(flush_delalloc_helper); diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h index e9e31c94758f..703989cd53ca 100644 --- a/fs/btrfs/async-thread.h +++ b/fs/btrfs/async-thread.h @@ -77,4 +77,5 @@ void btrfs_queue_work(struct btrfs_workqueue *wq, void btrfs_destroy_workqueue(struct btrfs_workqueue *wq); void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max); void btrfs_set_work_high_priority(struct btrfs_work *work); +bool btrfs_workqueue_normal_congested(struct btrfs_workqueue *wq); #endif diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 30289bf0601a..61f87c7edbb8 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -1371,7 +1371,8 @@ release_path: total_done++; =20 btrfs_release_prepared_delayed_node(delayed_node); - if (async_work->nr =3D=3D 0 || total_done < async_work->nr) + if ((async_work->nr =3D=3D 0 && total_done < BTRFS_DELAYED_WRITEBACK) || + total_done < async_work->nr) goto again; =20 free_path: @@ -1383,11 +1384,12 @@ out: =20 =20 static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_ro= ot, - struct btrfs_root *root, int nr) + struct btrfs_fs_info *fs_info, int nr) { struct btrfs_async_delayed_work *async_work; =20 - if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND) + if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND || + btrfs_workqueue_normal_congested(fs_info->delayed_workers)) return 0; =20 async_work =3D kmalloc(sizeof(*async_work), GFP_NOFS); @@ -1399,7 +1401,7 @@ static int btrfs_wq_run_delayed_node(struct btrfs_del= ayed_root *delayed_root, btrfs_async_run_delayed_root, NULL, NULL); async_work->nr =3D nr; =20 - btrfs_queue_work(root->fs_info->delayed_workers, &async_work->work); + btrfs_queue_work(fs_info->delayed_workers, &async_work->work); return 0; } =20 @@ -1426,6 +1428,7 @@ static int could_end_wait(struct btrfs_delayed_root *= delayed_root, int seq) void btrfs_balance_delayed_items(struct btrfs_root *root) { struct btrfs_delayed_root *delayed_root; + struct btrfs_fs_info *fs_info =3D root->fs_info; =20 delayed_root =3D btrfs_get_delayed_root(root); =20 @@ -1438,7 +1441,7 @@ void btrfs_balance_delayed_items(struct btrfs_root *r= oot) =20 seq =3D atomic_read(&delayed_root->items_seq); =20 - ret =3D btrfs_wq_run_delayed_node(delayed_root, root, 0); + ret =3D btrfs_wq_run_delayed_node(delayed_root, fs_info, 0); if (ret) return; =20 @@ -1447,7 +1450,7 @@ void btrfs_balance_delayed_items(struct btrfs_root *r= oot) return; } =20 - btrfs_wq_run_delayed_node(delayed_root, root, BTRFS_DELAYED_BATCH); + btrfs_wq_run_delayed_node(delayed_root, fs_info, BTRFS_DELAYED_BATCH); } =20 /* Will return 0 or -ENOMEM */ diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 482ebbcd1d72..fd518dffe6d3 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2429,11 +2429,11 @@ static noinline int __btrfs_run_delayed_refs(struct= btrfs_trans_handle *trans, if (ref && ref->seq && btrfs_check_delayed_seq(fs_info, delayed_refs, ref->seq)) { spin_unlock(&locked_ref->lock); - btrfs_delayed_ref_unlock(locked_ref); spin_lock(&delayed_refs->lock); locked_ref->processing =3D 0; delayed_refs->num_heads_ready++; spin_unlock(&delayed_refs->lock); + btrfs_delayed_ref_unlock(locked_ref); locked_ref =3D NULL; cond_resched(); count++; @@ -2479,7 +2479,10 @@ static noinline int __btrfs_run_delayed_refs(struct = btrfs_trans_handle *trans, */ if (must_insert_reserved) locked_ref->must_insert_reserved =3D 1; + spin_lock(&delayed_refs->lock); locked_ref->processing =3D 0; + delayed_refs->num_heads_ready++; + spin_unlock(&delayed_refs->lock); btrfs_debug(fs_info, "run_delayed_extent_op returned %d", ret); btrfs_delayed_ref_unlock(locked_ref); return ret; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index eb4348781a97..cde876a98fb8 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -5536,6 +5536,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; @@ -5546,8 +5550,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 023c5d905aac..a0fa16033006 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1778,12 +1778,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 8f5835c89194..61266439b603 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -262,12 +262,13 @@ static int parse_reply_info_extra(void **p, void *end, struct ceph_mds_reply_info_parsed *info, u64 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 if (info->head->op =3D=3D CEPH_MDS_OP_READDIR || - info->head->op =3D=3D CEPH_MDS_OP_LSSNAP) + else if (op =3D=3D CEPH_MDS_OP_READDIR || op =3D=3D CEPH_MDS_OP_LSSNAP) return parse_reply_info_dir(p, end, info, features); - else if (info->head->op =3D=3D CEPH_MDS_OP_CREATE) + else if (op =3D=3D CEPH_MDS_OP_CREATE) return parse_reply_info_create(p, end, info, features); else return -EIO; diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 1c663a16f78a..ba4b92846cf0 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -606,6 +606,8 @@ struct TCP_Server_Info { #ifdef CONFIG_CIFS_SMB2 unsigned int max_read; unsigned int max_write; + struct delayed_work reconnect; /* reconnect workqueue job */ + struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ #endif /* CONFIG_CIFS_SMB2 */ }; =20 @@ -795,6 +797,7 @@ cap_unix(struct cifs_ses *ses) struct cifs_tcon { struct list_head tcon_list; int tc_count; + struct list_head rlist; /* reconnect list */ struct list_head openFileList; spinlock_t open_file_lock; /* protects list above */ struct cifs_ses *ses; /* pointer to session associated with */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 05ce3072fb09..ea1cbff2932f 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -203,6 +203,9 @@ extern void cifs_add_pending_open_locked(struct cifs_fi= d *fid, struct tcon_link *tlink, struct cifs_pending_open *open); extern void cifs_del_pending_open(struct cifs_pending_open *open); +extern void cifs_put_tcp_session(struct TCP_Server_Info *server, + int from_reconnect); +extern void cifs_put_tcon(struct cifs_tcon *tcon); =20 #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) extern void cifs_dfs_release_automount_timer(void); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 4392296e6f3f..b8c5b541c813 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -52,6 +52,9 @@ #include "nterr.h" #include "rfc1002pdu.h" #include "fscache.h" +#ifdef CONFIG_CIFS_SMB2 +#include "smb2proto.h" +#endif =20 #define CIFS_PORT 445 #define RFC1001_PORT 139 @@ -2060,8 +2063,8 @@ cifs_find_tcp_session(struct smb_vol *vol) return NULL; } =20 -static void -cifs_put_tcp_session(struct TCP_Server_Info *server) +void +cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) { struct task_struct *task; =20 @@ -2078,6 +2081,19 @@ cifs_put_tcp_session(struct TCP_Server_Info *server) =20 cancel_delayed_work_sync(&server->echo); =20 +#ifdef CONFIG_CIFS_SMB2 + if (from_reconnect) + /* + * Avoid deadlock here: reconnect work calls + * cifs_put_tcp_session() at its end. Need to be sure + * that reconnect work does nothing with server pointer after + * that step. + */ + cancel_delayed_work(&server->reconnect); + else + cancel_delayed_work_sync(&server->reconnect); +#endif + spin_lock(&GlobalMid_Lock); server->tcpStatus =3D CifsExiting; spin_unlock(&GlobalMid_Lock); @@ -2142,6 +2158,10 @@ cifs_get_tcp_session(struct smb_vol *volume_info) INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); INIT_LIST_HEAD(&tcp_ses->smb_ses_list); INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); +#ifdef CONFIG_CIFS_SMB2 + INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server); + mutex_init(&tcp_ses->reconnect_mutex); +#endif memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr, sizeof(tcp_ses->srcaddr)); memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr, @@ -2294,7 +2314,7 @@ cifs_put_smb_ses(struct cifs_ses *ses) spin_unlock(&cifs_tcp_ses_lock); =20 sesInfoFree(ses); - cifs_put_tcp_session(server); + cifs_put_tcp_session(server, 0); } =20 #ifdef CONFIG_KEYS @@ -2467,7 +2487,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, stru= ct smb_vol *volume_info) mutex_unlock(&ses->session_mutex); =20 /* existing SMB ses has a server reference already */ - cifs_put_tcp_session(server); + cifs_put_tcp_session(server, 0); free_xid(xid); return ses; } @@ -2557,7 +2577,7 @@ cifs_find_tcon(struct cifs_ses *ses, const char *unc) return NULL; } =20 -static void +void cifs_put_tcon(struct cifs_tcon *tcon) { unsigned int xid; @@ -3606,7 +3626,7 @@ mount_fail_check: else if (ses) cifs_put_smb_ses(ses); else - cifs_put_tcp_session(server); + cifs_put_tcp_session(server, 0); bdi_destroy(&cifs_sb->bdi); } =20 @@ -3910,7 +3930,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kui= d_t fsuid) ses =3D cifs_get_smb_ses(master_tcon->ses->server, vol_info); if (IS_ERR(ses)) { tcon =3D (struct cifs_tcon *)ses; - cifs_put_tcp_session(master_tcon->ses->server); + cifs_put_tcp_session(master_tcon->ses->server, 0); goto out; } =20 diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c index 45992944e238..b87b07504947 100644 --- a/fs/cifs/smb2file.c +++ b/fs/cifs/smb2file.c @@ -241,7 +241,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) * and check it for zero before using. */ max_buf =3D tlink_tcon(cfile->tlink)->ses->server->maxBuf; - if (!max_buf) { + if (max_buf < sizeof(struct smb2_lock_element)) { free_xid(xid); return -EINVAL; } diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 1da1622aa1ea..2256a992389f 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -282,7 +282,7 @@ out: case SMB2_CHANGE_NOTIFY: case SMB2_QUERY_INFO: case SMB2_SET_INFO: - return -EAGAIN; + rc =3D -EAGAIN; } unload_nls(nls_codepage); return rc; @@ -1598,6 +1598,54 @@ smb2_echo_callback(struct mid_q_entry *mid) add_credits(server, credits_received, CIFS_ECHO_OP); } =20 +void smb2_reconnect_server(struct work_struct *work) +{ + struct TCP_Server_Info *server =3D container_of(work, + struct TCP_Server_Info, reconnect.work); + struct cifs_ses *ses; + struct cifs_tcon *tcon, *tcon2; + struct list_head tmp_list; + int tcon_exist =3D false; + + /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */ + mutex_lock(&server->reconnect_mutex); + + INIT_LIST_HEAD(&tmp_list); + cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n"); + + spin_lock(&cifs_tcp_ses_lock); + list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { + if (tcon->need_reconnect) { + tcon->tc_count++; + list_add_tail(&tcon->rlist, &tmp_list); + tcon_exist =3D true; + } + } + } + /* + * Get the reference to server struct to be sure that the last call of + * cifs_put_tcon() in the loop below won't release the server pointer. + */ + if (tcon_exist) + server->srv_count++; + + spin_unlock(&cifs_tcp_ses_lock); + + list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) { + smb2_reconnect(SMB2_ECHO, tcon); + list_del_init(&tcon->rlist); + cifs_put_tcon(tcon); + } + + cifs_dbg(FYI, "Reconnecting tcons finished\n"); + mutex_unlock(&server->reconnect_mutex); + + /* now we can safely release srv struct */ + if (tcon_exist) + cifs_put_tcp_session(server, 1); +} + int SMB2_echo(struct TCP_Server_Info *server) { @@ -1610,32 +1658,11 @@ SMB2_echo(struct TCP_Server_Info *server) cifs_dbg(FYI, "In echo request\n"); =20 if (server->tcpStatus =3D=3D CifsNeedNegotiate) { - struct list_head *tmp, *tmp2; - struct cifs_ses *ses; - struct cifs_tcon *tcon; - - cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n"); - spin_lock(&cifs_tcp_ses_lock); - list_for_each(tmp, &server->smb_ses_list) { - ses =3D list_entry(tmp, struct cifs_ses, smb_ses_list); - list_for_each(tmp2, &ses->tcon_list) { - tcon =3D list_entry(tmp2, struct cifs_tcon, - tcon_list); - /* add check for persistent handle reconnect */ - if (tcon && tcon->need_reconnect) { - spin_unlock(&cifs_tcp_ses_lock); - rc =3D smb2_reconnect(SMB2_ECHO, tcon); - spin_lock(&cifs_tcp_ses_lock); - } - } - } - spin_unlock(&cifs_tcp_ses_lock); + /* No need to send echo on newly established connections */ + queue_delayed_work(cifsiod_wq, &server->reconnect, 0); + return rc; } =20 - /* if no session, renegotiate failed above */ - if (server->tcpStatus =3D=3D CifsNeedNegotiate) - return -EIO; - rc =3D small_smb2_init(SMB2_ECHO, NULL, (void **)&req); if (rc) return rc; diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 8e0d57bf446b..98d9b36ea3e2 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -89,6 +89,7 @@ extern int smb2_open_file(const unsigned int xid, extern int smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, const unsigned int xid); extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile); +extern void smb2_reconnect_server(struct work_struct *work); =20 /* * SMB2 Worker functions - most of protocol specific implementation details diff --git a/fs/exec.c b/fs/exec.c index 993ed0aba99a..5b653a126b20 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -19,7 +19,7 @@ * current->executable is only used by the procfs. This allows a dispatch * table to check for several different types of binary formats. We keep * trying until we recognize the file or we run out of supported binary - * formats.=20 + * formats. */ =20 #include @@ -1087,6 +1087,13 @@ int flush_old_exec(struct linux_binprm * bprm) flush_thread(); current->personality &=3D ~bprm->per_clear; =20 + /* + * We have to apply CLOEXEC before we change whether the process is + * dumpable (in setup_new_exec) to avoid a race with a process in userspa= ce + * trying to access the should-be-closed file descriptors of a process + * undergoing exec(2). + */ + do_close_on_exec(current->files); return 0; =20 out: @@ -1136,7 +1143,6 @@ void setup_new_exec(struct linux_binprm * bprm) group */ current->self_exec_id++; flush_signal_handlers(current, 0); - do_close_on_exec(current->files); } EXPORT_SYMBOL(setup_new_exec); =20 diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 7af6a3dcbb1f..7bd13f3d1790 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -340,8 +340,10 @@ static int ext4_update_inline_data(handle_t *handle, s= truct inode *inode, =20 len -=3D EXT4_MIN_INLINE_DATA_SIZE; value =3D kzalloc(len, GFP_NOFS); - if (!value) + if (!value) { + error =3D -ENOMEM; goto out; + } =20 error =3D ext4_xattr_ibody_get(inode, i.name_index, i.name, value, len); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c37dd715060f..898e9659ebf1 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4118,6 +4118,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; uid_t i_uid; gid_t i_gid; @@ -4209,6 +4210,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 62d0c5cbcad6..425dd618a9e2 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -668,7 +668,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 @@ -2252,7 +2252,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *s= eq, void *v) struct ext4_group_info *grinfo; 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 13a33c3047f4..c608d805f509 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3301,10 +3301,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; @@ -3407,7 +3412,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; @@ -3427,16 +3432,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_sb =3D sb; sbi->s_inode_readahead_blks =3D EXT4_DEF_INODE_READAHEAD_BLKS; @@ -3582,11 +3585,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, 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, 0)) { + ext4_msg(sb, KERN_WARNING, + "failed to parse options in superblock: %s", + s_mount_opts); + } + kfree(s_mount_opts); } sbi->s_def_mount_opt =3D sbi->s_mount_opt; if (!parse_options((char *) data, sb, &journal_devnum, @@ -3750,12 +3761,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); @@ -3839,13 +3854,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; - } - /* Do we have standard group size of clustersize * 8 blocks ? */ if (sbi->s_blocks_per_group =3D=3D clustersize << 3) set_opt2(sb, STD_GROUP_SIZE); @@ -4251,7 +4259,9 @@ no_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) @@ -4325,8 +4335,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 err ? err : ret; } diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index b52c12cf5873..df18edb33601 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -295,6 +295,7 @@ static int stat_open(struct inode *inode, struct file *= file) } =20 static const struct file_operations stat_fops =3D { + .owner =3D THIS_MODULE, .open =3D stat_open, .read =3D seq_read, .llseek =3D seq_lseek, diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index c832599669bc..5cbdbb6aedde 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -455,7 +455,7 @@ void nfs_force_use_readdirplus(struct inode *dir) { if (!list_empty(&NFS_I(dir)->open_files)) { nfs_advise_use_readdirplus(dir); - nfs_zap_mapping(dir, dir->i_mapping); + invalidate_mapping_pages(dir->i_mapping, 0, -1); } } =20 @@ -837,17 +837,6 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc) goto out; } =20 -static bool nfs_dir_mapping_need_revalidate(struct inode *dir) -{ - struct nfs_inode *nfsi =3D NFS_I(dir); - - if (nfs_attribute_cache_expired(dir)) - return true; - if (nfsi->cache_validity & NFS_INO_INVALID_DATA) - return true; - return false; -} - /* The file offset position represents the dirent entry number. A last cookie cache takes care of the common case of reading the whole directory. @@ -880,7 +869,7 @@ static int nfs_readdir(struct file *file, struct dir_co= ntext *ctx) desc->plus =3D nfs_use_readdirplus(inode, ctx) ? 1 : 0; =20 nfs_block_sillyrename(dentry); - if (ctx->pos =3D=3D 0 || nfs_dir_mapping_need_revalidate(inode)) + if (ctx->pos =3D=3D 0 || nfs_attribute_cache_expired(inode)) res =3D nfs_revalidate_mapping(inode, file->f_mapping); if (res < 0) goto out; diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 4042ff58fe3f..19cfc636b691 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -403,7 +403,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/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayo= utdev.c index 44bf0140a4c7..651b171387e2 100644 --- a/fs/nfs/filelayout/filelayoutdev.c +++ b/fs/nfs/filelayout/filelayoutdev.c @@ -827,7 +827,8 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u3= 2 ds_idx) nfs4_wait_ds_connect(ds); } out_test_devid: - if (filelayout_test_devid_unavailable(devid)) + if (ret->ds_clp =3D=3D NULL || + filelayout_test_devid_unavailable(devid)) ret =3D NULL; out: return ret; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 3d88bc967c8e..f96c66b4d504 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1086,6 +1086,7 @@ static void nfs_increment_seqid(int status, struct nf= s_seqid *seqid) case -NFS4ERR_BADXDR: case -NFS4ERR_RESOURCE: case -NFS4ERR_NOFILEHANDLE: + case -NFS4ERR_MOVED: /* Non-seqid mutating errors */ return; }; diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index fbb9dfb7b1d2..12c6ff070cd8 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c @@ -249,12 +249,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 @@ -277,50 +275,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 118a494a323e..3c4d6f5811e8 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -3305,6 +3305,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 5d965e83bd43..783bcdce5666 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 66334a30cea8..e1b30931974d 100644 --- a/fs/ocfs2/stackglue.h +++ b/fs/ocfs2/stackglue.h @@ -298,4 +298,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 962c7f7e03f6..41f10ce929dd 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -212,6 +212,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 8a40cf9c02d7..f07596463cde 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 @@ -403,7 +408,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 @@ -2767,7 +2784,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_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 3d807ef4f821..09dc999a7e4e 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1632,6 +1632,7 @@ xfs_swap_extents( int error =3D 0; int aforkblks =3D 0; int taforkblks =3D 0; + xfs_extnum_t nextents; __uint64_t tmp; int lock_flags; =20 @@ -1833,7 +1834,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; } @@ -1852,7 +1854,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/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 4b973653a0e8..21737d4bab7c 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3813,6 +3813,7 @@ xlog_recover_clear_agi_bucket( agi->agi_unlinked[bucket] =3D cpu_to_be32(NULLAGINO); offset =3D offsetof(xfs_agi_t, agi_unlinked) + (sizeof(xfs_agino_t) * bucket); + xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF); xfs_trans_log_buf(tp, agibp, offset, (offset + sizeof(xfs_agino_t) - 1)); =20 diff --git a/include/linux/can/core.h b/include/linux/can/core.h index a0875001b13c..df08a41d5be5 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 285111f95464..3b73e762b2f5 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -122,22 +122,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) -#define __cpu_notifier(fn, pri) do { (void)(fn); } while (0) -#endif /* #else #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */ =20 -#ifdef CONFIG_HOTPLUG_CPU extern int register_cpu_notifier(struct notifier_block *nb); extern int __register_cpu_notifier(struct notifier_block *nb); extern void unregister_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); -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) +#define __cpu_notifier(fn, pri) do { (void)(fn); } while (0) + static inline int register_cpu_notifier(struct notifier_block *nb) { return 0; @@ -147,7 +141,6 @@ static inline int __register_cpu_notifier(struct notifi= er_block *nb) { return 0; } -#endif =20 static inline void unregister_cpu_notifier(struct notifier_block *nb) { diff --git a/include/linux/jump_label_ratelimit.h b/include/linux/jump_labe= l_ratelimit.h index 089f70f83e97..23da3af459fe 100644 --- a/include/linux/jump_label_ratelimit.h +++ b/include/linux/jump_label_ratelimit.h @@ -14,6 +14,7 @@ struct static_key_deferred { =20 #ifdef HAVE_JUMP_LABEL extern void static_key_slow_dec_deferred(struct static_key_deferred *key); +extern void static_key_deferred_flush(struct static_key_deferred *key); extern void jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl); =20 @@ -26,6 +27,10 @@ static inline void static_key_slow_dec_deferred(struct s= tatic_key_deferred *key) STATIC_KEY_CHECK_USE(); static_key_slow_dec(&key->key); } +static inline void static_key_deferred_flush(struct static_key_deferred *k= ey) +{ + STATIC_KEY_CHECK_USE(); +} static inline void jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b3404718fda1..e5145f8e4004 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2016,14 +2016,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/linux/nfs4.h b/include/linux/nfs4.h index a1e3064a8d99..b17c7031d2bb 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -243,7 +243,7 @@ enum nfsstat4 { =20 static inline bool seqid_mutating_err(u32 err) { - /* rfc 3530 section 8.1.5: */ + /* See RFC 7530, section 9.1.7 */ switch (err) { case NFS4ERR_STALE_CLIENTID: case NFS4ERR_STALE_STATEID: @@ -252,6 +252,7 @@ static inline bool seqid_mutating_err(u32 err) case NFS4ERR_BADXDR: case NFS4ERR_RESOURCE: case NFS4ERR_NOFILEHANDLE: + case NFS4ERR_MOVED: return false; }; return true; diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 70736b98c721..c2a0ecf02d27 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -175,6 +175,7 @@ void rpc_force_rebind(struct rpc_clnt *); size_t rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t); const char *rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t); int rpc_localaddr(struct rpc_clnt *, struct sockaddr *, size_t); +void rpc_cleanup_clids(void); =20 #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_CLNT_H */ diff --git a/include/linux/tcp.h b/include/linux/tcp.h index a0513210798f..d7da0cf3332b 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -57,8 +57,13 @@ static inline unsigned int tcp_optlen(const struct sk_bu= ff *skb) =20 /* TCP Fast Open Cookie as stored in memory */ struct tcp_fastopen_cookie { + union { + u8 val[TCP_FASTOPEN_COOKIE_MAX]; +#if IS_ENABLED(CONFIG_IPV6) + struct in6_addr addr; +#endif + }; s8 len; - u8 val[TCP_FASTOPEN_COOKIE_MAX]; }; =20 /* This defines a selective acknowledgement block. */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index e46c437944f7..024ab92822fd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3942,6 +3942,17 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *b= ss); =20 /** + * cfg80211_abandon_assoc - notify cfg80211 of abandoned association attem= pt + * @dev: network device + * @bss: The BSS entry with which association was abandoned. + * + * Call this whenever - for reasons reported through other API, like deaut= h RX, + * an association attempt was abandoned. + * This function may sleep. The caller must hold the corresponding wdev's = mutex. + */ +void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *b= ss); + +/** * cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc fra= me * @dev: network device * @buf: 802.11 frame (header + body) diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h index a6fd939f202d..c8b8852ce9b8 100644 --- a/include/net/cipso_ipv4.h +++ b/include/net/cipso_ipv4.h @@ -302,6 +302,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) || (tag_len > (opt_len - opt_iter))) { err_offset =3D opt_iter + 1; diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h index 99eac12d040b..6e11c346137d 100644 --- a/include/net/netfilter/nf_log.h +++ b/include/net/netfilter/nf_log.h @@ -12,6 +12,8 @@ #define NF_LOG_UID 0x08 /* Log UID owning local socket */ #define NF_LOG_MASK 0x0f =20 +#define NF_LOG_PREFIXLEN 128 + #define NF_LOG_TYPE_LOG 0x01 #define NF_LOG_TYPE_ULOG 0x02 =20 diff --git a/include/net/sock.h b/include/net/sock.h index 07ede95596bb..ae9dc6ce5712 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1411,7 +1411,7 @@ static inline struct inode *SOCK_INODE(struct socket = *socket) * Functions for memory accounting */ int __sk_mem_schedule(struct sock *sk, int size, int kind); -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) @@ -1452,7 +1452,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) @@ -1460,7 +1460,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) @@ -1475,6 +1475,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) @@ -1569,6 +1579,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigne= d long size, int force, void sock_wfree(struct sk_buff *skb); void skb_orphan_partial(struct sk_buff *skb); void sock_rfree(struct sk_buff *skb); +void sock_efree(struct sk_buff *skb); void sock_edemux(struct sk_buff *skb); =20 int sock_setsockopt(struct socket *sock, int level, int op, diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h index aa33fd1b2d4f..a81f5473a801 100644 --- a/include/uapi/linux/usb/ch9.h +++ b/include/uapi/linux/usb/ch9.h @@ -398,6 +398,11 @@ struct usb_endpoint_descriptor { #define USB_ENDPOINT_XFER_INT 3 #define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 =20 +#define USB_EP_MAXP_MULT_SHIFT 11 +#define USB_EP_MAXP_MULT_MASK (3 << USB_EP_MAXP_MULT_SHIFT) +#define USB_EP_MAXP_MULT(m) \ + (((m) & USB_EP_MAXP_MULT_MASK) >> USB_EP_MAXP_MULT_SHIFT) + /* The USB 3.0 spec redefines bits 5:4 of bmAttributes as interrupt ep typ= e. */ #define USB_ENDPOINT_INTRTYPE 0x30 #define USB_ENDPOINT_INTR_PERIODIC (0 << 4) @@ -605,6 +610,20 @@ static inline int usb_endpoint_maxp(const struct usb_e= ndpoint_descriptor *epd) return __le16_to_cpu(epd->wMaxPacketSize); } =20 +/** + * usb_endpoint_maxp_mult - get endpoint's transactional opportunities + * @epd: endpoint to be checked + * + * Return @epd's wMaxPacketSize[12:11] + 1 + */ +static inline int +usb_endpoint_maxp_mult(const struct usb_endpoint_descriptor *epd) +{ + int maxp =3D __le16_to_cpu(epd->wMaxPacketSize); + + return USB_EP_MAXP_MULT(maxp) + 1; +} + static inline int usb_endpoint_interrupt_type( const struct usb_endpoint_descriptor *epd) { diff --git a/ipc/shm.c b/ipc/shm.c index 471f730e8640..f8bb7b3fdd49 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -1044,8 +1044,8 @@ out_unlock1: * "raddr" thing points to kernel space, and there has to be a wrapper aro= und * this. */ -long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, - unsigned long shmlba) +long do_shmat(int shmid, char __user *shmaddr, int shmflg, + ulong *raddr, unsigned long shmlba) { struct shmid_kernel *shp; unsigned long addr; @@ -1066,8 +1066,13 @@ long do_shmat(int shmid, char __user *shmaddr, int s= hmflg, 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 247d8dd17a2c..e160b9b065e6 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -210,12 +210,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); EXPORT_SYMBOL(__register_cpu_notifier); =20 @@ -233,6 +227,13 @@ void __ref __unregister_cpu_notifier(struct notifier_b= lock *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)); +} + /** * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU * @cpu: a CPU id diff --git a/kernel/events/core.c b/kernel/events/core.c index 7413ddd1de57..2faaed3ba61b 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5472,6 +5472,27 @@ static void perf_event_mmap_event(struct perf_mmap_e= vent *mmap_event) char *buf =3D NULL; char *name; =20 + if (vma->vm_flags & VM_READ) + prot |=3D PROT_READ; + if (vma->vm_flags & VM_WRITE) + prot |=3D PROT_WRITE; + if (vma->vm_flags & VM_EXEC) + prot |=3D PROT_EXEC; + + if (vma->vm_flags & VM_MAYSHARE) + flags =3D MAP_SHARED; + else + flags =3D MAP_PRIVATE; + + if (vma->vm_flags & VM_DENYWRITE) + flags |=3D MAP_DENYWRITE; + if (vma->vm_flags & VM_MAYEXEC) + flags |=3D MAP_EXECUTABLE; + if (vma->vm_flags & VM_LOCKED) + flags |=3D MAP_LOCKED; + if (vma->vm_flags & VM_HUGETLB) + flags |=3D MAP_HUGETLB; + if (file) { struct inode *inode; dev_t dev; @@ -5498,27 +5519,6 @@ static void perf_event_mmap_event(struct perf_mmap_e= vent *mmap_event) maj =3D MAJOR(dev); min =3D MINOR(dev); =20 - if (vma->vm_flags & VM_READ) - prot |=3D PROT_READ; - if (vma->vm_flags & VM_WRITE) - prot |=3D PROT_WRITE; - if (vma->vm_flags & VM_EXEC) - prot |=3D PROT_EXEC; - - if (vma->vm_flags & VM_MAYSHARE) - flags =3D MAP_SHARED; - else - flags =3D MAP_PRIVATE; - - if (vma->vm_flags & VM_DENYWRITE) - flags |=3D MAP_DENYWRITE; - if (vma->vm_flags & VM_MAYEXEC) - flags |=3D MAP_EXECUTABLE; - if (vma->vm_flags & VM_LOCKED) - flags |=3D MAP_LOCKED; - if (vma->vm_flags & VM_HUGETLB) - flags |=3D MAP_HUGETLB; - goto got_name; } else { name =3D (char *)arch_vma_name(vma); diff --git a/kernel/futex.c b/kernel/futex.c index af67d3eaf232..1d1ccb0e87a7 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -3085,4 +3085,4 @@ static int __init futex_init(void) =20 return 0; } -__initcall(futex_init); +core_initcall(futex_init); diff --git a/kernel/jump_label.c b/kernel/jump_label.c index 9019f15deab2..7d4d0a917d13 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c @@ -116,6 +116,13 @@ void static_key_slow_dec_deferred(struct static_key_de= ferred *key) } EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred); =20 +void static_key_deferred_flush(struct static_key_deferred *key) +{ + STATIC_KEY_CHECK_USE(); + flush_delayed_work(&key->work); +} +EXPORT_SYMBOL_GPL(static_key_deferred_flush); + void jump_label_rate_limit(struct static_key_deferred *key, unsigned long rl) { diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 627bf25048c6..e4c6905db298 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1356,7 +1356,7 @@ static void call_console_drivers(int level, const cha= r *text, size_t len) { struct console *con; =20 - trace_console(text, len); + trace_console_rcuidle(text, len); =20 if (level >=3D console_loglevel && !ignore_loglevel) return; diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 349ada9a7fa5..ed0d9b8b666a 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -753,6 +753,9 @@ cputime_t task_gtime(struct task_struct *t) unsigned int seq; cputime_t gtime; =20 + if (!context_tracking_is_enabled()) + return t->gtime; + do { seq =3D read_seqbegin(&t->vtime_seqlock); =20 diff --git a/kernel/sysctl.c b/kernel/sysctl.c index f9293694b52a..3a3172559b22 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -2317,6 +2317,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/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_func= tions_graph.c index 4de3e57f723c..319cf14c92d3 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -841,6 +841,10 @@ print_graph_entry_leaf(struct trace_iterator *iter, =20 cpu_data =3D per_cpu_ptr(data->cpu_data, cpu); =20 + /* If a graph tracer ignored set_graph_notrace */ + if (call->depth < -1) + call->depth +=3D FTRACE_NOTRACE_DEPTH; + /* * Comments display at + 1 to depth. Since * this is a leaf function, keep the comments @@ -849,7 +853,8 @@ print_graph_entry_leaf(struct trace_iterator *iter, cpu_data->depth =3D call->depth - 1; =20 /* No need to keep this function around for this depth */ - if (call->depth < FTRACE_RETFUNC_DEPTH) + if (call->depth < FTRACE_RETFUNC_DEPTH && + !WARN_ON_ONCE(call->depth < 0)) cpu_data->enter_funcs[call->depth] =3D 0; } =20 @@ -886,11 +891,16 @@ print_graph_entry_nested(struct trace_iterator *iter, struct fgraph_cpu_data *cpu_data; int cpu =3D iter->cpu; =20 + /* If a graph tracer ignored set_graph_notrace */ + if (call->depth < -1) + call->depth +=3D FTRACE_NOTRACE_DEPTH; + cpu_data =3D per_cpu_ptr(data->cpu_data, cpu); cpu_data->depth =3D call->depth; =20 /* Save this function pointer to see if the exit matches */ - if (call->depth < FTRACE_RETFUNC_DEPTH) + if (call->depth < FTRACE_RETFUNC_DEPTH && + !WARN_ON_ONCE(call->depth < 0)) cpu_data->enter_funcs[call->depth] =3D call->func; } =20 @@ -1143,7 +1153,8 @@ print_graph_return(struct ftrace_graph_ret *trace, st= ruct trace_seq *s, */ cpu_data->depth =3D trace->depth - 1; =20 - if (trace->depth < FTRACE_RETFUNC_DEPTH) { + if (trace->depth < FTRACE_RETFUNC_DEPTH && + !WARN_ON_ONCE(trace->depth < 0)) { if (cpu_data->enter_funcs[trace->depth] !=3D trace->func) func_match =3D 0; cpu_data->enter_funcs[trace->depth] =3D 0; diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 6fe2c84eb055..ce12a88a8fd1 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1657,7 +1657,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 a5024d71fcc3..31b5b25c3d2d 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1482,6 +1482,11 @@ static ssize_t do_generic_file_read(struct file *fil= p, 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 dc528a51ccbf..abc04a803aa8 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1192,6 +1192,18 @@ out_unlock: 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 vm_area_struct *vma, unsigned long addr, pmd_t *pmd, @@ -1202,9 +1214,6 @@ struct page *follow_trans_huge_pmd(struct vm_area_str= uct *vma, =20 assert_spin_locked(pmd_lockptr(mm, pmd)); =20 - if (flags & FOLL_WRITE && !pmd_write(*pmd)) - goto out; - /* Avoid dumping huge zero page */ if ((flags & FOLL_DUMP) && is_huge_zero_pmd(*pmd)) return ERR_PTR(-EFAULT); @@ -1215,6 +1224,10 @@ struct page *follow_trans_huge_pmd(struct vm_area_st= ruct *vma, =20 page =3D pmd_page(*pmd); VM_BUG_ON_PAGE(!PageHead(page), page); + + if (flags & FOLL_WRITE && !can_follow_write_pmd(*pmd, page, flags)) + goto out; + if (flags & FOLL_TOUCH) { pmd_t _pmd; /* diff --git a/mm/hugetlb.c b/mm/hugetlb.c index fca6c6c91d76..467d04b62948 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1301,23 +1301,32 @@ free: } =20 /* - * When releasing a hugetlb pool reservation, any surplus pages that were - * allocated to satisfy the reservation must be explicitly freed if they w= ere - * never used. - * Called with hugetlb_lock held. + * This routine has two main purposes: + * 1) Decrement the reservation count (resv_huge_pages) by the value passed + * in unused_resv_pages. This corresponds to the prior adjustments made + * to the associated reservation map. + * 2) Free any unused surplus pages that may have been allocated to satisfy + * the reservation. As many as unused_resv_pages may be freed. + * + * Called with hugetlb_lock held. However, the lock could be dropped (and + * reacquired) during calls to cond_resched_lock. Whenever dropping the l= ock, + * we must make sure nobody else can claim pages we are in the process of + * freeing. Do this by ensuring resv_huge_page always is greater than the + * number of huge pages we plan to free when dropping the lock. */ static void return_unused_surplus_pages(struct hstate *h, unsigned long unused_resv_pages) { unsigned long nr_pages; =20 - /* Uncommit the reservation */ - h->resv_huge_pages -=3D unused_resv_pages; - /* Cannot return gigantic pages currently */ if (hstate_is_gigantic(h)) - return; + goto out; =20 + /* + * Part (or even all) of the reservation could have been backed + * by pre-allocated pages. Only free surplus pages. + */ nr_pages =3D min(unused_resv_pages, h->surplus_huge_pages); =20 /* @@ -1327,12 +1336,22 @@ static void return_unused_surplus_pages(struct hsta= te *h, * when the nodes with surplus pages have no free pages. * free_pool_huge_page() will balance the the freed pages across the * on-line nodes with memory and will handle the hstate accounting. + * + * Note that we decrement resv_huge_pages as we free the pages. If + * we drop the lock, resv_huge_pages will still be sufficiently large + * to cover subsequent pages we may free. */ while (nr_pages--) { + h->resv_huge_pages--; + unused_resv_pages--; if (!free_pool_huge_page(h, &node_states[N_MEMORY], 1)) - break; + goto out; cond_resched_lock(&hugetlb_lock); } + +out: + /* Fully uncommit the reservation */ + h->resv_huge_pages -=3D unused_resv_pages; } =20 /* diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 8d423bc649b9..f876f707fd9e 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 d6030d6949df..ee6eee7a8b42 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -446,6 +446,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 identification + * @sk: socket pointer (might be NULL) * * Description: * Invokes the callback function with the received sk_buff and the given @@ -469,7 +470,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; @@ -497,6 +498,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++; @@ -521,8 +523,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 /** @@ -597,8 +602,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 fca0fe9fc45a..b86f5129e838 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 #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS) diff --git a/net/can/bcm.c b/net/can/bcm.c index b96434d09177..468dfa12eebe 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -706,14 +706,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); @@ -1169,7 +1178,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); @@ -1178,7 +1187,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 050a2110d43f..d4921582d3bd 100644 --- a/net/can/gw.c +++ b/net/can/gw.c @@ -441,7 +441,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 9f5ee3a6b666..59e4cab9cd76 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -164,7 +164,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) @@ -185,7 +185,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 f2ea1a093800..a1244a228811 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1977,6 +1977,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 75be7e226268..c14258a3841e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1600,24 +1600,19 @@ EXPORT_SYMBOL(call_netdevice_notifiers); =20 static struct static_key netstamp_needed __read_mostly; #ifdef HAVE_JUMP_LABEL -/* We are not allowed to call static_key_slow_dec() from irq context - * If net_disable_timestamp() is called from irq context, defer the - * static_key_slow_dec() calls. - */ static atomic_t netstamp_needed_deferred; -#endif - -void net_enable_timestamp(void) +static void netstamp_clear(struct work_struct *work) { -#ifdef HAVE_JUMP_LABEL int deferred =3D atomic_xchg(&netstamp_needed_deferred, 0); =20 - if (deferred) { - while (--deferred) - static_key_slow_dec(&netstamp_needed); - return; - } + while (deferred--) + static_key_slow_dec(&netstamp_needed); +} +static DECLARE_WORK(netstamp_work, netstamp_clear); #endif + +void net_enable_timestamp(void) +{ static_key_slow_inc(&netstamp_needed); } EXPORT_SYMBOL(net_enable_timestamp); @@ -1625,12 +1620,12 @@ EXPORT_SYMBOL(net_enable_timestamp); void net_disable_timestamp(void) { #ifdef HAVE_JUMP_LABEL - if (in_interrupt()) { - atomic_inc(&netstamp_needed_deferred); - return; - } -#endif + /* net_disable_timestamp() can be called from non process context */ + atomic_inc(&netstamp_needed_deferred); + schedule_work(&netstamp_work); +#else static_key_slow_dec(&netstamp_needed); +#endif } EXPORT_SYMBOL(net_disable_timestamp); =20 @@ -2287,7 +2282,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: @@ -2555,9 +2550,9 @@ static netdev_features_t harmonize_features(struct sk= _buff *skb, if (skb->ip_summed !=3D CHECKSUM_NONE && !can_checksum_protocol(features, type)) { features &=3D ~NETIF_F_ALL_CSUM; - } else if (illegal_highdma(skb->dev, skb)) { - features &=3D ~NETIF_F_SG; } + if (illegal_highdma(skb->dev, skb)) + features &=3D ~NETIF_F_SG; =20 return features; } @@ -3920,7 +3915,9 @@ static void skb_gro_reset_offset(struct sk_buff *skb) pinfo->nr_frags && !PageHighMem(skb_frag_page(frag0))) { NAPI_GRO_CB(skb)->frag0 =3D skb_frag_address(frag0); - NAPI_GRO_CB(skb)->frag0_len =3D skb_frag_size(frag0); + NAPI_GRO_CB(skb)->frag0_len =3D min_t(unsigned int, + skb_frag_size(frag0), + skb->end - skb->tail); } } =20 @@ -4815,6 +4812,7 @@ static inline bool netdev_adjacent_is_neigh_list(stru= ct net_device *dev, =20 static int __netdev_adjacent_dev_insert(struct net_device *dev, struct net_device *adj_dev, + u16 ref_nr, struct list_head *dev_list, void *private, bool master) { @@ -4824,7 +4822,7 @@ static int __netdev_adjacent_dev_insert(struct net_de= vice *dev, adj =3D __netdev_find_adj(dev, adj_dev, dev_list); =20 if (adj) { - adj->ref_nr++; + adj->ref_nr +=3D ref_nr; return 0; } =20 @@ -4834,7 +4832,7 @@ static int __netdev_adjacent_dev_insert(struct net_de= vice *dev, =20 adj->dev =3D adj_dev; adj->master =3D master; - adj->ref_nr =3D 1; + adj->ref_nr =3D ref_nr; adj->private =3D private; dev_hold(adj_dev); =20 @@ -4873,6 +4871,7 @@ free_adj: =20 static void __netdev_adjacent_dev_remove(struct net_device *dev, struct net_device *adj_dev, + u16 ref_nr, struct list_head *dev_list) { struct netdev_adjacent *adj; @@ -4885,10 +4884,10 @@ static void __netdev_adjacent_dev_remove(struct net= _device *dev, BUG(); } =20 - if (adj->ref_nr > 1) { - pr_debug("%s to %s ref_nr-- =3D %d\n", dev->name, adj_dev->name, - adj->ref_nr-1); - adj->ref_nr--; + if (adj->ref_nr > ref_nr) { + pr_debug("%s to %s ref_nr-%d =3D %d\n", dev->name, adj_dev->name, + ref_nr, adj->ref_nr-ref_nr); + adj->ref_nr -=3D ref_nr; return; } =20 @@ -4907,21 +4906,22 @@ static void __netdev_adjacent_dev_remove(struct net= _device *dev, =20 static int __netdev_adjacent_dev_link_lists(struct net_device *dev, struct net_device *upper_dev, + u16 ref_nr, struct list_head *up_list, struct list_head *down_list, void *private, bool master) { int ret; =20 - ret =3D __netdev_adjacent_dev_insert(dev, upper_dev, up_list, private, - master); + ret =3D __netdev_adjacent_dev_insert(dev, upper_dev, ref_nr, up_list, + private, master); if (ret) return ret; =20 - ret =3D __netdev_adjacent_dev_insert(upper_dev, dev, down_list, private, - false); + ret =3D __netdev_adjacent_dev_insert(upper_dev, dev, ref_nr, down_list, + private, false); if (ret) { - __netdev_adjacent_dev_remove(dev, upper_dev, up_list); + __netdev_adjacent_dev_remove(dev, upper_dev, ref_nr, up_list); return ret; } =20 @@ -4929,9 +4929,10 @@ static int __netdev_adjacent_dev_link_lists(struct n= et_device *dev, } =20 static int __netdev_adjacent_dev_link(struct net_device *dev, - struct net_device *upper_dev) + struct net_device *upper_dev, + u16 ref_nr) { - return __netdev_adjacent_dev_link_lists(dev, upper_dev, + return __netdev_adjacent_dev_link_lists(dev, upper_dev, ref_nr, &dev->all_adj_list.upper, &upper_dev->all_adj_list.lower, NULL, false); @@ -4939,17 +4940,19 @@ static int __netdev_adjacent_dev_link(struct net_de= vice *dev, =20 static void __netdev_adjacent_dev_unlink_lists(struct net_device *dev, struct net_device *upper_dev, + u16 ref_nr, struct list_head *up_list, struct list_head *down_list) { - __netdev_adjacent_dev_remove(dev, upper_dev, up_list); - __netdev_adjacent_dev_remove(upper_dev, dev, down_list); + __netdev_adjacent_dev_remove(dev, upper_dev, ref_nr, up_list); + __netdev_adjacent_dev_remove(upper_dev, dev, ref_nr, down_list); } =20 static void __netdev_adjacent_dev_unlink(struct net_device *dev, - struct net_device *upper_dev) + struct net_device *upper_dev, + u16 ref_nr) { - __netdev_adjacent_dev_unlink_lists(dev, upper_dev, + __netdev_adjacent_dev_unlink_lists(dev, upper_dev, ref_nr, &dev->all_adj_list.upper, &upper_dev->all_adj_list.lower); } @@ -4958,17 +4961,17 @@ static int __netdev_adjacent_dev_link_neighbour(str= uct net_device *dev, struct net_device *upper_dev, void *private, bool master) { - int ret =3D __netdev_adjacent_dev_link(dev, upper_dev); + int ret =3D __netdev_adjacent_dev_link(dev, upper_dev, 1); =20 if (ret) return ret; =20 - ret =3D __netdev_adjacent_dev_link_lists(dev, upper_dev, + ret =3D __netdev_adjacent_dev_link_lists(dev, upper_dev, 1, &dev->adj_list.upper, &upper_dev->adj_list.lower, private, master); if (ret) { - __netdev_adjacent_dev_unlink(dev, upper_dev); + __netdev_adjacent_dev_unlink(dev, upper_dev, 1); return ret; } =20 @@ -4978,8 +4981,8 @@ static int __netdev_adjacent_dev_link_neighbour(struc= t net_device *dev, static void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev, struct net_device *upper_dev) { - __netdev_adjacent_dev_unlink(dev, upper_dev); - __netdev_adjacent_dev_unlink_lists(dev, upper_dev, + __netdev_adjacent_dev_unlink(dev, upper_dev, 1); + __netdev_adjacent_dev_unlink_lists(dev, upper_dev, 1, &dev->adj_list.upper, &upper_dev->adj_list.lower); } @@ -5020,7 +5023,7 @@ static int __netdev_upper_dev_link(struct net_device = *dev, list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) { pr_debug("Interlinking %s with %s, non-neighbour\n", i->dev->name, j->dev->name); - ret =3D __netdev_adjacent_dev_link(i->dev, j->dev); + ret =3D __netdev_adjacent_dev_link(i->dev, j->dev, i->ref_nr); if (ret) goto rollback_mesh; } @@ -5030,7 +5033,7 @@ static int __netdev_upper_dev_link(struct net_device = *dev, list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) { pr_debug("linking %s's upper device %s with %s\n", upper_dev->name, i->dev->name, dev->name); - ret =3D __netdev_adjacent_dev_link(dev, i->dev); + ret =3D __netdev_adjacent_dev_link(dev, i->dev, i->ref_nr); if (ret) goto rollback_upper_mesh; } @@ -5039,7 +5042,7 @@ static int __netdev_upper_dev_link(struct net_device = *dev, list_for_each_entry(i, &dev->all_adj_list.lower, list) { pr_debug("linking %s's lower device %s with %s\n", dev->name, i->dev->name, upper_dev->name); - ret =3D __netdev_adjacent_dev_link(i->dev, upper_dev); + ret =3D __netdev_adjacent_dev_link(i->dev, upper_dev, i->ref_nr); if (ret) goto rollback_lower_mesh; } @@ -5052,7 +5055,7 @@ rollback_lower_mesh: list_for_each_entry(i, &dev->all_adj_list.lower, list) { if (i =3D=3D to_i) break; - __netdev_adjacent_dev_unlink(i->dev, upper_dev); + __netdev_adjacent_dev_unlink(i->dev, upper_dev, i->ref_nr); } =20 i =3D NULL; @@ -5062,7 +5065,7 @@ rollback_upper_mesh: list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) { if (i =3D=3D to_i) break; - __netdev_adjacent_dev_unlink(dev, i->dev); + __netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr); } =20 i =3D j =3D NULL; @@ -5074,7 +5077,7 @@ rollback_mesh: list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) { if (i =3D=3D to_i && j =3D=3D to_j) break; - __netdev_adjacent_dev_unlink(i->dev, j->dev); + __netdev_adjacent_dev_unlink(i->dev, j->dev, i->ref_nr); } if (i =3D=3D to_i) break; @@ -5150,16 +5153,16 @@ void netdev_upper_dev_unlink(struct net_device *dev, */ list_for_each_entry(i, &dev->all_adj_list.lower, list) list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) - __netdev_adjacent_dev_unlink(i->dev, j->dev); + __netdev_adjacent_dev_unlink(i->dev, j->dev, i->ref_nr); =20 /* remove also the devices itself from lower/upper device * list */ list_for_each_entry(i, &dev->all_adj_list.lower, list) - __netdev_adjacent_dev_unlink(i->dev, upper_dev); + __netdev_adjacent_dev_unlink(i->dev, upper_dev, i->ref_nr); =20 list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) - __netdev_adjacent_dev_unlink(dev, i->dev); + __netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr); =20 call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev); } diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index e70301eb7a4a..add0544a571a 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -80,6 +80,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); @@ -87,21 +88,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 9cb00d1ea140..af856f01cc8f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1560,6 +1560,7 @@ struct sock *sk_clone_lock(const struct sock *sk, con= st gfp_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 @@ -1678,6 +1679,12 @@ 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); + void sock_edemux(struct sk_buff *skb) { struct sock *sk =3D skb->sk; @@ -2119,12 +2126,13 @@ 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) { - sk_memory_allocated_sub(sk, - sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT); - sk->sk_forward_alloc &=3D SK_MEM_QUANTUM - 1; + amount >>=3D SK_MEM_QUANTUM_SHIFT; + sk_memory_allocated_sub(sk, amount); + sk->sk_forward_alloc -=3D amount << SK_MEM_QUANTUM_SHIFT; =20 if (sk_under_memory_pressure(sk) && (sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0))) diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index b371341d899d..7d9b21a7dbb6 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -213,7 +213,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; @@ -223,11 +223,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, @@ -741,6 +743,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; @@ -762,18 +765,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 9f2dc1d15e43..b42151be8afa 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, @@ -1023,6 +1024,7 @@ static const struct inet_connection_sock_af_ops dccp_= ipv6_mapped =3D { .getsockopt =3D ipv6_getsockopt, .addr2sockaddr =3D inet6_csk_addr2sockaddr, .sockaddr_len =3D sizeof(struct sockaddr_in6), + .bind_conflict =3D inet6_csk_bind_conflict, #ifdef CONFIG_COMPAT .compat_setsockopt =3D compat_ipv6_setsockopt, .compat_getsockopt =3D compat_ipv6_getsockopt, diff --git a/net/dccp/proto.c b/net/dccp/proto.c index de2c1e719305..f8fa2d15115e 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 daccc4a36d80..4047341f6c07 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1042,10 +1042,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 @@ -1118,6 +1121,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); @@ -1159,6 +1164,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 69e77c8ff285..25be314d0e17 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -1645,6 +1645,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 727447c17954..8f1ee4bb4c51 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -164,7 +164,7 @@ static int unsolicited_report_interval(struct in_device= *in_dev) } =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); @@ -221,9 +221,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 prandom_u32() % 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 @@ -1104,10 +1109,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; @@ -1123,16 +1132,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 =3D pmc->tomb; psf; psf =3D psf_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; @@ -1330,7 +1350,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32= addr) ip_mc_hash_add(in_dev, 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) @@ -1421,8 +1441,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 */ @@ -1443,7 +1467,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); @@ -1474,8 +1497,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 /* @@ -1490,13 +1517,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 65a28620006c..643ec0bb80a5 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -883,8 +883,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/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpf= ilter.c index 60f27b1e46f6..d0b38aa58ca7 100644 --- a/net/ipv4/netfilter/ipt_rpfilter.c +++ b/net/ipv4/netfilter/ipt_rpfilter.c @@ -64,10 +64,10 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4, return dev_match || flags & XT_RPFILTER_LOOSE; } =20 -static bool rpfilter_is_local(const struct sk_buff *skb) +static bool +rpfilter_is_loopback(const struct sk_buff *skb, const struct net_device *i= n) { - const struct rtable *rt =3D skb_rtable(skb); - return rt && (rt->rt_flags & RTCF_LOCAL); + return skb->pkt_type =3D=3D PACKET_LOOPBACK || in->flags & IFF_LOOPBACK; } =20 static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param = *par) @@ -80,7 +80,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct= xt_action_param *par) info =3D par->matchinfo; invert =3D info->flags & XT_RPFILTER_INVERT; =20 - if (rpfilter_is_local(skb)) + if (rpfilter_is_loopback(skb, par->in)) return true ^ invert; =20 iph =3D ip_hdr(skb); diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 181d5de8ba52..571dabfe9ef3 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -646,6 +646,8 @@ static int ping_v4_push_pending_frames(struct sock *sk,= struct 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 7cd37b04f3a6..77bf6bde38cc 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1968,6 +1968,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 fnhe =3D NULL; diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index 2b986576e5ad..0b23c4ec653f 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -112,7 +112,7 @@ static bool tcp_fastopen_cookie_gen(struct request_sock= *req, struct tcp_fastopen_cookie tmp; =20 if (__tcp_fastopen_cookie_gen(&ip6h->saddr, &tmp)) { - struct in6_addr *buf =3D (struct in6_addr *) tmp.val; + struct in6_addr *buf =3D &tmp.addr; int i =3D 4; =20 for (i =3D 0; i < 4; i++) @@ -164,6 +164,7 @@ static bool tcp_fastopen_create_child(struct sock *sk, * scaled. So correct it appropriately. */ tp->snd_wnd =3D ntohs(tcp_hdr(skb)->window); + tp->max_window =3D tp->snd_wnd; =20 /* Activate the retrans timer so that SYNACK can be retransmitted. * The request socket is not added to the SYN table of the parent diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 8b5c457b40cd..f8ee2fc404cd 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1821,12 +1821,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. @@ -2249,9 +2251,11 @@ u32 __tcp_select_window(struct sock *sk) int full_space =3D min_t(int, tp->window_clamp, allowed_space); 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 @@ -2437,7 +2441,8 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_b= uff *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 (skb_still_in_host_queue(sk, skb)) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 716475fc884b..59ddab1fce28 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1533,7 +1533,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff= *skb) =20 /* if we're overly short, let UDP handle it */ encap_rcv =3D ACCESS_ONCE(up->encap_rcv); - if (skb->len > sizeof(struct udphdr) && encap_rcv !=3D NULL) { + if (encap_rcv) { int ret; =20 /* Verify checksum before giving to encap */ diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 011a4c710c94..cd12b63faf10 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4837,8 +4837,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); @@ -4847,7 +4846,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 newf) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 42dd7c0c4283..f204efd21f50 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -819,6 +819,9 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb,= struct net_device *dev) return -1; =20 offset =3D ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); + /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ + ipv6h =3D ipv6_hdr(skb); + if (offset > 0) { struct ipv6_tlv_tnl_enc_lim *tel; tel =3D (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index ef590d4e0171..f987e8a1282b 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c @@ -219,6 +219,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff= **head, ops =3D rcu_dereference(inet6_offloads[proto]); if (!ops || !ops->callbacks.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_output.c b/net/ipv6/ip6_output.c index cdd0bc79383a..7046af25d6be 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1031,17 +1031,12 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct soc= k *sk, struct flowi6 *fl6, const struct in6_addr *final_dst) { struct dst_entry *dst =3D sk_dst_check(sk, inet6_sk(sk)->dst_cookie); - int err; =20 dst =3D ip6_sk_dst_check(sk, dst, fl6); + if (!dst) + dst =3D ip6_dst_lookup_flow(sk, fl6, final_dst); =20 - err =3D ip6_dst_lookup_tail(sk, &dst, fl6); - if (err) - return ERR_PTR(err); - if (final_dst) - fl6->daddr =3D *final_dst; - - return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); + return dst; } EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow); =20 diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index e9399e5c1709..2879eb9a6049 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -402,18 +402,19 @@ ip6_tnl_dev_uninit(struct net_device *dev) =20 __u16 ip6_tnl_parse_tlv_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) @@ -424,20 +425,29 @@ __u16 ip6_tnl_parse_tlv_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; @@ -445,7 +455,7 @@ __u16 ip6_tnl_parse_tlv_enc_lim(struct sk_buff *skb, __= u8 *raw) i++; } } - nexthdr =3D hdr->nexthdr; + nexthdr =3D next; off +=3D optlen; } return 0; @@ -958,12 +968,21 @@ 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; =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); @@ -1021,7 +1040,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, consume_skb(skb); skb =3D new_skb; } - if (fl6->flowi6_mark) { + if (!use_cache) { skb_dst_set(skb, dst); ndst =3D NULL; } else { @@ -1118,6 +1137,8 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_devic= e *dev) return -1; =20 offset =3D ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); + /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ + ipv6h =3D ipv6_hdr(skb); if (offset > 0) { struct ipv6_tlv_tnl_enc_lim *tel; tel =3D (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 17049f81c750..6d2f7be65f4f 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -1076,6 +1076,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 ad84e7dec433..23575a0ac6f9 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -93,7 +93,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 bool mld_in_v1_mode(const struct inet6_dev *idev); static int sf_setstate(struct ifmcaddr6 *pmc); @@ -727,9 +727,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); @@ -737,8 +737,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 @@ -783,10 +781,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; @@ -803,14 +802,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) @@ -915,7 +921,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; @@ -938,6 +944,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; @@ -2479,15 +2486,17 @@ void ipv6_mc_down(struct inet6_dev *idev) /* Withdraw multicast list */ =20 read_lock_bh(&idev->lock); - mld_ifc_stop_timer(idev); - mld_gq_stop_timer(idev); - mld_dad_stop_timer(idev); =20 for (i =3D idev->mc_list; i; i=3Di->next) igmp6_group_dropped(i); - read_unlock_bh(&idev->lock); =20 - mld_clear_delrec(idev); + /* Should stop timer after group drop. or we will + * start timer again in mld_ifc_event() + */ + mld_ifc_stop_timer(idev); + mld_gq_stop_timer(idev); + mld_dad_stop_timer(idev); + read_unlock_bh(&idev->lock); } =20 =20 @@ -2500,8 +2509,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 @@ -2540,6 +2551,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 @@ -2554,11 +2566,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/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_r= pfilter.c index 790e0c6b19e1..a8af693b717d 100644 --- a/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/net/ipv6/netfilter/ip6t_rpfilter.c @@ -72,10 +72,10 @@ static bool rpfilter_lookup_reverse6(const struct sk_bu= ff *skb, return ret; } =20 -static bool rpfilter_is_local(const struct sk_buff *skb) +static bool +rpfilter_is_loopback(const struct sk_buff *skb, const struct net_device *i= n) { - const struct rt6_info *rt =3D (const void *) skb_dst(skb); - return rt && (rt->rt6i_flags & RTF_LOCAL); + return skb->pkt_type =3D=3D PACKET_LOOPBACK || in->flags & IFF_LOOPBACK; } =20 static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param = *par) @@ -85,7 +85,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct= xt_action_param *par) struct ipv6hdr *iph; bool invert =3D info->flags & XT_RPFILTER_INVERT; =20 - if (rpfilter_is_local(skb)) + if (rpfilter_is_loopback(skb, par->in)) return true ^ invert; =20 iph =3D ipv6_hdr(skb); diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 1463757e8682..edff1d1c74cb 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -588,8 +588,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/ipv6/sit.c b/net/ipv6/sit.c index b5bdd2aeb2f8..96b442ea904a 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -559,13 +559,13 @@ static int ipip6_err(struct sk_buff *skb, u32 info) =20 if (type =3D=3D ICMP_DEST_UNREACH && code =3D=3D ICMP_FRAG_NEEDED) { ipv4_update_pmtu(skb, dev_net(skb->dev), info, - t->parms.link, 0, IPPROTO_IPV6, 0); + t->parms.link, 0, iph->protocol, 0); err =3D 0; goto out; } if (type =3D=3D ICMP_REDIRECT) { ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0, - IPPROTO_IPV6, 0); + iph->protocol, 0); err =3D 0; goto out; } @@ -1368,6 +1368,7 @@ static int ipip6_tunnel_init(struct net_device *dev) tunnel->dst_cache =3D alloc_percpu(struct ip_tunnel_dst); if (!tunnel->dst_cache) { free_percpu(dev->tstats); + dev->tstats =3D NULL; return -ENOMEM; } =20 diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 8eb38558e157..067011cff207 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -631,7 +631,7 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff= *skb) =20 /* if we're overly short, let UDP handle it */ encap_rcv =3D ACCESS_ONCE(up->encap_rcv); - if (skb->len > sizeof(struct udphdr) && encap_rcv !=3D NULL) { + if (encap_rcv) { int ret; =20 /* Verify checksum before giving to encap */ diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c index 7152624ed5f1..26ccd65cdcab 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 68aa9ffd4ae4..e9ec7d2cc357 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -273,6 +273,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct = sk_buff *skb, int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops *ops); 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 5d53249a2e84..5fc8b6899b90 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -11,6 +11,7 @@ =20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt =20 +#include #include #include #include @@ -555,6 +556,30 @@ out: return err ? err : 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, @@ -563,7 +588,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/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index a6e69677a6a1..0531450657d2 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c @@ -716,7 +716,7 @@ static struct proto l2tp_ip6_prot =3D { .bind =3D l2tp_ip6_bind, .connect =3D l2tp_ip6_connect, .disconnect =3D l2tp_ip6_disconnect, - .ioctl =3D udp_ioctl, + .ioctl =3D l2tp_ioctl, .destroy =3D l2tp_ip6_destroy_sock, .setsockopt =3D ipv6_setsockopt, .getsockopt =3D ipv6_getsockopt, diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 42dc2e45c921..9c68d0bca046 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 06033f6c845f..cdc1b620cbe1 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -290,7 +290,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 27b5b3b43744..58f5f34a7af1 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -352,7 +352,7 @@ int mesh_add_vendor_ies(struct ieee80211_sub_if_data *s= data, /* 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/mac80211/mlme.c b/net/mac80211/mlme.c index ff3dac855100..58fab5951b22 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2458,7 +2458,7 @@ static void ieee80211_get_rates(struct ieee80211_supp= orted_band *sband, } =20 static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sda= ta, - bool assoc) + bool assoc, bool abandon) { struct ieee80211_mgd_assoc_data *assoc_data =3D sdata->u.mgd.assoc_data; =20 @@ -2473,6 +2473,9 @@ static void ieee80211_destroy_assoc_data(struct ieee8= 0211_sub_if_data *sdata, mutex_lock(&sdata->local->mtx); ieee80211_vif_release_channel(sdata); mutex_unlock(&sdata->local->mtx); + + if (abandon) + cfg80211_abandon_assoc(sdata->dev, assoc_data->bss); } =20 kfree(assoc_data); @@ -2779,11 +2782,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct iee= e80211_sub_if_data *sdata, if (status_code !=3D WLAN_STATUS_SUCCESS) { sdata_info(sdata, "%pM denied association (code=3D%d)\n", mgmt->sa, status_code); - ieee80211_destroy_assoc_data(sdata, false); + ieee80211_destroy_assoc_data(sdata, false, false); } else { if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) { /* oops -- internal error -- send timeout for now */ - ieee80211_destroy_assoc_data(sdata, false); + ieee80211_destroy_assoc_data(sdata, false, false); cfg80211_assoc_timeout(sdata->dev, bss); return; } @@ -2794,7 +2797,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee8= 0211_sub_if_data *sdata, * recalc after assoc_data is NULL but before associated * is set can cause the interface to go idle */ - ieee80211_destroy_assoc_data(sdata, true); + ieee80211_destroy_assoc_data(sdata, true, false); } =20 cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len); @@ -3491,7 +3494,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data = *sdata) ieee80211_do_assoc(sdata)) { struct cfg80211_bss *bss =3D ifmgd->assoc_data->bss; =20 - ieee80211_destroy_assoc_data(sdata, false); + ieee80211_destroy_assoc_data(sdata, false, false); cfg80211_assoc_timeout(sdata->dev, bss); } } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) @@ -3640,7 +3643,7 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_da= ta *sdata) WLAN_REASON_DEAUTH_LEAVING, false, frame_buf); if (ifmgd->assoc_data) - ieee80211_destroy_assoc_data(sdata, false); + ieee80211_destroy_assoc_data(sdata, false, true); if (ifmgd->auth_data) ieee80211_destroy_auth_data(sdata, false); cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, @@ -4553,7 +4556,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data = *sdata) sdata_lock(sdata); if (ifmgd->assoc_data) { struct cfg80211_bss *bss =3D ifmgd->assoc_data->bss; - ieee80211_destroy_assoc_data(sdata, false); + ieee80211_destroy_assoc_data(sdata, false, false); cfg80211_assoc_timeout(sdata->dev, bss); } if (ifmgd->auth_data) diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index 85296d4eac0e..4e6245f09ee4 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c @@ -13,7 +13,6 @@ /* Internal logging interface, which relies on the real LOG target modules */ =20 -#define NF_LOG_PREFIXLEN 128 #define NFLOGGER_NAME_LEN 64 =20 static struct list_head nf_loggers_l[NFPROTO_NUMPROTO] __read_mostly; diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c index 10cfb156cdf4..8c24270e08e1 100644 --- a/net/netfilter/nft_log.c +++ b/net/netfilter/nft_log.c @@ -38,7 +38,8 @@ static void nft_log_eval(const struct nft_expr *expr, =20 static const struct nla_policy nft_log_policy[NFTA_LOG_MAX + 1] =3D { [NFTA_LOG_GROUP] =3D { .type =3D NLA_U16 }, - [NFTA_LOG_PREFIX] =3D { .type =3D NLA_STRING }, + [NFTA_LOG_PREFIX] =3D { .type =3D NLA_STRING, + .len =3D NF_LOG_PREFIXLEN - 1 }, [NFTA_LOG_SNAPLEN] =3D { .type =3D NLA_U32 }, [NFTA_LOG_QTHRESHOLD] =3D { .type =3D NLA_U16 }, }; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 062624c1be7e..193eac992814 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1402,6 +1402,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 @@ -1418,6 +1420,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 @@ -1451,13 +1455,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 && @@ -1487,7 +1494,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; @@ -1508,24 +1514,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 - f =3D po->fanout; - if (!f) - return; - mutex_lock(&fanout_mutex); - po->fanout =3D NULL; + f =3D po->fanout; + if (f) { + po->fanout =3D NULL; =20 - 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 bool packet_extra_vlan_len_allowed(const struct net_device *dev, @@ -2604,6 +2615,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 @@ -2643,9 +2655,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 27662e19c3bd..8f357a6eb150 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -103,6 +103,17 @@ static void tcf_pedit_cleanup(struct tc_action *a, int= bind) kfree(keys); } =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) { @@ -129,6 +140,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) @@ -141,10 +157,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 3b2617aa6bcd..7e4e15075c81 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -132,13 +132,15 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct= nlmsghdr *n) unsigned long cl; unsigned long fh; int err; - int tp_created =3D 0; + int tp_created; =20 if ((n->nlmsg_type !=3D RTM_GETTFILTER) && !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) return -EPERM; =20 replay: + tp_created =3D 0; + err =3D nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL); if (err < 0) return err; diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 9b8c0b0e60d7..386b2971df1b 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 5b766242af94..5d8180269dc9 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -255,6 +255,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; @@ -277,6 +278,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); @@ -392,6 +394,7 @@ static void dsmark_reset(struct Qdisc *sch) =20 pr_debug("%s(sch %p,[qdisc %p])\n", __func__, 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 718b015da5c3..b169a8a05a5d 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -600,6 +600,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; } @@ -889,6 +890,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; } @@ -955,6 +957,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); @@ -984,12 +987,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->hlevel, 0, sizeof(q->hlevel)); memset(q->row_mask, 0, sizeof(q->row_mask)); for (i =3D 0; i < TC_HTB_NUMPRIO; i++) diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 73f1db8e8039..aa9e07816feb 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -408,6 +408,25 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct= Qdisc *sch) sch->q.qlen++; } =20 +/* netem can't properly corrupt a megapacket (like we get from GSO), so in= stead + * when we statistically choose to corrupt one, we instead segment it, ret= urning + * the first packet to be corrupted, and re-enqueue the remaining frames + */ +static struct sk_buff *netem_segment(struct sk_buff *skb, struct Qdisc *sc= h) +{ + struct sk_buff *segs; + netdev_features_t features =3D netif_skb_features(skb); + + segs =3D skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); + + if (IS_ERR_OR_NULL(segs)) { + qdisc_reshape_fail(skb, sch); + return NULL; + } + consume_skb(skb); + return segs; +} + /* * Insert one skb into qdisc. * Note: parent depends on return value to account for queue length. @@ -420,7 +439,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Q= disc *sch) /* We don't fill cb now as skb_unshare() may invalidate it */ struct netem_skb_cb *cb; struct sk_buff *skb2; + struct sk_buff *segs =3D NULL; + unsigned int len =3D 0, last_len, prev_len =3D qdisc_pkt_len(skb); + int nb =3D 0; int count =3D 1; + int rc =3D NET_XMIT_SUCCESS; =20 /* Random duplication */ if (q->duplicate && q->duplicate >=3D get_crandom(&q->dup_cor)) @@ -466,10 +489,23 @@ static int netem_enqueue(struct sk_buff *skb, struct = Qdisc *sch) * do it now in software before we mangle it. */ if (q->corrupt && q->corrupt >=3D get_crandom(&q->corrupt_cor)) { + if (skb_is_gso(skb)) { + segs =3D netem_segment(skb, sch); + if (!segs) + return NET_XMIT_DROP; + } else { + segs =3D skb; + } + + skb =3D segs; + segs =3D segs->next; + if (!(skb =3D skb_unshare(skb, GFP_ATOMIC)) || (skb->ip_summed =3D=3D CHECKSUM_PARTIAL && - skb_checksum_help(skb))) - return qdisc_drop(skb, sch); + skb_checksum_help(skb))) { + rc =3D qdisc_drop(skb, sch); + goto finish_segs; + } =20 skb->data[prandom_u32() % skb_headlen(skb)] ^=3D 1<<(prandom_u32() % 8); @@ -529,6 +565,27 @@ static int netem_enqueue(struct sk_buff *skb, struct Q= disc *sch) sch->qstats.requeues++; } =20 +finish_segs: + if (segs) { + while (segs) { + skb2 =3D segs->next; + segs->next =3D NULL; + qdisc_skb_cb(segs)->pkt_len =3D segs->len; + last_len =3D segs->len; + rc =3D qdisc_enqueue(segs, sch); + if (rc !=3D NET_XMIT_SUCCESS) { + if (net_xmit_drop_count(rc)) + sch->qstats.drops++; + } else { + nb++; + len +=3D last_len; + } + segs =3D skb2; + } + sch->q.qlen +=3D nb; + if (nb > 1) + qdisc_tree_reduce_backlog(sch, 1 - nb, prev_len - len); + } return NET_XMIT_SUCCESS; } =20 diff --git a/net/sctp/socket.c b/net/sctp/socket.c index adfb4b58831f..ad0292262581 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1217,9 +1217,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; @@ -4280,7 +4283,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); @@ -4328,6 +4331,12 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id= , struct socket **sockp) if (!asoc) return -EINVAL; =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. */ @@ -5801,6 +5810,9 @@ static int sctp_getsockopt(struct sock *sk, int level= , int optname, if (get_user(len, optlen)) return -EFAULT; =20 + if (len < 0) + return -EINVAL; + lock_sock(sk); =20 switch (optname) { @@ -6754,7 +6766,6 @@ static int sctp_wait_for_sndbuf(struct sctp_associati= on *asoc, long *timeo_p, */ release_sock(sk); current_timeo =3D schedule_timeout(current_timeo); - BUG_ON(sk !=3D asoc->base.sk); lock_sock(sk); =20 *timeo_p =3D current_timeo; diff --git a/net/socket.c b/net/socket.c index 8da2e2ea4151..ccfaebcdba66 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1998,7 +1998,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 int 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; @@ -2097,6 +2097,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) @@ -2122,7 +2124,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: @@ -2149,6 +2151,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; @@ -2167,7 +2170,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); @@ -2175,7 +2179,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); @@ -2185,6 +2190,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); @@ -2349,8 +2356,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/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rp= c_xdr.c index eeeba5adee6d..2410d557ae39 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c @@ -260,7 +260,7 @@ static int gssx_dec_option_array(struct xdr_stream *xdr, if (!oa->data) return -ENOMEM; =20 - creds =3D kmalloc(sizeof(struct svc_cred), GFP_KERNEL); + creds =3D kzalloc(sizeof(struct svc_cred), GFP_KERNEL); if (!creds) { kfree(oa->data); return -ENOMEM; diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcaut= h_gss.c index efac1201c55d..8bc077f3e91f 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -1479,7 +1479,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/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 70273ab30e85..710d4191e9d5 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -336,6 +336,11 @@ out: =20 static DEFINE_IDA(rpc_clids); =20 +void rpc_cleanup_clids(void) +{ + ida_destroy(&rpc_clids); +} + static int rpc_alloc_clid(struct rpc_clnt *clnt) { int clid; diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index cd30120de9e4..aefb4488880f 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c @@ -117,6 +117,7 @@ out: static void __exit cleanup_sunrpc(void) { + rpc_cleanup_clids(); rpcauth_remove_module(); cleanup_socket_xprt(); svc_cleanup_xprt_sock(); diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 85d232bed87d..e8d3313ea2c9 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1796,27 +1796,8 @@ vsock_stream_recvmsg(struct kiocb *kiocb, else if (sk->sk_shutdown & RCV_SHUTDOWN) err =3D 0; =20 - if (copied > 0) { - /* We only do these additional bookkeeping/notification steps - * if we actually copied something out of the queue pair - * instead of just peeking ahead. - */ - - if (!(flags & MSG_PEEK)) { - /* If the other side has shutdown for sending and there - * is nothing more to read, then modify the socket - * state. - */ - if (vsk->peer_shutdown & SEND_SHUTDOWN) { - if (vsock_stream_has_data(vsk) <=3D 0) { - sk->sk_state =3D SS_UNCONNECTED; - sock_set_flag(sk, SOCK_DONE); - sk->sk_state_change(sk); - } - } - } + if (copied > 0) err =3D copied; - } =20 out_wait: finish_wait(sk_sleep(sk), &wait); diff --git a/net/wireless/core.h b/net/wireless/core.h index c4d4b0c4f0e6..805aaab05ffc 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -369,6 +369,7 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev); void cfg80211_sme_deauth(struct wireless_dev *wdev); void cfg80211_sme_auth_timeout(struct wireless_dev *wdev); void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev); +void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev); =20 /* internal helpers */ bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 266766b8d80b..66dd9bfe5a96 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -148,6 +148,18 @@ void cfg80211_assoc_timeout(struct net_device *dev, st= ruct cfg80211_bss *bss) } EXPORT_SYMBOL(cfg80211_assoc_timeout); =20 +void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *b= ss) +{ + struct wireless_dev *wdev =3D dev->ieee80211_ptr; + struct wiphy *wiphy =3D wdev->wiphy; + + cfg80211_sme_abandon_assoc(wdev); + + cfg80211_unhold_bss(bss_from_pub(bss)); + cfg80211_put_bss(wiphy, bss); +} +EXPORT_SYMBOL(cfg80211_abandon_assoc); + void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t l= en) { struct wireless_dev *wdev =3D dev->ieee80211_ptr; diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 8bbeeb302216..c74505c1a320 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -39,6 +39,7 @@ struct cfg80211_conn { CFG80211_CONN_ASSOCIATING, CFG80211_CONN_ASSOC_FAILED, CFG80211_CONN_DEAUTH, + CFG80211_CONN_ABANDON, CFG80211_CONN_CONNECTED, } state; u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; @@ -195,6 +196,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *w= dev) cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, NULL, 0, WLAN_REASON_DEAUTH_LEAVING, false); + /* fall through */ + case CFG80211_CONN_ABANDON: /* free directly, disconnected event already sent */ cfg80211_sme_free(wdev); return 0; @@ -418,6 +421,17 @@ void cfg80211_sme_assoc_timeout(struct wireless_dev *w= dev) schedule_work(&rdev->conn_work); } =20 +void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev) +{ + struct cfg80211_registered_device *rdev =3D wiphy_to_rdev(wdev->wiphy); + + if (!wdev->conn) + return; + + wdev->conn->state =3D CFG80211_CONN_ABANDON; + schedule_work(&rdev->conn_work); +} + static int cfg80211_sme_connect(struct wireless_dev *wdev, struct cfg80211_connect_params *connect, const u8 *prev_bssid) diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c index 8275f0e55106..4b2f44c20caf 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 (getmaxy(stdscr)-(prompt_lines+4))/2; - x =3D (getmaxx(stdscr)-(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 04ef9b5351f9..15331bb173f2 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -419,7 +419,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; @@ -432,14 +431,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) { - pr_warn("ALSA: snd_seq_pool_done timeout: %d cells remain\n", atomic_re= ad(&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 77ec21420355..f676ae53c477 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -181,6 +181,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 */ @@ -192,11 +194,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 @@ -502,19 +504,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++; @@ -529,6 +521,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/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 9b54e936aae7..ced54249c171 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -2843,6 +2843,8 @@ enum { CXT_FIXUP_HP_530, CXT_FIXUP_CAP_MIX_AMP_5047, CXT_FIXUP_MUTE_LED_EAPD, + CXT_FIXUP_HP_SPECTRE, + CXT_FIXUP_HP_GATE_MIC, }; =20 /* for hda_fixup_thinkpad_acpi() */ @@ -3216,6 +3218,17 @@ static void cxt_fixup_cap_mix_amp_5047(struct hda_co= dec *codec, (1 << AC_AMPCAP_MUTE_SHIFT)); } =20 +static void cxt_fixup_hp_gate_mic_jack(struct hda_codec *codec, + const struct hda_fixup *fix, + int action) +{ + /* the mic pin (0x19) doesn't give an unsolicited event; + * probe the mic pin together with the headphone pin (0x16) + */ + if (action =3D=3D HDA_FIXUP_ACT_PROBE) + snd_hda_jack_set_gating_jack(codec, 0x19, 0x16); +} + /* ThinkPad X200 & co with cxt5051 */ static const struct hda_pintbl cxt_pincfg_lenovo_x200[] =3D { { 0x16, 0x042140ff }, /* HP (seq# overridden) */ @@ -3349,6 +3362,18 @@ static const struct hda_fixup cxt_fixups[] =3D { .type =3D HDA_FIXUP_FUNC, .v.func =3D cxt_fixup_mute_led_eapd, }, + [CXT_FIXUP_HP_SPECTRE] =3D { + .type =3D HDA_FIXUP_PINS, + .v.pins =3D (const struct hda_pintbl[]) { + /* enable NID 0x1d for the speaker on top */ + { 0x1d, 0x91170111 }, + { } + } + }, + [CXT_FIXUP_HP_GATE_MIC] =3D { + .type =3D HDA_FIXUP_FUNC, + .v.func =3D cxt_fixup_hp_gate_mic_jack, + }, }; =20 static const struct snd_pci_quirk cxt5045_fixups[] =3D { @@ -3397,6 +3422,9 @@ static const struct hda_model_fixup cxt5051_fixup_mod= els[] =3D { static const struct snd_pci_quirk cxt5066_fixups[] =3D { SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMI= C), SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC= ), + SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC), + SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), + SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index c4f149ca1a72..06b990727f68 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -3345,6 +3345,7 @@ static const struct hda_codec_preset snd_hda_preset_h= dmi[] =3D { { .id =3D 0x10de0071, .name =3D "GPU 71 HDMI/DP", .patch =3D patch_nvhdmi = }, { .id =3D 0x10de0072, .name =3D "GPU 72 HDMI/DP", .patch =3D patch_nvhdmi = }, { .id =3D 0x10de007d, .name =3D "GPU 7d HDMI/DP", .patch =3D patch_nvhdmi = }, +{ .id =3D 0x10de0080, .name =3D "GPU 80 HDMI/DP", .patch =3D patch_nvhdmi = }, { .id =3D 0x10de0082, .name =3D "GPU 82 HDMI/DP", .patch =3D patch_nvhdmi = }, { .id =3D 0x10de0083, .name =3D "GPU 83 HDMI/DP", .patch =3D patch_nvhdmi = }, { .id =3D 0x10de8001, .name =3D "MCP73 HDMI", .patch =3D patch_nvhdmi_2ch = }, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b76f4ff117a2..1b8fa72a6302 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2282,6 +2282,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = =3D { SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), + SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3), SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PR= IMARY_HP), @@ -6126,6 +6127,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = =3D { SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51), SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51), + SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8), SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP= ), SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), diff --git a/sound/usb/card.c b/sound/usb/card.c index 34f934095ddd..8887f4e19956 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -204,7 +204,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/hiface/pcm.c b/sound/usb/hiface/pcm.c index 2c44139b4041..33db205dd12b 100644 --- a/sound/usb/hiface/pcm.c +++ b/sound/usb/hiface/pcm.c @@ -445,6 +445,8 @@ static int hiface_pcm_prepare(struct snd_pcm_substream = *alsa_sub) =20 mutex_lock(&rt->stream_mutex); =20 + hiface_pcm_stream_stop(rt); + sub->dma_off =3D 0; sub->period_off =3D 0; =20 diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 21c60eff920e..5d249caf3349 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -916,9 +916,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")) { usb_audio_info(chip, diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index f954c26de231..0dbb69a404fe 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1646,7 +1646,7 @@ static int trace__sys_enter(struct trace *trace, stru= ct perf_evsel *evsel, =20 if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) { if (!trace->duration_filter && !trace->summary_only) { - trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output= ); + trace__fprintf_entry_head(trace, thread, 1, ttrace->entry_time, trace->= output); fprintf(trace->output, "%-70s\n", ttrace->entry_str); } } else @@ -1701,7 +1701,7 @@ static int trace__sys_exit(struct trace *trace, struc= t perf_evsel *evsel, if (trace->summary_only) goto out; =20 - trace__fprintf_entry_head(trace, thread, duration, sample->time, trace->o= utput); + trace__fprintf_entry_head(trace, thread, duration, ttrace->entry_time, tr= ace->output); =20 if (ttrace->entry_pending) { fprintf(trace->output, "%-70s", ttrace->entry_str); diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trac= e-event-scripting.c index 57aaccc1692e..6a1fe83386ea 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -90,7 +90,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 @@ -153,7 +154,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 diff --git a/tools/testing/selftests/net/run_netsocktests b/tools/testing/s= elftests/net/run_netsocktests index c09a682df56a..16058bbea7a8 100644 --- a/tools/testing/selftests/net/run_netsocktests +++ b/tools/testing/selftests/net/run_netsocktests @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh =20 echo "--------------------" echo "running socket test" diff --git a/tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c = b/tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c index a503fa70c950..9be22e932cc4 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/pmc56_overflow_test.c @@ -64,7 +64,7 @@ int pmc56_overflow(void) =20 FAIL_IF(ebb_event_enable(&event)); =20 - mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); + mtspr(SPRN_PMC2, pmc_sample_period(sample_period)); mtspr(SPRN_PMC5, 0); mtspr(SPRN_PMC6, 0); =20 --KRJ4yArSHF8vY7I3-- --Er97KPJOrxRt+yKZ Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUBWMq+T+e/yOyVhhEJAQp1Jw/+KogyKMUFv63NRzM/j5ARqINZDL53GOsI aPffa7R9DZyzH/HClwcUiBTxEt0FQkPFqormF0b0B/NtRCkyeYH4Fj5FlUKnnDzj 8fKwA4vCl0UwOvW4FqXTVc+KXyG2w2tdjSqgc7QY4UHB/oi1Li6INUhAKntainkX 5NjAm8u2GT6FcpYRz/U5WDoRuE9MB53upJTOaljjINJi0NKsxNKeB23ASI1mDmSu acCEt2lSmVnTv8MwUxzFpsLl5vHxMPyaAJuB6ncbu0vHQG0/ET5Srn/H4ZiSezYe kcBE2VgZfLSgriOiMEsGJ++pAucAtziQ6xaR2J8K7vRIO15Rukee6RoY70YXjXRI 4TeLucNnl6bvD+dZWD5l5FadL461sXZYvA9W5Fjea4wXXzLkFbR/39SpCIiy7XiJ hes3LVxXLO0LupV8+d2EY05dH24W6Vmr46zjRlTzxWsknPsqylJt84gJnurwPD7C ncJZlGYJEA5cIH+yM+r8LeFBpbef8htZ5JcgASEIwJOKRdhXV005Ig0seVDxg/LE E/rd4VDxiAHEYoCZ8VRK8jv9eCi5lJ3z1CPw2dH3UzSl0Uo81qWXnG8pDIzUfw8G wikMiKe6reGK7MEKjqgwUeF5Eb8gvBNnh94L/O/WeQaz3p986DhL+MU6XXMtJNYW su+cuGyKC1E= =/p9k -----END PGP SIGNATURE----- --Er97KPJOrxRt+yKZ--