Linux 3.16.50
From: Ben Hutchings
Date: Mon Nov 13 2017 - 08:08:15 EST
I'm announcing the release of the 3.16.50 kernel.
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.git linux-3.16.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git
The diff from 3.16.49 is attached to this message.
Ben.
------------
Documentation/video4linux/v4l2-pci-skeleton.c | 2 +-
Makefile | 3 +-
arch/alpha/include/asm/types.h | 1 -
arch/alpha/include/uapi/asm/types.h | 12 +-
arch/arm/include/asm/kexec.h | 5 +
arch/arm/kernel/iwmmxt.S | 13 +
arch/arm/kernel/machine_kexec.c | 11 +-
arch/arm/kernel/pj4-cp0.c | 4 +
arch/arm/kernel/return_address.c | 4 -
arch/arm/mach-cns3xxx/Makefile | 1 +
arch/arm/mach-omap2/Kconfig | 3 -
arch/arm/mach-pxa/Kconfig | 1 +
arch/arm/mm/cache-l2x0.c | 111 ++---
arch/arm/plat-omap/Kconfig | 3 +
arch/arm64/kernel/fpsimd.c | 2 +
arch/arm64/mm/fault.c | 5 +-
arch/mips/boot/elf2ecoff.c | 10 +-
arch/mips/dec/int-handler.S | 18 +-
arch/mips/include/asm/page.h | 3 +-
arch/mips/jz4740/board-qi_lb60.c | 1 +
arch/mips/jz4740/gpio.c | 1 +
arch/mips/jz4740/irq.h | 2 +
arch/mips/kernel/bmips_vec.S | 3 -
arch/mips/pci/ops-pmcmsp.c | 12 -
arch/mips/pci/ops-tx4927.c | 2 -
arch/mips/sgi-ip22/Platform | 2 +-
arch/powerpc/boot/Makefile | 16 +-
arch/powerpc/kvm/book3s_hv.c | 2 +
arch/powerpc/mm/subpage-prot.c | 2 +-
arch/powerpc/platforms/pseries/reconfig.c | 1 -
arch/x86/boot/compressed/misc.h | 11 +-
arch/x86/crypto/sha1_avx2_x86_64_asm.S | 67 +--
arch/x86/crypto/sha1_ssse3_glue.c | 2 +-
arch/x86/kernel/acpi/boot.c | 8 +
arch/x86/kernel/cpu/perf_event.c | 7 +-
arch/x86/kernel/entry_64.S | 2 +
arch/x86/kernel/kprobes/core.c | 10 +-
arch/x86/kernel/kvm.c | 6 +-
arch/x86/xen/mmu.c | 2 +-
arch/xtensa/kernel/xtensa_ksyms.c | 2 -
arch/xtensa/mm/cache.c | 12 +-
block/bio.c | 8 +
drivers/ata/libata-scsi.c | 6 +-
drivers/ata/pata_hpt366.c | 4 +-
drivers/block/drbd/drbd_bitmap.c | 6 +
drivers/block/paride/pg.c | 4 +-
drivers/clk/clk-efm32gg.c | 6 +-
drivers/dma/amba-pl08x.c | 4 +-
drivers/gpio/gpio-tegra.c | 6 +-
drivers/gpu/drm/drm_gem.c | 6 +-
drivers/gpu/drm/i915/i915_debugfs.c | 5 +-
drivers/gpu/drm/msm/msm_gem_submit.c | 7 +-
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 +-
drivers/hid/usbhid/hid-core.c | 12 +-
drivers/i2c/busses/i2c-ismt.c | 5 +
drivers/i2c/muxes/Kconfig | 2 +-
drivers/iio/adc/exynos_adc.c | 2 +-
drivers/iio/adc/vf610_adc.c | 2 +-
drivers/iio/imu/adis16480.c | 2 +-
drivers/iio/light/tsl2563.c | 2 +-
drivers/infiniband/core/cma.c | 2 +
drivers/infiniband/core/uverbs_cmd.c | 5 +-
drivers/infiniband/core/uverbs_main.c | 3 +-
drivers/infiniband/hw/cxgb3/iwch_provider.c | 5 +-
drivers/infiniband/hw/cxgb4/cq.c | 1 +
drivers/infiniband/hw/mlx5/mem.c | 2 +-
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 4 +-
drivers/infiniband/ulp/ipoib/ipoib_cm.c | 1 -
drivers/infiniband/ulp/ipoib/ipoib_main.c | 3 +-
drivers/input/joystick/analog.c | 2 +-
drivers/input/mouse/trackpoint.c | 3 +-
drivers/input/mouse/trackpoint.h | 3 +-
drivers/input/serio/gscps2.c | 2 +-
drivers/iommu/amd_iommu_init.c | 2 +-
drivers/irqchip/irq-brcmstb-l2.c | 1 +
drivers/isdn/hardware/mISDN/mISDNipac.c | 12 +-
drivers/isdn/hardware/mISDN/w6692.c | 6 +-
drivers/md/dm-bufio.c | 1 +
drivers/md/dm.c | 10 -
drivers/md/raid5.c | 6 +-
drivers/media/platform/davinci/vpfe_capture.c | 22 +-
drivers/media/rc/ir-lirc-codec.c | 2 +-
drivers/message/i2o/i2o_config.c | 4 +-
drivers/mfd/arizona-core.c | 4 +-
drivers/mfd/arizona-i2c.c | 5 +-
drivers/mfd/arizona-spi.c | 3 +-
drivers/mfd/arizona.h | 4 +-
drivers/mtd/maps/pmcmsp-flash.c | 4 +-
drivers/mtd/maps/rbtx4939-flash.c | 2 -
drivers/mtd/nand/nandsim.c | 1 +
drivers/net/Kconfig | 3 +
drivers/net/ethernet/amd/amd8111e.c | 19 +-
drivers/net/ethernet/amd/nmclan_cs.c | 4 +-
drivers/net/ethernet/broadcom/b44.c | 1 +
drivers/net/ethernet/broadcom/bcmsysport.c | 4 +-
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 456 ++++++++++-----------
drivers/net/ethernet/broadcom/genet/bcmgenet.h | 9 +
drivers/net/ethernet/dec/tulip/tulip_core.c | 9 +-
drivers/net/ethernet/dec/tulip/uli526x.c | 2 +-
drivers/net/ethernet/dec/tulip/winbond-840.c | 2 +-
drivers/net/ethernet/emulex/benet/be_main.c | 1 -
drivers/net/ethernet/intel/e1000e/ich8lan.c | 13 +-
drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 30 +-
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 4 +
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 15 +-
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 10 +-
drivers/net/ethernet/mellanox/mlx4/en_tx.c | 6 +-
drivers/net/ethernet/mellanox/mlx4/fw.c | 4 +
drivers/net/ethernet/mellanox/mlx4/fw.h | 1 +
drivers/net/ethernet/mellanox/mlx4/main.c | 2 +
drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 19 +-
drivers/net/ethernet/mellanox/mlx5/core/debugfs.c | 6 +-
drivers/net/ethernet/neterion/vxge/vxge-main.c | 31 +-
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 2 +-
drivers/net/ethernet/qlogic/qlge/qlge_dbg.c | 2 +-
drivers/net/ethernet/realtek/r8169.c | 5 +-
drivers/net/ethernet/ti/cpmac.c | 7 +-
drivers/net/ethernet/xilinx/ll_temac_main.c | 2 +-
drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c | 2 +-
drivers/net/ethernet/xilinx/xilinx_emaclite.c | 2 +-
drivers/net/hyperv/netvsc_drv.c | 9 +-
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 2 +-
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 18 +-
drivers/net/wireless/hostap/hostap_hw.c | 15 +-
drivers/net/wireless/iwlegacy/3945.c | 3 +-
drivers/net/wireless/iwlwifi/dvm/tx.c | 2 +-
drivers/net/wireless/iwlwifi/mvm/sta.c | 3 +-
drivers/net/wireless/ti/wl1251/main.c | 1 +
drivers/of/device.c | 2 +
drivers/parisc/dino.c | 2 +-
drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 1 +
drivers/platform/x86/samsung-laptop.c | 2 +-
drivers/power/reset/xgene-reboot.c | 2 +-
drivers/s390/net/qeth_l3_main.c | 4 +-
drivers/scsi/advansys.c | 3 +-
drivers/scsi/aic94xx/aic94xx_sds.c | 5 +-
drivers/scsi/be2iscsi/be_main.c | 3 +-
drivers/scsi/bfa/bfa_ioc.c | 22 +-
drivers/scsi/ips.c | 9 +-
drivers/scsi/mvsas/mv_sas.c | 4 +-
drivers/scsi/scsi_tgt_if.c | 2 +-
drivers/scsi/st.c | 4 +-
drivers/spi/spi-atmel.c | 4 +-
drivers/spi/spi-pl022.c | 2 +-
drivers/spi/spi-rspi.c | 1 -
drivers/spmi/spmi.c | 12 +
drivers/staging/bcm/Kconfig | 1 +
drivers/staging/dgnc/dgnc_tty.c | 16 +-
drivers/staging/iio/adc/ad7192.c | 2 +-
drivers/staging/iio/resolver/ad2s1210.c | 2 +-
drivers/staging/imx-drm/imx-hdmi.c | 2 +-
drivers/staging/lustre/lustre/llite/llite_lib.c | 3 +-
drivers/staging/rtl8188eu/os_dep/usb_intf.c | 2 +
drivers/staging/rtl8192ee/pci.c | 4 +-
drivers/staging/rtl8723au/core/rtw_wlan_util.c | 2 +-
drivers/staging/vt6655/device_main.c | 10 +-
drivers/staging/wlan-ng/prism2fw.c | 33 +-
drivers/target/iscsi/iscsi_target.c | 1 +
drivers/target/iscsi/iscsi_target_core.h | 1 +
drivers/target/iscsi/iscsi_target_login.c | 7 +-
drivers/tty/isicom.c | 2 +-
drivers/tty/nozomi.c | 2 +-
drivers/usb/class/cdc-acm.c | 3 +
drivers/usb/core/config.c | 20 +-
drivers/usb/core/hcd.c | 2 +
drivers/usb/core/hub.c | 10 +-
drivers/usb/core/quirks.c | 4 +
drivers/usb/host/pci-quirks.c | 71 +++-
drivers/usb/host/pci-quirks.h | 2 +
drivers/usb/host/xhci-hub.c | 3 +
drivers/usb/host/xhci-pci.c | 6 +
drivers/usb/host/xhci-ring.c | 11 +-
drivers/usb/host/xhci.c | 10 +-
drivers/usb/host/xhci.h | 1 +
drivers/usb/misc/usbtest.c | 5 +-
drivers/usb/renesas_usbhs/common.c | 4 +-
drivers/usb/renesas_usbhs/mod_gadget.c | 42 +-
drivers/usb/renesas_usbhs/pipe.c | 10 +
drivers/usb/renesas_usbhs/pipe.h | 1 +
drivers/usb/serial/cp210x.c | 1 +
drivers/usb/serial/option.c | 2 +
drivers/usb/storage/isd200.c | 5 +-
drivers/usb/storage/uas-detect.h | 15 +-
drivers/usb/storage/uas.c | 10 +-
drivers/usb/storage/unusual_uas.h | 4 +-
drivers/video/fbdev/Kconfig | 3 +-
fs/cifs/dir.c | 19 +-
fs/cifs/smb2pdu.c | 4 +-
fs/cifs/smb2pdu.h | 4 +-
fs/eventpoll.c | 36 +-
fs/ext4/file.c | 3 +
fs/ext4/resize.c | 3 +-
fs/fuse/file.c | 2 +-
fs/gfs2/dir.c | 11 +-
fs/nfs/client.c | 1 +
fs/nfsd/nfs4xdr.c | 6 +-
fs/nilfs2/btree.c | 2 +-
fs/nilfs2/recovery.c | 4 +-
fs/nilfs2/super.c | 5 +-
fs/ocfs2/acl.c | 27 +-
fs/xfs/xfs_ialloc.c | 2 +-
include/asm-generic/topology.h | 6 +-
include/linux/cpumask.h | 6 +-
include/linux/device-mapper.h | 70 ++--
include/linux/fs.h | 4 +-
include/linux/ftrace_event.h | 2 +-
include/linux/gpio/driver.h | 2 +-
include/linux/mlx4/device.h | 1 +
include/linux/mm_types.h | 31 +-
include/linux/module.h | 2 +-
include/linux/mtd/map.h | 12 +-
include/linux/perf_event.h | 28 +-
include/linux/workqueue.h | 4 +-
include/net/dst.h | 13 +-
include/net/ip6_fib.h | 35 +-
include/net/ip6_route.h | 2 +-
include/net/ip_fib.h | 10 +-
include/net/sch_generic.h | 5 +-
include/net/sctp/sctp.h | 4 +
include/rdma/ib_addr.h | 6 +-
include/trace/ftrace.h | 7 +-
include/uapi/linux/usb/ch9.h | 1 +
kernel/audit_watch.c | 12 +-
kernel/events/core.c | 135 +++---
kernel/fork.c | 2 +-
kernel/sched/core.c | 2 +-
kernel/trace/trace.c | 1 +
kernel/trace/trace_event_perf.c | 4 +-
kernel/trace/trace_events_filter.c | 4 +
kernel/trace/trace_kprobe.c | 4 +-
kernel/trace/trace_syscalls.c | 4 +-
kernel/trace/trace_uprobe.c | 2 +-
kernel/workqueue.c | 23 +-
lib/assoc_array.c | 51 +--
lib/cpumask.c | 74 ++--
mm/hugetlb.c | 12 +-
mm/mempolicy.c | 5 -
mm/mprotect.c | 4 +-
mm/page_alloc.c | 37 +-
net/batman-adv/translation-table.c | 57 ++-
net/batman-adv/types.h | 2 +
net/bridge/br_device.c | 3 +-
net/bridge/br_input.c | 3 +-
net/bridge/br_netfilter.c | 2 +-
net/caif/cfpkt_skbuff.c | 2 +-
net/ceph/messenger.c | 6 +-
net/core/dev.c | 23 +-
net/core/dst.c | 45 +-
net/core/pktgen.c | 2 +-
net/ipv4/fib_frontend.c | 9 +-
net/ipv4/fib_semantics.c | 27 +-
net/ipv4/netfilter/ipt_CLUSTERIP.c | 4 +-
net/ipv4/netfilter/nft_reject_ipv4.c | 2 +
net/ipv4/route.c | 10 +-
net/ipv4/udp_offload.c | 2 +-
net/ipv6/addrconf.c | 2 +-
net/ipv6/ip6_fib.c | 37 +-
net/ipv6/ip6_tunnel.c | 2 +-
net/ipv6/netfilter/nft_reject_ipv6.c | 2 +
net/ipv6/output_core.c | 6 +-
net/ipv6/route.c | 26 +-
net/ipv6/tcp_ipv6.c | 3 +-
net/ipv6/udp_offload.c | 2 +-
net/ipv6/xfrm6_policy.c | 6 +-
net/key/af_key.c | 48 ++-
net/l2tp/l2tp_core.c | 79 ++--
net/l2tp/l2tp_core.h | 18 +-
net/l2tp/l2tp_netlink.c | 72 ++--
net/mac80211/key.c | 20 +-
net/netfilter/ipvs/ip_vs_xmit.c | 2 +-
net/netfilter/nft_compat.c | 6 +-
net/netfilter/nft_ct.c | 8 +
net/netfilter/nft_reject.c | 2 +
net/packet/af_packet.c | 30 +-
net/sched/sch_api.c | 2 +
net/sched/sch_cbq.c | 10 +-
net/sched/sch_fq_codel.c | 4 +-
net/sched/sch_hfsc.c | 4 +-
net/sched/sch_hhf.c | 11 +-
net/sched/sch_htb.c | 5 +-
net/sched/sch_mq.c | 10 +-
net/sched/sch_mqprio.c | 19 +-
net/sched/sch_multiq.c | 9 +-
net/sched/sch_netem.c | 4 +-
net/sched/sch_sfq.c | 8 +-
net/sched/sch_tbf.c | 5 +-
net/sctp/ipv6.c | 2 +-
net/xfrm/xfrm_user.c | 2 +
scripts/mod/modpost.c | 34 +-
security/keys/key.c | 10 +
security/keys/keyctl.c | 5 +
sound/core/control.c | 2 +-
sound/core/seq/seq_clientmgr.c | 6 +-
sound/core/seq/seq_lock.c | 4 -
sound/core/seq/seq_lock.h | 12 -
sound/core/seq/seq_ports.c | 7 +-
sound/pci/hda/patch_conexant.c | 1 +
sound/pci/hda/patch_realtek.c | 1 +
sound/soc/codecs/adau1977.c | 2 +-
sound/soc/fsl/fsl_sai.c | 3 +-
sound/soc/fsl/fsl_ssi.c | 4 +-
sound/soc/fsl/imx-audmux.c | 8 +-
sound/soc/soc-pcm.c | 4 +
sound/usb/card.c | 20 +
sound/usb/mixer.c | 14 +-
sound/usb/mixer.h | 3 +
sound/usb/mixer_quirks.c | 6 +
tools/perf/ui/browser.c | 2 +-
309 files changed, 1999 insertions(+), 1318 deletions(-)
A Raghavendra Rao (1):
Staging: wlan-ng: fix sparse warning in prism2fw.c
Aaron Ma (1):
Input: trackpoint - add new trackpoint firmware ID
Akinobu Mita (1):
iio: light: tsl2563: use correct event code
Alan Stern (4):
USB: Check for dropped connection before switching to full speed
USB: uas: fix bug in handling of alternate settings
usb: usbtest: fix NULL pointer dereference
USB: core: fix out-of-bounds access bug in usb_get_bos_descriptor()
Alan Swanson (1):
uas: Add US_FL_IGNORE_RESIDUE for Initio Corporation INIC-3069
Alban Bedel (1):
MIPS: Fix the build on jz4740 after removing the custom gpio.h
Alex Vesker (1):
IB/ipoib: Prevent setting negative values to max_nonsrq_conn_qp
Alexander Potapenko (1):
sctp: don't dereference ptr before leaving _sctp_walk_{params, errors}()
Andrew Morton (1):
MODULE_DEVICE_TABLE: fix some callsites
Andrey Ryabinin (1):
module: fix types of device tables aliases
Andy Lutomirski (1):
x86/asm/64: Clear AC on NMI entries
Andy Shevchenko (1):
platform/x86: samsung-laptop: Initialize loca variable
Aneesh Kumar K.V (1):
powerpc/mm/hash: Free the subpage_prot_table correctly
Anil Gurumurthy (1):
bfa: Fix indentation
Ard Biesheuvel (2):
ARM: 8221/1: PJ4: allow building in Thumb-2 mode
ARM: 8452/3: PJ4: make coprocessor access sequences buildable in Thumb2 mode
Arend Van Spriel (1):
brcmfmac: add length check in brcmf_cfg80211_escan_handler()
Arnd Bergmann (35):
staging:iio:resolver:ad2s1210 fix negative IIO_ANGL_VEL read
ARM: pxa: select both FB and FB_W100 for eseries
qlge: avoid memcpy buffer overflow
gfs2: remove IS_ERR_VALUE abuse
iio: adc: fix building on 64-bit
infiniband: mlx5: avoid a compile-time warning
ata: hpt366: fix constant cast warning
tty: nozomi: avoid a harmless gcc warning
tty/isicom: fix big-endian compile warning
i2o: hide unsafe ioctl on 64-bit
dm bufio: hide bogus warning
scsi-tgt: fix type conversion warning
scsi: advansys: remove #warning message
mtd: pmcmsp: use kstrndup instead of kmalloc+strncpy
mlx5: avoid build warnings on 32-bit
mISDN: avoid arch specific __builtin_return_address call
cpmac: remove hopeless #warning
net: caif: fix misleading indentation
net: am2150: fix nmclan_cs.c shared interrupt handling
net: tulip: turn compile-time warning into dev_warn()
net: vxge: avoid unused function warnings
hostap: avoid uninitialized variable use in hfa384x_get_rid
iwlegacy: avoid warning about missing braces
brcmfmac: avoid gcc-5.1 warning
video: mx3fb: always enable BACKLIGHT_LCD_SUPPORT
staging: bcm: add 32-bit host dependency
staging: imx-drm: fix indentation warning
staging: vt6655: fix overly large stack usage
ARM: cns3xxx: shut up frame size warning
ARM: 8296/1: cache-l2x0: clean up aurora cache handling
MIPS: ip22: Fix ip28 build for modern gcc
staging: r8192ee: prorperly format warning message
mtd: cfi: reduce stack size
MIPS: jz4740: fix build error in irq.h
net/xen-netback: disable on 64KB page granularity
Atsushi Nemoto (2):
mtd: maps: rbtx4939-flash: delete an unused variable in rbtx4939_flash_remove
MIPS: TXx9: Delete an unused variable in tx4927_pcibios_setup
Banajit Goswami (1):
ASoC: do not close shared backend dailink
Bart Van Assche (2):
IB/cma: Fix a race condition in iboe_addr_get_sgid()
dm: fix printk() rate limiting code
Ben Hutchings (4):
dst: Increase alignment of metrics to allow extra flag on pointers
alpha: uapi: Add support for __SANE_USERSPACE_TYPES__
ALSA: seq: Enable 'use' locking in all configurations
Linux 3.16.50
Bjorn Andersson (1):
spmi: Include OF based modalias in device uevent
Bodo Stroesser (1):
scsi: st: fix blk_get_queue usage
Charles Milette (1):
staging: rtl8188eu: add RNX-N150NUB support
Chen Yu (1):
PM/hibernate: touch NMI watchdog when creating snapshot
Chris Gorman (1):
i2c: mux: pinctrl: mention correct module name in Kconfig help text
Chris Wilson (1):
drm: Release driver tracking before making the object available again
Chuck Lever (1):
nfsd: Limit end of page list when decoding NFSv4 WRITE
Chunyu Hu (1):
tracing: Fix kmemleak in instance_rmdir
Colin Ian King (3):
usb: storage: return on error to avoid a null pointer dereference
netxen: fix incorrect loop counter decrement
Staging: iio: adc: fix indent on break statement
Cong Wang (1):
wl1251: add a missing spin_lock_init()
Dan Carpenter (11):
libceph: potential NULL dereference in ceph_msg_data_create()
libata: array underflow in ata_find_dev()
cxgb4: Fix error codes in c4iw_create_cq()
IB/cxgb3: Fix error codes in iwch_alloc_mr()
RDMA/ocrdma: Fix an error code in ocrdma_alloc_pd()
RDMA/ocrdma: Fix error codes in ocrdma_create_srq()
drm/msm: fix an integer overflow test
x86/ldt: Fix off by one in get_segment_base()
paride: fix the "verbose" module param
drm/i915: cleanup some indenting
Staging: lustre: missing curly braces in ll_setattr_raw()
Dave Martin (1):
arm64: fpsimd: Prevent registers leaking across exec
David Howells (2):
assoc_array: Fix a buggy node-splitting case
KEYS: don't let add_key() update an uninstantiated key
David Malcolm (1):
drivers/net/ethernet/dec/tulip/uli526x.c: fix misleading indentation in uli526x_timer
David Miller (1):
netfilter: Fix switch statement warnings with recent gcc.
David S. Miller (1):
netfilter; Add some missing default cases to switch statements in nft_reject.
Doug Berger (2):
net: bcmgenet: Fix unmapping of fragments in bcmgenet_xmit()
net: bcmgenet: Free skb after last Tx frag
Dragos Bogdan (1):
iio: imu: adis16480: Fix acceleration scale factor for adis16480
Emmanuel Grumbach (1):
iwlwifi: dvm: prevent an out of bounds access
Eric Biggers (1):
KEYS: prevent KEYCTL_READ on negative key
Eric Dumazet (6):
net: reduce skb_warn_bad_offload() noise
net: skb_needs_check() accepts CHECKSUM_NONE for tx
af_key: do not use GFP_KERNEL in atomic contexts
ipv4: add reference counting to metrics
ipv4: fix NULL dereference in free_fib_info_rcu()
net_sched: fix error recovery at qdisc creation
Feras Daoud (1):
IB/ipoib: Set IPOIB_NEIGH_TBL_FLUSH after flushed completion initialization
Florian Fainelli (12):
net: bcmgenet: check harder for out of memory conditions
net: bcmgenet: fix off-by-one in incrementing read pointer
net: bcmgenet: update ring producer index and buffer count in xmit
b44: Initialize 64-bit stats seqcount
i40e: Initialize 64-bit statistics TX ring seqcount
ixgbe: Initialize 64-bit stats seqcounts
irqchip: brcmstb-l2: Define an irq_pm_shutdown function
net: systemport: Be drop monitor friendly
net: bcmgenet: Be drop monitor friendly
net: systemport: Free DMA coherent descriptors on errors
r8169: Do not increment tx_dropped in TX ring cleaning
r8169: Be drop monitor friendly
Geert Uytterhoeven (2):
Input: gscps2 - fix MODULE_DEVICE_TABLE invocation
spi: rspi: Remove unused variable in rspi_rz_transfer_one()
Gerald Schaefer (1):
mm/hugetlb: improve locking in dissolve_free_huge_pages()
Greg Kroah-Hartman (1):
USB: fix out-of-bounds in usb_set_configuration
Guillaume Nault (8):
l2tp: initialise session's refcount before making it reachable
l2tp: define parameters of l2tp_session_get*() as "const"
l2tp: hold tunnel while looking up sessions in l2tp_netlink
l2tp: hold tunnel while processing genl delete command
l2tp: hold tunnel while handling genl tunnel updates
l2tp: hold tunnel while handling genl TUNNEL_GET commands
l2tp: remove useless duplicate session detection in l2tp_netlink
l2tp: hold tunnel used while creating sessions with netlink
Hannes Reinecke (1):
aic94xx: Skip reading user settings if flash is not found
Hector Martin (1):
USB: serial: option: add D-Link DWM-222 device ID
Icenowy Zheng (1):
pinctrl: sunxi: add a missing function of A10/A20 pinctrl driver
Inbar Karmy (1):
net/mlx4_en: Fix wrong indication of Wake-on-LAN (WoL) support
Ingo Molnar (1):
x86/boot: Add CONFIG_PARAVIRT_SPINLOCKS quirk to arch/x86/boot/compressed/misc.h
Ismail, Mustafa (2):
RDMA/uverbs: Fix the check for port number
RDMA/core: Initialize port_num in qp_attr
IvÃn Briano (1):
net/packet: Fix Tx queue selection for AF_PACKET
Jaejoong Kim (1):
HID: usbhid: fix out-of-bounds bug
James Bottomley (1):
ips: remove pointless #warning
Jan Kara (3):
ocfs2: don't clear SGID when inheriting ACLs
ext4: fix SEEK_HOLE/SEEK_DATA for blocksize < pagesize
audit: Fix use after free in audit_remove_watch_rule()
Jeff Kirsher (2):
am2150: Update nmclan_cs.c to use update PCMCIA API
e1000e: fix call to do_div() to use u64 arg
Jerry Lee (1):
ext4: fix overflow caused by missing cast in ext4_resize_fs()
Jiahau Chang (1):
xhci: Bad Ethernet performance plugged in ASM1042A host
Jin Yao (1):
perf annotate: Fix broken arrow at row 0 connecting jmp instruction to its target
Jiri Olsa (1):
perf/core: Fix locking for children siblings group read
Joe Perches (2):
dm: convert DM printk macros to pr_<level> macros
i40e: Reduce stack in i40e_dbg_dump_desc
Joerg Roedel (1):
iommu/amd: Fix schedule-while-atomic BUG in initialization code
Johan Hovold (1):
USB: cdc-acm: add device-id for quirky printer
Johannes Berg (1):
mac80211: accept key reinstall without changing anything
Juergen Gross (1):
x86/xen: fix upper bound of pmd loop in xen_cleanhighmap()
Julian Wiedmann (1):
s390/qeth: fix L3 next-hop in xmit qeth hdr
Kai-Heng Feng (1):
usb: quirks: Add no-lpm quirk for Moshi USB to Ethernet Adapter
Kalderon, Michal (1):
IB/cma: Fix reference count leak when no ipv4 addresses are set
Kasin Li (1):
drm/msm: Fix potential buffer overflow issue
Kevin Cernekee (1):
MIPS: BMIPS: Fix ".previous without corresponding .section" warnings
Konrad Zapalowicz (1):
staging: dgnc: Fix frame size is larger than 1024B
Konstantin Khlebnikov (2):
net_sched/sfq: update hierarchical backlog when drop packet
net_sched: fix order of queue length updates in qdisc_replace()
Lars Ellenberg (1):
drbd: avoid redefinition of BITS_PER_PAGE
Laurent Vivier (1):
powerpc/pseries: Fix of_node_put() underflow during reconfig remove
Lee Jones (1):
mfd: arizona: Rid data size incompatibility warn when building for 64bit
Leon Romanovsky (2):
IB/ipoib: Remove double pointer assigning
RDMA/uverbs: Prevent leak of reserved field
Linus LÃssing (1):
batman-adv: fix TT sync flag inconsistencies
Linus Torvalds (2):
Clarify (and fix) MAX_LFS_FILESIZE macros
Disable "frame-address" warning
Linus Walleij (1):
gpio: drop retval check enforcing from gpiochip_remove()
Luis de Bethencourt (2):
mvsas: fix misleading indentation
staging: rtl8723au: core: rtw_wlan_util: fix misleading indentation
Maciej W. Rozycki (1):
MIPS: DEC: Fix an int-handler.S CPU_DADDI_WORKAROUNDS regression
Mahesh Bandewar (1):
ipv4: initialize fib_trie prior to register_netdev_notifier call.
Manuel SchÃlling (1):
xilinx: Fix compiler warning
Mark Brown (7):
power/reset: xgene-reset: Fix prototype of xgene_restart()
Input: joystick - use get_cycles on ARMv8
dma: pl08x: Use correct specifier for size_t values
ASoC: imx-audmux: Use uintptr_t for port numbers
ASoC: adau1977: Fix truncation warning on 64 bit architectures
spi/atmel: Fix pointer to int conversion warnings on 64 bit builds
spi/pl022: Explicitly truncate large bitmask
Mark Rutland (2):
arm64: mm: abort uaccess retries upon fatal signal
perf/core: Fix group {cpu,task} validation
Martin KaFai Lau (1):
ipv6: Add rt6_get_cookie() function
Masami Hiramatsu (1):
kprobes/x86: Release insn_slot in failure path
Mateusz Jurczyk (1):
fuse: initialize the flock flag in fuse_file on allocation
Mathias Krause (2):
xfrm_user: fix info leak in xfrm_notify_sa()
xfrm_user: fix info leak in build_aevent()
Mathias Nyman (2):
xhci: Fix NULL pointer dereference when cleaning up streams for removed host
xhci: fix 20000ms port resume timeout
Max Filippov (3):
xtensa: fix cache aliasing handling code for WT cache
xtensa: don't limit csum_partial export by CONFIG_NET
xtensa: mm/cache: add missing EXPORT_SYMBOLs
Michael Ellerman (1):
powerpc/boot: Fix 64-bit boot wrapper build with non-biarch compiler
Michael Gugino (1):
staging: rtl8188eu: add TL-WN722N v2 support
MichaÅ MirosÅaw (1):
gpio: tegra: fix unbalanced chained_irq_enter/exit
Moshe Shemesh (1):
net/mlx5: Fix command bad flow on command entry allocation failure
Nadav Amit (1):
mm: migrate: prevent racy access to tlb_flush_pending
Naftali Goldstein (1):
iwlwifi: mvm: set the RTS_MIMO_PROT bit in flag mask when sending sta to fw
Nicholas Bellinger (1):
iscsi-target: Fix iscsi_np reset hung task during parallel delete
Nicolin Chen (1):
ASoC: fsl_sai: Set SYNC bit of TCR2 to Asynchronous Mode
Nikolay Aleksandrov (9):
net: bridge: fix dest lookup when vlan proto doesn't match
sch_htb: fix crash on init failure
sch_multiq: fix double free on init failure
sch_hhf: fix null pointer dereference on init failure
sch_hfsc: fix null pointer deref and double free on init failure
sch_cbq: fix null pointer dereferences on init failure
sch_fq_codel: avoid double free on init failure
sch_netem: avoid null pointer deref on init failure
sch_tbf: fix two null pointer dereferences on init failure
Nikolay Borisov (1):
ARM: kexec: Make .text R/W in machine_kexec
Ofer Heifetz (1):
md/raid5: add thread_group worker async_tx_issue_pending_all
Oleg Nesterov (1):
epoll: fix race between ep_poll_callback(POLLFREE) and ep_free()/ep_remove()
Oliver O'Halloran (1):
mm/init: fix zone boundary creation
Omar Sandoval (1):
xfs: fix inobt inode allocation search optimization
Paul Burton (1):
net: ti: cpmac: Fix compiler warning due to type confusion
Paul Gortmaker (2):
modpost: expand pattern matching to support substring matches
modpost: don't emit section mismatch warnings for compiler optimizations
Paul Mackerras (1):
KVM: PPC: Book3S HV: Enable TM before accessing TM registers
Pavel Shilovsky (1):
CIFS: Fix maximum SMB2 header size
Peter Zijlstra (1):
perf/core: Invert perf_read_group() loops
Peter Zijlstra (Intel) (1):
perf: Avoid horrible stack usage
Petri Gynther (4):
net: bcmgenet: simplify __bcmgenet_tx_reclaim()
net: bcmgenet: rewrite bcmgenet_rx_refill()
net: bcmgenet: fix dev->stats.tx_bytes accounting
net: bcmgenet: cleanup for bcmgenet_xmit_frag()
Pontus Andersson (1):
i2c: ismt: Separate I2C block read from SMBus block read
Prabhakar Lad (1):
media: platform: davinci: return -EINVAL for VPFE_CMD_S_CCDC_RAW_PARAMS ioctl
Rafael J. Wysocki (1):
USB: hcd: Mark secondary HCD as dead if the primary one died
Ralf Baechle (3):
MIPS: DEC: Avoid la pseudo-instruction in delay slots
MIPS: elf2ecoff: Fix warning due to dead code.
MIPS: elf2ecoff: Ignore PT_MIPS_ABIFLAGS program headers.
Ronnie Sahlberg (2):
cifs: return ENAMETOOLONG for overlong names in cifs_open()/cifs_lookup()
cifs: check MaxPathNameComponentLength != 0 before using it
Russell King (1):
ARM: kexec: fix failure to boot crash kernel
Rusty Russell (1):
cpumask_set_cpu_local_first => cpumask_local_spread, lament
Ryusuke Konishi (1):
nilfs2: fix gcc uninitialized-variable warnings in powerpc build
Sabrina Dubroca (1):
netfilter: ipt_CLUSTERIP: fix use-after-free of proc entry
Sachin Prabhu (1):
cifs: Fix df output for users with quota limits
Sandeep Singh (1):
usb:xhci:Add quirk for Certain failing HP keyboard on reset after resume
Sean Young (1):
media: lirc: LIRC_GET_REC_RESOLUTION should return microseconds
Sergei A. Trusov (1):
ALSA: hda - Fix speaker output from VAIO VPCL14M1R
Sergey Ryazanov (1):
MIPS: MSP71xx: remove odd locking in PCI config space access code
Seunghun Han (1):
x86/acpi: Prevent out of bound access caused by broken ACPI tables
Shu Wang (1):
xhci: fix memleak in xhci_run()
Sinclair Yeh (1):
drm/vmwgfx: Fix gcc-7.1.1 warning
Stefan Triller (1):
USB: serial: cp210x: add support for Qivicon USB ZigBee dongle
Stefan-Gabriel Mirea (1):
iio: adc: vf610_adc: Fix VALT selection value for REFSEL bits
Stefano Brivio (1):
ipv6: accept 64k - 1 packet length in ip6_find_1stfragopt()
Steffen Klassert (1):
ipv6: Fix may be used uninitialized warning in rt6_check
Stephen Boyd (1):
of: device: Export of_device_{get_modalias, uvent_modalias} to modules
Stephen Douthit (2):
i2c: ismt: Don't duplicate the receive length for block reads
i2c: ismt: Return EMSGSIZE for block reads with bogus length
Steve Dickson (1):
mount: copy the port field into the cloned nfs_server structure.
Steve French (1):
CIFS: remove endian related sparse warning
Steven Rostedt (VMware) (1):
tracing: Fix freeing of filter in create_filter() when set_str is false
Takashi Iwai (6):
ALSA: usb-audio: Add mute TLV for playback volumes on C-Media devices
ALSA: core: Fix unexpected error at replacing user TLV
ALSA: hda - Add stereo mic quirk for Lenovo G50-70 (17aa:3978)
ALSA: seq: Fix use-after-free at creating a port
ALSA: usb-audio: Kill stray URB at exiting
ALSA: usb-audio: Check out-of-bounds access by corrupted buffer descriptor
Tejun Heo (3):
workqueue: restore WQ_UNBOUND/max_active==1 to be ordered
workqueue: implicit ordered attribute should be overridable
cpumask: fix spurious cpumask_of_node() on non-NUMA multi-node configs
Thomas Bogendoerfer (1):
parisc: pci memory bar assignment fails with 64bit kernels on dino/cujo
Tim Gardner (1):
be2iscsi: Fix bogus WARN_ON length check
Timur Tabi (1):
ASoC: fsl-ssi: fix do_div build warning in fsl_ssi_set_bclk()
Tony Lindgren (1):
ARM: OMAP: Fix Kconfig warning for omap1
Uwe Kleine-KÃnig (3):
mtd: nandsim: remove debugfs entries in error path
clk/efm32gg: fix dt init prototype
ARM: 8160/1: drop warning about return_address not using unwind tables
Varka Bhadram (1):
ethernet: amd: fix pci device ids
Vitaly Mayatskikh (1):
fix unbalanced page refcounting in bio_map_user_iov
Wanpeng Li (1):
KVM: async_pf: make rcu irq exit if not triggered from idle task
Wei Wang (3):
ipv6: reset fn->rr_ptr when replacing route
ipv6: add rcu grace period before freeing fib6_node
ipv6: fix sparse warning on rt6i_node
Willem de Bruijn (3):
net: avoid skb_warn_bad_offload false positives on UFO
packet: hold bind lock when rebinding to fanout hook
packet: in packet_do_bind, test fanout with bind_lock held
Xiao Ni (1):
Raid5 should update rdev->sectors after reshape
Xin Long (2):
sctp: fix the check for _sctp_walk_params and _sctp_walk_errors
ipv6: set rt6i_protocol properly in the route when it is installed
Yishai Hadas (1):
IB/uverbs: Fix device cleanup
Yoshihiro Shimoda (4):
usb: renesas_usbhs: gadget: fix re-enabling pipe without re-connecting
usb: renesas_usbhs: gadget: Fix NULL pointer dereference in usbhsg_ep_dequeue()
usb: renesas_usbhs: fix usbhsc_resume() for !USBHSF_RUNTIME_PWCTRL
usb: renesas_usbhs: gadget: disable all eps when the driver stops
Zubair Lutfullah Kakakhel (1):
MIPS: Fix a warning for virt_to_page
franÃois romieu (1):
net: remove open-coded skb_cow_head.
megha.dey@xxxxxxxxxxxxxxx (1):
crypto: x86/sha1 - Fix reads beyond the number of blocks passed
stephen hemminger (1):
netvsc: fix deadlock betwen link status and removal
zhong jiang (1):
mm/mempolicy: fix use after free when calling get_mempolicy
diff --git a/Documentation/video4linux/v4l2-pci-skeleton.c b/Documentation/video4linux/v4l2-pci-skeleton.c
index 46904fe49609..8c3d3d625c6c 100644
--- a/Documentation/video4linux/v4l2-pci-skeleton.c
+++ b/Documentation/video4linux/v4l2-pci-skeleton.c
@@ -42,7 +42,6 @@
MODULE_DESCRIPTION("V4L2 PCI Skeleton Driver");
MODULE_AUTHOR("Hans Verkuil");
MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(pci, skeleton_pci_tbl);
/**
* struct skeleton - All internal data for one instance of device
@@ -95,6 +94,7 @@ static const struct pci_device_id skeleton_pci_tbl[] = {
/* { PCI_DEVICE(PCI_VENDOR_ID_, PCI_DEVICE_ID_) }, */
{ 0, }
};
+MODULE_DEVICE_TABLE(pci, skeleton_pci_tbl);
/*
* HDTV: this structure has the capabilities of the HDTV receiver.
diff --git a/Makefile b/Makefile
index f15a93eded21..11af06e140e2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 3
PATCHLEVEL = 16
-SUBLEVEL = 49
+SUBLEVEL = 50
EXTRAVERSION =
NAME = Museum of Fishiegoodies
@@ -616,6 +616,7 @@ all: vmlinux
include $(srctree)/arch/$(SRCARCH)/Makefile
KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)
+KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,)
diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h
index f61e1a56c378..0bc66e1d3a7e 100644
--- a/arch/alpha/include/asm/types.h
+++ b/arch/alpha/include/asm/types.h
@@ -1,7 +1,6 @@
#ifndef _ALPHA_TYPES_H
#define _ALPHA_TYPES_H
-#include <asm-generic/int-ll64.h>
#include <uapi/asm/types.h>
#endif /* _ALPHA_TYPES_H */
diff --git a/arch/alpha/include/uapi/asm/types.h b/arch/alpha/include/uapi/asm/types.h
index 9fd3cd459777..8d1024d7be05 100644
--- a/arch/alpha/include/uapi/asm/types.h
+++ b/arch/alpha/include/uapi/asm/types.h
@@ -9,8 +9,18 @@
* need to be careful to avoid a name clashes.
*/
-#ifndef __KERNEL__
+/*
+ * This is here because we used to use l64 for alpha
+ * and we don't want to impact user mode with our change to ll64
+ * in the kernel.
+ *
+ * However, some user programs are fine with this. They can
+ * flag __SANE_USERSPACE_TYPES__ to get int-ll64.h here.
+ */
+#if !defined(__SANE_USERSPACE_TYPES__) && !defined(__KERNEL__)
#include <asm-generic/int-l64.h>
+#else
+#include <asm-generic/int-ll64.h>
#endif
#endif /* _UAPI_ALPHA_TYPES_H */
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
index c2b9b4bdec00..a664941a5593 100644
--- a/arch/arm/include/asm/kexec.h
+++ b/arch/arm/include/asm/kexec.h
@@ -19,6 +19,11 @@
#ifndef __ASSEMBLY__
+#define ARCH_HAS_KIMAGE_ARCH
+struct kimage_arch {
+ u32 kernel_r2;
+};
+
/**
* crash_setup_regs() - save registers for the panic kernel
* @newregs: registers are saved here
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index 2b32978ae905..d65bb940d797 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -58,6 +58,7 @@
#define MMX_SIZE (0x98)
.text
+ .arm
/*
* Lazy switching of Concan coprocessor context
@@ -182,6 +183,8 @@ ENTRY(iwmmxt_task_enable)
tmcr wCon, r2
mov pc, lr
+ENDPROC(iwmmxt_task_enable)
+
/*
* Back up Concan regs to save area and disable access to them
* (mainly for gdb or sleep mode usage)
@@ -232,6 +235,8 @@ ENTRY(iwmmxt_task_disable)
1: msr cpsr_c, ip @ restore interrupt mode
ldmfd sp!, {r4, pc}
+ENDPROC(iwmmxt_task_disable)
+
/*
* Copy Concan state to given memory address
*
@@ -268,6 +273,8 @@ ENTRY(iwmmxt_task_copy)
msr cpsr_c, ip @ restore interrupt mode
mov pc, r3
+ENDPROC(iwmmxt_task_copy)
+
/*
* Restore Concan state from given memory address
*
@@ -304,6 +311,8 @@ ENTRY(iwmmxt_task_restore)
msr cpsr_c, ip @ restore interrupt mode
mov pc, r3
+ENDPROC(iwmmxt_task_restore)
+
/*
* Concan handling on task switch
*
@@ -335,6 +344,8 @@ ENTRY(iwmmxt_task_switch)
mrc p15, 0, r1, c2, c0, 0
sub pc, lr, r1, lsr #32 @ cpwait and return
+ENDPROC(iwmmxt_task_switch)
+
/*
* Remove Concan ownership of given task
*
@@ -353,6 +364,8 @@ ENTRY(iwmmxt_task_release)
msr cpsr_c, r2 @ restore interrupts
mov pc, lr
+ENDPROC(iwmmxt_task_release)
+
.data
concan_owner:
.word 0
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 8cf0996aa1a8..3c7cda46edeb 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -40,6 +40,9 @@ int machine_kexec_prepare(struct kimage *image)
__be32 header;
int i, err;
+ image->arch.kernel_r2 = image->start - KEXEC_ARM_ZIMAGE_OFFSET
+ + KEXEC_ARM_ATAGS_OFFSET;
+
/*
* Validate that if the current HW supports SMP, then the SW supports
* and implements CPU hotplug for the current HW. If not, we won't be
@@ -63,8 +66,8 @@ int machine_kexec_prepare(struct kimage *image)
if (err)
return err;
- if (be32_to_cpu(header) == OF_DT_HEADER)
- kexec_boot_atags = current_segment->mem;
+ if (header == cpu_to_be32(OF_DT_HEADER))
+ image->arch.kernel_r2 = current_segment->mem;
}
return 0;
}
@@ -166,9 +169,7 @@ void machine_kexec(struct kimage *image)
kexec_start_address = image->start;
kexec_indirection_page = page_list;
kexec_mach_type = machine_arch_type;
- if (!kexec_boot_atags)
- kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
-
+ kexec_boot_atags = image->arch.kernel_r2;
/* copy our kernel relocation code to the control code page */
reboot_entry = fncpy(reboot_code_buffer,
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
index 8153e36b2491..7c9248b74d3f 100644
--- a/arch/arm/kernel/pj4-cp0.c
+++ b/arch/arm/kernel/pj4-cp0.c
@@ -66,9 +66,13 @@ static void __init pj4_cp_access_write(u32 value)
__asm__ __volatile__ (
"mcr p15, 0, %1, c1, c0, 2\n\t"
+#ifdef CONFIG_THUMB2_KERNEL
+ "isb\n\t"
+#else
"mrc p15, 0, %0, c1, c0, 2\n\t"
"mov %0, %0\n\t"
"sub pc, pc, #4\n\t"
+#endif
: "=r" (temp) : "r" (value));
}
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index fafedd86885d..827d946d2be4 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -59,10 +59,6 @@ void *return_address(unsigned int level)
#else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
-#if defined(CONFIG_ARM_UNWIND)
-#warning "TODO: return_address should use unwind tables"
-#endif
-
void *return_address(unsigned int level)
{
return NULL;
diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile
index a1ff10848698..fd610561616e 100644
--- a/arch/arm/mach-cns3xxx/Makefile
+++ b/arch/arm/mach-cns3xxx/Makefile
@@ -2,4 +2,5 @@ obj-$(CONFIG_ARCH_CNS3XXX) += cns3xxx.o
cns3xxx-y += core.o pm.o
cns3xxx-$(CONFIG_ATAGS) += devices.o
cns3xxx-$(CONFIG_PCI) += pcie.o
+CFLAGS_pcie.o += -Wframe-larger-than=1536 # override default 1024, this is safe here
cns3xxx-$(CONFIG_MACH_CNS3420VB) += cns3420vb.o
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 1c1ed737f7ab..3ac9cb2b2eb2 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -1,9 +1,6 @@
menu "TI OMAP/AM/DM/DRA Family"
depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
-config ARCH_OMAP
- bool
-
config ARCH_OMAP2
bool "TI OMAP2"
depends on ARCH_MULTI_V6
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index e6690a44917d..170bc3ff5da3 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -546,6 +546,7 @@ config MACH_ICONTROL
config ARCH_PXA_ESERIES
bool "PXA based Toshiba e-series PDAs"
select FB_W100
+ select FB
select PXA25x
config MACH_E330
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 7c3fb41a462e..011490e7204d 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -135,73 +135,6 @@ static void l2c_disable(void)
dsb(st);
}
-#ifdef CONFIG_CACHE_PL310
-static inline void cache_wait(void __iomem *reg, unsigned long mask)
-{
- /* cache operations by line are atomic on PL310 */
-}
-#else
-#define cache_wait l2c_wait_mask
-#endif
-
-static inline void cache_sync(void)
-{
- void __iomem *base = l2x0_base;
-
- writel_relaxed(0, base + sync_reg_offset);
- cache_wait(base + L2X0_CACHE_SYNC, 1);
-}
-
-#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
-static inline void debug_writel(unsigned long val)
-{
- l2c_set_debug(l2x0_base, val);
-}
-#else
-/* Optimised out for non-errata case */
-static inline void debug_writel(unsigned long val)
-{
-}
-#endif
-
-static void l2x0_cache_sync(void)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2x0_lock, flags);
- cache_sync();
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
-static void __l2x0_flush_all(void)
-{
- debug_writel(0x03);
- __l2c_op_way(l2x0_base + L2X0_CLEAN_INV_WAY);
- cache_sync();
- debug_writel(0x00);
-}
-
-static void l2x0_flush_all(void)
-{
- unsigned long flags;
-
- /* clean all ways */
- raw_spin_lock_irqsave(&l2x0_lock, flags);
- __l2x0_flush_all();
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
-static void l2x0_disable(void)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2x0_lock, flags);
- __l2x0_flush_all();
- l2c_write_sec(0, l2x0_base, L2X0_CTRL);
- dsb(st);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
static void l2c_save(void __iomem *base)
{
l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
@@ -1126,14 +1059,15 @@ static unsigned long calc_range_end(unsigned long start, unsigned long end)
static void aurora_pa_range(unsigned long start, unsigned long end,
unsigned long offset)
{
+ void __iomem *base = l2x0_base;
unsigned long flags;
raw_spin_lock_irqsave(&l2x0_lock, flags);
- writel_relaxed(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG);
- writel_relaxed(end, l2x0_base + offset);
+ writel_relaxed(start, base + AURORA_RANGE_BASE_ADDR_REG);
+ writel_relaxed(end, base + offset);
raw_spin_unlock_irqrestore(&l2x0_lock, flags);
- cache_sync();
+ writel_relaxed(0, base + AURORA_SYNC_REG);
}
static void aurora_inv_range(unsigned long start, unsigned long end)
@@ -1193,6 +1127,37 @@ static void aurora_flush_range(unsigned long start, unsigned long end)
}
}
+static void aurora_flush_all(void)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ /* clean all ways */
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+
+ writel_relaxed(0, base + AURORA_SYNC_REG);
+}
+
+static void aurora_cache_sync(void)
+{
+ writel_relaxed(0, l2x0_base + AURORA_SYNC_REG);
+}
+
+static void aurora_disable(void)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+ writel_relaxed(0, base + AURORA_SYNC_REG);
+ l2c_write_sec(0, base, L2X0_CTRL);
+ dsb(st);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
static void aurora_save(void __iomem *base)
{
l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
@@ -1267,9 +1232,9 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
.inv_range = aurora_inv_range,
.clean_range = aurora_clean_range,
.flush_range = aurora_flush_range,
- .flush_all = l2x0_flush_all,
- .disable = l2x0_disable,
- .sync = l2x0_cache_sync,
+ .flush_all = aurora_flush_all,
+ .disable = aurora_disable,
+ .sync = aurora_cache_sync,
.resume = aurora_resume,
},
};
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 02fc10d2d63b..d055db32ffcb 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -1,3 +1,6 @@
+config ARCH_OMAP
+ bool
+
if ARCH_OMAP
menu "TI OMAP Common Features"
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a43a40b6a846..5fc3c469654b 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -156,9 +156,11 @@ void fpsimd_thread_switch(struct task_struct *next)
void fpsimd_flush_thread(void)
{
+ preempt_disable();
memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
fpsimd_flush_task_state(current);
set_thread_flag(TIF_FOREIGN_FPSTATE);
+ preempt_enable();
}
/*
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 4e4a10df87c1..8fd2315bdf4d 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -252,8 +252,11 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
* signal first. We do not need to release the mmap_sem because it
* would already be released in __lock_page_or_retry in mm/filemap.c.
*/
- if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
+ if (!user_mode(regs))
+ goto no_context;
return 0;
+ }
/*
* Major/minor page fault accounting is only done on the initial
diff --git a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c
index 8585078ae50e..6950fee4576c 100644
--- a/arch/mips/boot/elf2ecoff.c
+++ b/arch/mips/boot/elf2ecoff.c
@@ -49,7 +49,8 @@
/*
* Some extra ELF definitions
*/
-#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
+#define PT_MIPS_ABIFLAGS 0x70000003 /* Records ABI related flags */
/* -------------------------------------------------------------------- */
@@ -267,7 +268,6 @@ int main(int argc, char *argv[])
Elf32_Ehdr ex;
Elf32_Phdr *ph;
Elf32_Shdr *sh;
- char *shstrtab;
int i, pad;
struct sect text, data, bss;
struct filehdr efh;
@@ -335,9 +335,6 @@ int main(int argc, char *argv[])
"sh");
if (must_convert_endian)
convert_elf_shdrs(sh, ex.e_shnum);
- /* Read in the section string table. */
- shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
- sh[ex.e_shstrndx].sh_size, "shstrtab");
/* Figure out if we can cram the program header into an ECOFF
header... Basically, we can't handle anything but loadable
@@ -351,7 +348,8 @@ int main(int argc, char *argv[])
/* Section types we can ignore... */
if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE ||
ph[i].p_type == PT_PHDR
- || ph[i].p_type == PT_MIPS_REGINFO)
+ || ph[i].p_type == PT_MIPS_REGINFO
+ || ph[i].p_type == PT_MIPS_ABIFLAGS)
continue;
/* Section types we can't handle... */
else if (ph[i].p_type != PT_LOAD) {
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
index 41a2fa1fa12e..a0c2d6ccdedc 100644
--- a/arch/mips/dec/int-handler.S
+++ b/arch/mips/dec/int-handler.S
@@ -146,7 +146,14 @@
/*
* Find irq with highest priority
*/
- PTR_LA t1,cpu_mask_nr_tbl
+ # open coded PTR_LA t1, cpu_mask_nr_tbl
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
+ # open coded la t1, cpu_mask_nr_tbl
+ lui t1, %hi(cpu_mask_nr_tbl)
+ addiu t1, %lo(cpu_mask_nr_tbl)
+#else
+#error GCC `-msym32' option required for 64-bit DECstation builds
+#endif
1: lw t2,(t1)
nop
and t2,t0
@@ -195,7 +202,14 @@
/*
* Find irq with highest priority
*/
- PTR_LA t1,asic_mask_nr_tbl
+ # open coded PTR_LA t1,asic_mask_nr_tbl
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
+ # open coded la t1, asic_mask_nr_tbl
+ lui t1, %hi(asic_mask_nr_tbl)
+ addiu t1, %lo(asic_mask_nr_tbl)
+#else
+#error GCC `-msym32' option required for 64-bit DECstation builds
+#endif
2: lw t2,(t1)
nop
and t2,t0
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index 5699ec3a71af..fd0347da36df 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -223,7 +223,8 @@ static inline int pfn_valid(unsigned long pfn)
#endif
-#define virt_to_page(kaddr) pfn_to_page(PFN_DOWN(virt_to_phys(kaddr)))
+#define virt_to_page(kaddr) pfn_to_page(PFN_DOWN(virt_to_phys((void *) \
+ (kaddr))))
extern int __virt_addr_valid(const volatile void *kaddr);
#define virt_addr_valid(kaddr) \
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 088e92a79ae6..7da9ff143499 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -25,6 +25,7 @@
#include <linux/power/jz4740-battery.h>
#include <linux/power/gpio-charger.h>
+#include <asm/mach-jz4740/gpio.h>
#include <asm/mach-jz4740/jz4740_fb.h>
#include <asm/mach-jz4740/jz4740_mmc.h>
#include <asm/mach-jz4740/jz4740_nand.h>
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
index 00b798d2fb7c..000d2d91b704 100644
--- a/arch/mips/jz4740/gpio.c
+++ b/arch/mips/jz4740/gpio.c
@@ -27,6 +27,7 @@
#include <linux/seq_file.h>
#include <asm/mach-jz4740/base.h>
+#include <asm/mach-jz4740/gpio.h>
#include "irq.h"
diff --git a/arch/mips/jz4740/irq.h b/arch/mips/jz4740/irq.h
index 0f48720b5b63..486db78808cc 100644
--- a/arch/mips/jz4740/irq.h
+++ b/arch/mips/jz4740/irq.h
@@ -16,7 +16,9 @@
#define __MIPS_JZ4740_IRQ_H__
#include <linux/irq.h>
+#include <asm/mach-jz4740/irq.h>
+struct irq_data;
extern void jz4740_irq_suspend(struct irq_data *data);
extern void jz4740_irq_resume(struct irq_data *data);
diff --git a/arch/mips/kernel/bmips_vec.S b/arch/mips/kernel/bmips_vec.S
index d4614d31d828..d9495f3f3fad 100644
--- a/arch/mips/kernel/bmips_vec.S
+++ b/arch/mips/kernel/bmips_vec.S
@@ -211,7 +211,6 @@ NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
END(bmips_reset_nmi_vec)
.set pop
- .previous
/***********************************************************************
* CPU1 warm restart vector (used for second and subsequent boots).
@@ -286,5 +285,3 @@ LEAF(bmips_enable_xks01)
jr ra
END(bmips_enable_xks01)
-
- .previous
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
index 50034f985be1..dd2d9f7e9412 100644
--- a/arch/mips/pci/ops-pmcmsp.c
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -193,8 +193,6 @@ static void pci_proc_init(void)
}
#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
-static DEFINE_SPINLOCK(bpci_lock);
-
/*****************************************************************************
*
* STRUCT: pci_io_resource
@@ -368,7 +366,6 @@ int msp_pcibios_config_access(unsigned char access_type,
struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
unsigned char bus_num = bus->number;
unsigned char dev_fn = (unsigned char)devfn;
- unsigned long flags;
unsigned long intr;
unsigned long value;
static char pciirqflag;
@@ -401,10 +398,7 @@ int msp_pcibios_config_access(unsigned char access_type,
}
#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
- local_irq_save(flags);
vpe_status = dvpe();
-#else
- spin_lock_irqsave(&bpci_lock, flags);
#endif
/*
@@ -457,9 +451,6 @@ int msp_pcibios_config_access(unsigned char access_type,
#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
evpe(vpe_status);
- local_irq_restore(flags);
-#else
- spin_unlock_irqrestore(&bpci_lock, flags);
#endif
return -1;
@@ -467,9 +458,6 @@ int msp_pcibios_config_access(unsigned char access_type,
#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
evpe(vpe_status);
- local_irq_restore(flags);
-#else
- spin_unlock_irqrestore(&bpci_lock, flags);
#endif
return PCIBIOS_SUCCESSFUL;
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c
index 0e046d82e4e3..d54ea93651ac 100644
--- a/arch/mips/pci/ops-tx4927.c
+++ b/arch/mips/pci/ops-tx4927.c
@@ -199,8 +199,6 @@ static struct {
char *tx4927_pcibios_setup(char *str)
{
- unsigned long val;
-
if (!strncmp(str, "trdyto=", 7)) {
u8 val = 0;
if (kstrtou8(str + 7, 0, &val) == 0)
diff --git a/arch/mips/sgi-ip22/Platform b/arch/mips/sgi-ip22/Platform
index b7a4b7e04c38..e8f6b3a42a48 100644
--- a/arch/mips/sgi-ip22/Platform
+++ b/arch/mips/sgi-ip22/Platform
@@ -25,7 +25,7 @@ endif
# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
#
ifdef CONFIG_SGI_IP28
- ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n)
+ ifeq ($(call cc-option-yn,-march=r10000 -mr10k-cache-barrier=store), n)
$(error gcc doesn't support needed option -mr10k-cache-barrier=store)
endif
endif
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index f5443645ffca..4dcd7f5b027f 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -21,11 +21,19 @@ all: $(obj)/zImage
BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -Os -msoft-float -pipe \
- -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
- -isystem $(shell $(CROSS32CC) -print-file-name=include)
+ -fomit-frame-pointer -fno-builtin -fPIC -nostdinc
+BOOTCC := $(CC)
ifdef CONFIG_PPC64_BOOT_WRAPPER
BOOTCFLAGS += -m64
+else
+BOOTCFLAGS += -m32
+ifdef CROSS32_COMPILE
+ BOOTCC := $(CROSS32_COMPILE)gcc
+endif
endif
+
+BOOTCFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include)
+
ifdef CONFIG_CPU_BIG_ENDIAN
BOOTCFLAGS += -mbig-endian
else
@@ -165,10 +173,10 @@ clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
empty.c zImage.coff.lds zImage.ps3.lds zImage.lds
quiet_cmd_bootcc = BOOTCC $@
- cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
+ cmd_bootcc = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
quiet_cmd_bootas = BOOTAS $@
- cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
+ cmd_bootas = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
quiet_cmd_bootar = BOOTAR $@
cmd_bootar = $(CROSS32AR) -cr$(KBUILD_ARFLAGS) $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 73abf3119ad1..eaac0cb57717 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1816,6 +1816,8 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu)
run->fail_entry.hardware_entry_failure_reason = 0;
return -EINVAL;
}
+ /* Enable TM so we can read the TM SPRs */
+ mtmsr(mfmsr() | MSR_TM);
current->thread.tm_tfhar = mfspr(SPRN_TFHAR);
current->thread.tm_tfiar = mfspr(SPRN_TFIAR);
current->thread.tm_texasr = mfspr(SPRN_TEXASR);
diff --git a/arch/powerpc/mm/subpage-prot.c b/arch/powerpc/mm/subpage-prot.c
index 6c0b1f5f8d2c..6fd582b16e22 100644
--- a/arch/powerpc/mm/subpage-prot.c
+++ b/arch/powerpc/mm/subpage-prot.c
@@ -36,7 +36,7 @@ void subpage_prot_free(struct mm_struct *mm)
}
}
addr = 0;
- for (i = 0; i < 2; ++i) {
+ for (i = 0; i < (TASK_SIZE_USER64 >> 43); ++i) {
p = spt->protptrs[i];
if (!p)
continue;
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 1c0a60d98867..c24c73a2e2b5 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -112,7 +112,6 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
of_detach_node(np);
of_node_put(parent);
- of_node_put(np); /* Must decrement the refcount */
return 0;
}
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index 24e3e569a13c..124312be129b 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -2,14 +2,13 @@
#define BOOT_COMPRESSED_MISC_H
/*
- * we have to be careful, because no indirections are allowed here, and
- * paravirt_ops is a kind of one. As it will only run in baremetal anyway,
- * we just keep it from happening
+ * Special hack: we have to be careful, because no indirections are allowed here,
+ * and paravirt_ops is a kind of one. As it will only run in baremetal anyway,
+ * we just keep it from happening. (This list needs to be extended when new
+ * paravirt and debugging variants are added.)
*/
#undef CONFIG_PARAVIRT
-#ifdef CONFIG_X86_32
-#define _ASM_X86_DESC_H 1
-#endif
+#undef CONFIG_PARAVIRT_SPINLOCKS
#include <linux/linkage.h>
#include <linux/screen_info.h>
diff --git a/arch/x86/crypto/sha1_avx2_x86_64_asm.S b/arch/x86/crypto/sha1_avx2_x86_64_asm.S
index 1cd792db15ef..1eab79c9ac48 100644
--- a/arch/x86/crypto/sha1_avx2_x86_64_asm.S
+++ b/arch/x86/crypto/sha1_avx2_x86_64_asm.S
@@ -117,11 +117,10 @@
.set T1, REG_T1
.endm
-#define K_BASE %r8
#define HASH_PTR %r9
+#define BLOCKS_CTR %r8
#define BUFFER_PTR %r10
#define BUFFER_PTR2 %r13
-#define BUFFER_END %r11
#define PRECALC_BUF %r14
#define WK_BUF %r15
@@ -205,14 +204,14 @@
* blended AVX2 and ALU instruction scheduling
* 1 vector iteration per 8 rounds
*/
- vmovdqu ((i * 2) + PRECALC_OFFSET)(BUFFER_PTR), W_TMP
+ vmovdqu (i * 2)(BUFFER_PTR), W_TMP
.elseif ((i & 7) == 1)
- vinsertf128 $1, (((i-1) * 2)+PRECALC_OFFSET)(BUFFER_PTR2),\
+ vinsertf128 $1, ((i-1) * 2)(BUFFER_PTR2),\
WY_TMP, WY_TMP
.elseif ((i & 7) == 2)
vpshufb YMM_SHUFB_BSWAP, WY_TMP, WY
.elseif ((i & 7) == 4)
- vpaddd K_XMM(K_BASE), WY, WY_TMP
+ vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP
.elseif ((i & 7) == 7)
vmovdqu WY_TMP, PRECALC_WK(i&~7)
@@ -255,7 +254,7 @@
vpxor WY, WY_TMP, WY_TMP
.elseif ((i & 7) == 7)
vpxor WY_TMP2, WY_TMP, WY
- vpaddd K_XMM(K_BASE), WY, WY_TMP
+ vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP
vmovdqu WY_TMP, PRECALC_WK(i&~7)
PRECALC_ROTATE_WY
@@ -291,7 +290,7 @@
vpsrld $30, WY, WY
vpor WY, WY_TMP, WY
.elseif ((i & 7) == 7)
- vpaddd K_XMM(K_BASE), WY, WY_TMP
+ vpaddd K_XMM + K_XMM_AR(%rip), WY, WY_TMP
vmovdqu WY_TMP, PRECALC_WK(i&~7)
PRECALC_ROTATE_WY
@@ -446,6 +445,16 @@
.endm
+/* Add constant only if (%2 > %3) condition met (uses RTA as temp)
+ * %1 + %2 >= %3 ? %4 : 0
+ */
+.macro ADD_IF_GE a, b, c, d
+ mov \a, RTA
+ add $\d, RTA
+ cmp $\c, \b
+ cmovge RTA, \a
+.endm
+
/*
* macro implements 80 rounds of SHA-1, for multiple blocks with s/w pipelining
*/
@@ -463,13 +472,16 @@
lea (2*4*80+32)(%rsp), WK_BUF
# Precalc WK for first 2 blocks
- PRECALC_OFFSET = 0
+ ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 2, 64
.set i, 0
.rept 160
PRECALC i
.set i, i + 1
.endr
- PRECALC_OFFSET = 128
+
+ /* Go to next block if needed */
+ ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 3, 128
+ ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128
xchg WK_BUF, PRECALC_BUF
.align 32
@@ -479,8 +491,8 @@
* we use K_BASE value as a signal of a last block,
* it is set below by: cmovae BUFFER_PTR, K_BASE
*/
- cmp K_BASE, BUFFER_PTR
- jne _begin
+ test BLOCKS_CTR, BLOCKS_CTR
+ jnz _begin
.align 32
jmp _end
.align 32
@@ -512,10 +524,10 @@
.set j, j+2
.endr
- add $(2*64), BUFFER_PTR /* move to next odd-64-byte block */
- cmp BUFFER_END, BUFFER_PTR /* is current block the last one? */
- cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */
-
+ /* Update Counter */
+ sub $1, BLOCKS_CTR
+ /* Move to the next block only if needed*/
+ ADD_IF_GE BUFFER_PTR, BLOCKS_CTR, 4, 128
/*
* rounds
* 60,62,64,66,68
@@ -532,8 +544,8 @@
UPDATE_HASH 12(HASH_PTR), D
UPDATE_HASH 16(HASH_PTR), E
- cmp K_BASE, BUFFER_PTR /* is current block the last one? */
- je _loop
+ test BLOCKS_CTR, BLOCKS_CTR
+ jz _loop
mov TB, B
@@ -575,10 +587,10 @@
.set j, j+2
.endr
- add $(2*64), BUFFER_PTR2 /* move to next even-64-byte block */
-
- cmp BUFFER_END, BUFFER_PTR2 /* is current block the last one */
- cmovae K_BASE, BUFFER_PTR /* signal the last iteration smartly */
+ /* update counter */
+ sub $1, BLOCKS_CTR
+ /* Move to the next block only if needed*/
+ ADD_IF_GE BUFFER_PTR2, BLOCKS_CTR, 4, 128
jmp _loop3
_loop3:
@@ -641,19 +653,12 @@
avx2_zeroupper
- lea K_XMM_AR(%rip), K_BASE
-
+ /* Setup initial values */
mov CTX, HASH_PTR
mov BUF, BUFFER_PTR
- lea 64(BUF), BUFFER_PTR2
-
- shl $6, CNT /* mul by 64 */
- add BUF, CNT
- add $64, CNT
- mov CNT, BUFFER_END
- cmp BUFFER_END, BUFFER_PTR2
- cmovae K_BASE, BUFFER_PTR2
+ mov BUF, BUFFER_PTR2
+ mov CNT, BLOCKS_CTR
xmm_mov BSWAP_SHUFB_CTL(%rip), YMM_SHUFB_BSWAP
diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c
index ba9c75c5a432..b11fb043c80f 100644
--- a/arch/x86/crypto/sha1_ssse3_glue.c
+++ b/arch/x86/crypto/sha1_ssse3_glue.c
@@ -224,7 +224,7 @@ static bool __init avx_usable(void)
#ifdef CONFIG_AS_AVX2
static bool __init avx2_usable(void)
{
- if (false && avx_usable() && cpu_has_avx2 &&
+ if (avx_usable() && cpu_has_avx2 &&
boot_cpu_has(X86_FEATURE_BMI1) &&
boot_cpu_has(X86_FEATURE_BMI2))
return true;
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 86281ffb96d6..239cd7913df6 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -909,6 +909,14 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
int pin;
struct mpc_intsrc mp_irq;
+ /*
+ * Check bus_irq boundary.
+ */
+ if (bus_irq >= NR_IRQS_LEGACY) {
+ pr_warn("Invalid bus_irq %u for legacy override\n", bus_irq);
+ return;
+ }
+
/*
* Convert 'gsi' to 'ioapic.pin'.
*/
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 10544b9ae3d0..ec91ccee0661 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -2009,17 +2009,14 @@ static unsigned long get_segment_base(unsigned int segment)
if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) {
struct ldt_struct *ldt;
- if (idx > LDT_ENTRIES)
- return 0;
-
/* IRQs are off, so this synchronizes with smp_store_release */
ldt = lockless_dereference(current->active_mm->context.ldt);
- if (!ldt || idx > ldt->size)
+ if (!ldt || idx >= ldt->size)
return 0;
desc = &ldt->entries[idx];
} else {
- if (idx > GDT_ENTRIES)
+ if (idx >= GDT_ENTRIES)
return 0;
desc = __this_cpu_ptr(&gdt_page.gdt[0]) + idx;
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 701db48562b1..42a970d19ab3 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1476,6 +1476,8 @@ ENTRY(nmi)
* other IST entries.
*/
+ ASM_CLAC
+
/* Use %rdx as out temp variable throughout */
pushq_cfi %rdx
CFI_REL_OFFSET rdx, 0
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index b6547a441bad..608f18c62412 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -401,6 +401,8 @@ static int arch_copy_kprobe(struct kprobe *p)
int arch_prepare_kprobe(struct kprobe *p)
{
+ int ret;
+
if (alternatives_text_reserved(p->addr, p->addr))
return -EINVAL;
@@ -411,7 +413,13 @@ int arch_prepare_kprobe(struct kprobe *p)
if (!p->ainsn.insn)
return -ENOMEM;
- return arch_copy_kprobe(p);
+ ret = arch_copy_kprobe(p);
+ if (ret) {
+ free_insn_slot(p->ainsn.insn, 0);
+ p->ainsn.insn = NULL;
+ }
+
+ return ret;
}
void arch_arm_kprobe(struct kprobe *p)
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 61da6be309a7..17cc2a2e27d6 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -150,6 +150,8 @@ void kvm_async_pf_task_wait(u32 token)
if (hlist_unhashed(&n.link))
break;
+ rcu_irq_exit();
+
if (!n.halted) {
local_irq_enable();
schedule();
@@ -158,11 +160,11 @@ void kvm_async_pf_task_wait(u32 token)
/*
* We cannot reschedule. So halt.
*/
- rcu_irq_exit();
native_safe_halt();
local_irq_disable();
- rcu_irq_enter();
}
+
+ rcu_irq_enter();
}
if (!n.halted)
finish_wait(&n.wq, &wait);
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 16fb0099b7f2..f05f2d897a67 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1187,7 +1187,7 @@ static void __init xen_cleanhighmap(unsigned long vaddr,
/* NOTE: The loop is more greedy than the cleanup_highmap variant.
* We include the PMD passed in on _both_ boundaries. */
- for (; vaddr <= vaddr_end && (pmd < (level2_kernel_pgt + PAGE_SIZE));
+ for (; vaddr <= vaddr_end && (pmd < (level2_kernel_pgt + PTRS_PER_PMD));
pmd++, vaddr += PMD_SIZE) {
if (pmd_none(*pmd))
continue;
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index 4d2872fd9bb5..a71d2739fa82 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -94,13 +94,11 @@ unsigned long __sync_fetch_and_or_4(unsigned long *p, unsigned long v)
}
EXPORT_SYMBOL(__sync_fetch_and_or_4);
-#ifdef CONFIG_NET
/*
* Networking support
*/
EXPORT_SYMBOL(csum_partial);
EXPORT_SYMBOL(csum_partial_copy_generic);
-#endif /* CONFIG_NET */
/*
* Architecture-specific symbols
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c
index 63cbb867dadd..1fface176acd 100644
--- a/arch/xtensa/mm/cache.c
+++ b/arch/xtensa/mm/cache.c
@@ -63,7 +63,7 @@
#error "HIGHMEM is not supported on cores with aliasing cache."
#endif
-#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
/*
* Any time the kernel writes to a user page cache page, or it is about to
@@ -116,7 +116,7 @@ void flush_dcache_page(struct page *page)
/* There shouldn't be an entry in the cache for this page anymore. */
}
-
+EXPORT_SYMBOL(flush_dcache_page);
/*
* For now, flush the whole cache. FIXME??
@@ -128,6 +128,7 @@ void local_flush_cache_range(struct vm_area_struct *vma,
__flush_invalidate_dcache_all();
__invalidate_icache_all();
}
+EXPORT_SYMBOL(local_flush_cache_range);
/*
* Remove any entry in the cache for this page.
@@ -147,8 +148,9 @@ void local_flush_cache_page(struct vm_area_struct *vma, unsigned long address,
__flush_invalidate_dcache_page_alias(virt, phys);
__invalidate_icache_page_alias(virt, phys);
}
+EXPORT_SYMBOL(local_flush_cache_page);
-#endif
+#endif /* DCACHE_WAY_SIZE > PAGE_SIZE */
void
update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
@@ -165,7 +167,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
flush_tlb_page(vma, addr);
-#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) {
@@ -197,7 +199,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
* flush_dcache_page() on the page.
*/
-#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long vaddr, void *dst, const void *src,
diff --git a/block/bio.c b/block/bio.c
index 529e4195724e..dcc6365bcc11 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1337,6 +1337,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
offset = uaddr & ~PAGE_MASK;
for (j = cur_page; j < page_limit; j++) {
unsigned int bytes = PAGE_SIZE - offset;
+ unsigned short prev_bi_vcnt = bio->bi_vcnt;
if (len <= 0)
break;
@@ -1351,6 +1352,13 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
bytes)
break;
+ /*
+ * check if vector was merged with previous
+ * drop page reference if needed
+ */
+ if (bio->bi_vcnt == prev_bi_vcnt)
+ put_page(pages[j]);
+
len -= bytes;
offset = 0;
}
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 90112092d1e6..b297d43e1121 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2796,10 +2796,12 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
{
if (!sata_pmp_attached(ap)) {
- if (likely(devno < ata_link_max_devices(&ap->link)))
+ if (likely(devno >= 0 &&
+ devno < ata_link_max_devices(&ap->link)))
return &ap->link.device[devno];
} else {
- if (likely(devno < ap->nr_pmp_links))
+ if (likely(devno >= 0 &&
+ devno < ap->nr_pmp_links))
return &ap->pmp_link[devno].device[0];
}
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index cbc3de793d1d..0038dc4c06c7 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -352,7 +352,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
};
const struct ata_port_info *ppi[] = { &info_hpt366, NULL };
- void *hpriv = NULL;
+ const void *hpriv = NULL;
u32 reg1;
int rc;
@@ -383,7 +383,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
break;
}
/* Now kick off ATA set up */
- return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, hpriv, 0);
+ return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, (void *)hpriv, 0);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 1aa29f8fdfe1..7c76f7270bec 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -478,8 +478,14 @@ void drbd_bm_cleanup(struct drbd_device *device)
* this masks out the remaining bits.
* Returns the number of bits cleared.
*/
+#ifndef BITS_PER_PAGE
#define BITS_PER_PAGE (1UL << (PAGE_SHIFT + 3))
#define BITS_PER_PAGE_MASK (BITS_PER_PAGE - 1)
+#else
+# if BITS_PER_PAGE != (1UL << (PAGE_SHIFT + 3))
+# error "ambiguous BITS_PER_PAGE"
+# endif
+#endif
#define BITS_PER_LONG_MASK (BITS_PER_LONG - 1)
static int bm_clear_surplus(struct drbd_bitmap *b)
{
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 2ce3dfd7e6b9..876d0c3eaf58 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -137,7 +137,7 @@
*/
-static bool verbose = 0;
+static int verbose;
static int major = PG_MAJOR;
static char *name = PG_NAME;
static int disable = 0;
@@ -168,7 +168,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
#include <asm/uaccess.h>
-module_param(verbose, bool, 0644);
+module_param(verbose, int, 0644);
module_param(major, int, 0);
module_param(name, charp, 0);
module_param_array(drive0, int, NULL, 0);
diff --git a/drivers/clk/clk-efm32gg.c b/drivers/clk/clk-efm32gg.c
index bac2ddf49d02..73a8d0ff530c 100644
--- a/drivers/clk/clk-efm32gg.c
+++ b/drivers/clk/clk-efm32gg.c
@@ -22,7 +22,7 @@ static struct clk_onecell_data clk_data = {
.clk_num = ARRAY_SIZE(clk),
};
-static int __init efm32gg_cmu_init(struct device_node *np)
+static void __init efm32gg_cmu_init(struct device_node *np)
{
int i;
void __iomem *base;
@@ -33,7 +33,7 @@ static int __init efm32gg_cmu_init(struct device_node *np)
base = of_iomap(np, 0);
if (!base) {
pr_warn("Failed to map address range for efm32gg,cmu node\n");
- return -EADDRNOTAVAIL;
+ return;
}
clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL,
@@ -76,6 +76,6 @@ static int __init efm32gg_cmu_init(struct device_node *np)
clk[clk_HFPERCLKDAC0] = clk_register_gate(NULL, "HFPERCLK.DAC0",
"HFXO", 0, base + CMU_HFPERCLKEN0, 17, 0, NULL);
- return of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+ of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
CLK_OF_DECLARE(efm32ggcmu, "efm32gg,cmu", efm32gg_cmu_init);
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 8114731a1c62..8ff32b126605 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1040,7 +1040,7 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
if (early_bytes) {
dev_vdbg(&pl08x->adev->dev,
- "%s byte width LLIs (remain 0x%08x)\n",
+ "%s byte width LLIs (remain 0x%08zx)\n",
__func__, bd.remainder);
prep_byte_width_lli(pl08x, &bd, &cctl, early_bytes,
num_llis++, &total_bytes);
@@ -1662,7 +1662,7 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_cyclic(
dma_addr_t slave_addr;
dev_dbg(&pl08x->adev->dev,
- "%s prepare cyclic transaction of %d/%d bytes %s %s\n",
+ "%s prepare cyclic transaction of %zd/%zd bytes %s %s\n",
__func__, period_len, buf_len,
direction == DMA_MEM_TO_DEV ? "to" : "from",
plchan->name);
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 4e8fb8261a87..8dc43ac6fa8d 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -271,7 +271,7 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
struct tegra_gpio_bank *bank;
int port;
int pin;
- int unmasked = 0;
+ bool unmasked = false;
struct irq_chip *chip = irq_desc_get_chip(desc);
chained_irq_enter(chip, desc);
@@ -291,8 +291,8 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
* before executing the hander so that we don't
* miss edges
*/
- if (lvl & (0x100 << pin)) {
- unmasked = 1;
+ if (!unmasked && lvl & (0x100 << pin)) {
+ unmasked = true;
chained_irq_exit(chip, desc);
}
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index f7d71190aad5..903d059fc7a6 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -698,13 +698,13 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
struct drm_gem_object *obj = ptr;
struct drm_device *dev = obj->dev;
+ if (dev->driver->gem_close_object)
+ dev->driver->gem_close_object(obj, file_priv);
+
if (drm_core_check_feature(dev, DRIVER_PRIME))
drm_gem_remove_prime_handles(obj, file_priv);
drm_vma_node_revoke(&obj->vma_node, file_priv->filp);
- if (dev->driver->gem_close_object)
- dev->driver->gem_close_object(obj, file_priv);
-
drm_gem_object_handle_unreference_unlocked(obj);
return 0;
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index b8c689202c40..14d2f2cfd88f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -141,10 +141,11 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
if (obj->base.name)
seq_printf(m, " (name: %d)", obj->base.name);
- list_for_each_entry(vma, &obj->vma_list, vma_link)
+ list_for_each_entry(vma, &obj->vma_list, vma_link) {
if (vma->pin_count > 0)
pin_count++;
- seq_printf(m, " (pinned x %d)", pin_count);
+ }
+ seq_printf(m, " (pinned x %d)", pin_count);
if (obj->pin_display)
seq_printf(m, " (display)");
if (obj->fence_reg != I915_FENCE_REG_NONE)
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 057951163126..80a708396e49 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -34,10 +34,13 @@ static inline void __user *to_user_ptr(u64 address)
}
static struct msm_gem_submit *submit_create(struct drm_device *dev,
- struct msm_gpu *gpu, int nr)
+ struct msm_gpu *gpu, uint32_t nr)
{
struct msm_gem_submit *submit;
- int sz = sizeof(*submit) + (nr * sizeof(submit->bos[0]));
+ uint64_t sz = sizeof(*submit) + ((u64)nr * sizeof(submit->bos[0]));
+
+ if (sz > SIZE_MAX)
+ return NULL;
submit = kmalloc(sz, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
if (submit) {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index 118e2206b792..129751121684 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -285,7 +285,7 @@ static int vmw_cmd_invalid(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
SVGA3dCmdHeader *header)
{
- return capable(CAP_SYS_ADMIN) ? : -EINVAL;
+ return -EINVAL;
}
static int vmw_cmd_ok(struct vmw_private *dev_priv,
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index b8021c499bbd..f2f729adc3fd 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -975,6 +975,8 @@ static int usbhid_parse(struct hid_device *hid)
unsigned int rsize = 0;
char *rdesc;
int ret, n;
+ int num_descriptors;
+ size_t offset = offsetof(struct hid_descriptor, desc);
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
@@ -997,10 +999,18 @@ static int usbhid_parse(struct hid_device *hid)
return -ENODEV;
}
+ if (hdesc->bLength < sizeof(struct hid_descriptor)) {
+ dbg_hid("hid descriptor is too short\n");
+ return -EINVAL;
+ }
+
hid->version = le16_to_cpu(hdesc->bcdHID);
hid->country = hdesc->bCountryCode;
- for (n = 0; n < hdesc->bNumDescriptors; n++)
+ num_descriptors = min_t(int, hdesc->bNumDescriptors,
+ (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
+
+ for (n = 0; n < num_descriptors; n++)
if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
index eb3ba56e90b1..51d62e0c1113 100644
--- a/drivers/i2c/busses/i2c-ismt.c
+++ b/drivers/i2c/busses/i2c-ismt.c
@@ -343,6 +343,11 @@ static int ismt_process_desc(const struct ismt_desc *desc,
data->word = dma_buffer[0] | (dma_buffer[1] << 8);
break;
case I2C_SMBUS_BLOCK_DATA:
+ if (desc->rxbytes != dma_buffer[0] + 1)
+ return -EMSGSIZE;
+
+ memcpy(data->block, dma_buffer, desc->rxbytes);
+ break;
case I2C_SMBUS_I2C_BLOCK_DATA:
memcpy(&data->block[1], dma_buffer, desc->rxbytes);
data->block[0] = desc->rxbytes;
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
index f6d313e528de..15248f63583e 100644
--- a/drivers/i2c/muxes/Kconfig
+++ b/drivers/i2c/muxes/Kconfig
@@ -58,6 +58,6 @@ config I2C_MUX_PINCTRL
different sets of pins at run-time.
This driver can also be built as a module. If so, the module will be
- called pinctrl-i2cmux.
+ called i2c-mux-pinctrl.
endmenu
diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index 010578f1d762..bb7c50cd3f72 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -109,7 +109,7 @@ static inline unsigned int exynos_adc_get_version(struct platform_device *pdev)
const struct of_device_id *match;
match = of_match_node(exynos_adc_match, pdev->dev.of_node);
- return (unsigned int)match->data;
+ return (uintptr_t)match->data;
}
static void exynos_adc_hw_init(struct exynos_adc *info)
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
index 0062d0e71d03..fb58b2d11d28 100644
--- a/drivers/iio/adc/vf610_adc.c
+++ b/drivers/iio/adc/vf610_adc.c
@@ -71,7 +71,7 @@
#define VF610_ADC_ADSTS_MASK 0x300
#define VF610_ADC_ADLPC_EN 0x80
#define VF610_ADC_ADHSC_EN 0x400
-#define VF610_ADC_REFSEL_VALT 0x100
+#define VF610_ADC_REFSEL_VALT 0x800
#define VF610_ADC_REFSEL_VBG 0x1000
#define VF610_ADC_ADTRG_HARD 0x2000
#define VF610_ADC_AVGS_8 0x4000
diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c
index 5e1b117d4e3b..4f2994a667d0 100644
--- a/drivers/iio/imu/adis16480.c
+++ b/drivers/iio/imu/adis16480.c
@@ -724,7 +724,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
.gyro_max_scale = 450,
.accel_max_val = IIO_M_S_2_TO_G(12500),
- .accel_max_scale = 5,
+ .accel_max_scale = 10,
},
[ADIS16485] = {
.channels = adis16485_channels,
diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c
index 94daa9fc1247..6a135effb7c5 100644
--- a/drivers/iio/light/tsl2563.c
+++ b/drivers/iio/light/tsl2563.c
@@ -626,7 +626,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private)
struct tsl2563_chip *chip = iio_priv(dev_info);
iio_push_event(dev_info,
- IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
+ IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
0,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_EITHER),
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index fb9bb266a517..bb20bc543a29 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -753,6 +753,8 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
} else
ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
qp_attr_mask);
+ qp_attr->port_num = id_priv->id.port_num;
+ *qp_attr_mask |= IB_QP_PORT;
break;
default:
ret = -ENOSYS;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index ab6326cdde23..622da19f3f21 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1303,7 +1303,7 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
int out_len)
{
struct ib_uverbs_resize_cq cmd;
- struct ib_uverbs_resize_cq_resp resp;
+ struct ib_uverbs_resize_cq_resp resp = {};
struct ib_udata udata;
struct ib_cq *cq;
int ret = -EINVAL;
@@ -1915,7 +1915,8 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
goto out;
}
- if (!rdma_is_port_valid(qp->device, cmd.port_num)) {
+ if ((cmd.attr_mask & IB_QP_PORT) &&
+ !rdma_is_port_valid(qp->device, cmd.port_num)) {
ret = -EINVAL;
goto release_qp;
}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 5bbfd0ecb31a..6354c1c7576f 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -315,6 +315,7 @@ static void ib_uverbs_release_file(struct kref *ref)
if (atomic_dec_and_test(&file->device->refcount))
ib_uverbs_comp_dev(file->device);
+ kobject_put(&file->device->kobj);
kfree(file);
}
@@ -784,7 +785,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
static int ib_uverbs_close(struct inode *inode, struct file *filp)
{
struct ib_uverbs_file *file = filp->private_data;
- struct ib_uverbs_device *dev = file->device;
ib_uverbs_cleanup_ucontext(file, file->ucontext);
@@ -792,7 +792,6 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp)
kref_put(&file->async_file->ref, ib_uverbs_release_event_file);
kref_put(&file->ref, ib_uverbs_release_file);
- kobject_put(&dev->kobj);
return 0;
}
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 811b24a539c0..736cf45f8c0c 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -794,7 +794,7 @@ static struct ib_mr *iwch_alloc_fast_reg_mr(struct ib_pd *pd, int pbl_depth)
struct iwch_mr *mhp;
u32 mmid;
u32 stag = 0;
- int ret = 0;
+ int ret = -ENOMEM;
php = to_iwch_pd(pd);
rhp = php->rhp;
@@ -817,7 +817,8 @@ static struct ib_mr *iwch_alloc_fast_reg_mr(struct ib_pd *pd, int pbl_depth)
mhp->attr.state = 1;
mmid = (stag) >> 8;
mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
- if (insert_handle(rhp, &rhp->mmidr, mhp, mmid))
+ ret = insert_handle(rhp, &rhp->mmidr, mhp, mmid);
+ if (ret)
goto err3;
PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag);
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c
index c04292c950f1..94f7856c3bdb 100644
--- a/drivers/infiniband/hw/cxgb4/cq.c
+++ b/drivers/infiniband/hw/cxgb4/cq.c
@@ -938,6 +938,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries,
goto err2;
if (ucontext) {
+ ret = -ENOMEM;
mm = kmalloc(sizeof *mm, GFP_KERNEL);
if (!mm)
goto err3;
diff --git a/drivers/infiniband/hw/mlx5/mem.c b/drivers/infiniband/hw/mlx5/mem.c
index 8499aec94db6..deff377934ff 100644
--- a/drivers/infiniband/hw/mlx5/mem.c
+++ b/drivers/infiniband/hw/mlx5/mem.c
@@ -68,7 +68,7 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift,
for (k = 0; k < len; k++) {
if (!(i & mask)) {
tmp = (unsigned long)pfn;
- m = min(m, find_first_bit(&tmp, sizeof(tmp)));
+ m = min_t(unsigned long, m, find_first_bit(&tmp, sizeof(tmp)));
skip = 1 << m;
mask = skip - 1;
base = pfn;
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
index edf6211d84b8..43e6f0572717 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
@@ -565,7 +565,8 @@ struct ib_pd *ocrdma_alloc_pd(struct ib_device *ibdev,
if (is_uctx_pd) {
ocrdma_release_ucontext_pd(uctx);
} else {
- status = ocrdma_mbx_dealloc_pd(dev, pd);
+ if (ocrdma_mbx_dealloc_pd(dev, pd))
+ pr_err("%s: ocrdma_mbx_dealloc_pd() failed\n", __func__);
kfree(pd);
}
exit:
@@ -1719,6 +1720,7 @@ struct ib_srq *ocrdma_create_srq(struct ib_pd *ibpd,
goto err;
if (udata == NULL) {
+ status = -ENOMEM;
srq->rqe_wr_id_tbl = kzalloc(sizeof(u64) * srq->rq.max_cnt,
GFP_KERNEL);
if (srq->rqe_wr_id_tbl == NULL)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index d7db3486f933..4a5764fe4b23 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -508,7 +508,6 @@ static int ipoib_cm_rx_handler(struct ib_cm_id *cm_id,
case IB_CM_REQ_RECEIVED:
return ipoib_cm_req_handler(cm_id, event);
case IB_CM_DREQ_RECEIVED:
- p = cm_id->context;
ib_send_cm_drep(cm_id, NULL, 0);
/* Fall through */
case IB_CM_REJ_RECEIVED:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 40be7b4206c0..1370012798cb 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1235,6 +1235,7 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv)
int i, wait_flushed = 0;
init_completion(&priv->ntbl.flushed);
+ set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags);
spin_lock_irqsave(&priv->lock, flags);
@@ -1279,7 +1280,6 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev)
ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n");
init_completion(&priv->ntbl.deleted);
- set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags);
/* Stop GC if called at init fail need to cancel work */
stopped = test_and_set_bit(IPOIB_STOP_NEIGH_GC, &priv->flags);
@@ -1768,6 +1768,7 @@ static int __init ipoib_init_module(void)
ipoib_sendq_size = max3(ipoib_sendq_size, 2 * MAX_SEND_CQE, IPOIB_MIN_QUEUE_SIZE);
#ifdef CONFIG_INFINIBAND_IPOIB_CM
ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP);
+ ipoib_max_conn_qp = max(ipoib_max_conn_qp, 0);
#endif
/*
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 9135606c8649..ab0fdcd36e18 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -158,7 +158,7 @@ static unsigned int get_time_pit(void)
#define GET_TIME(x) rdtscl(x)
#define DELTA(x,y) ((y)-(x))
#define TIME_NAME "TSC"
-#elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_TILE)
+#elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_TILE)
#define GET_TIME(x) do { x = get_cycles(); } while (0)
#define DELTA(x,y) ((y)-(x))
#define TIME_NAME "get_cycles"
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index ca843b6cf6bd..db511998fc4c 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -263,7 +263,8 @@ static int trackpoint_start_protocol(struct psmouse *psmouse, unsigned char *fir
if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
return -1;
- if (param[0] != TP_MAGIC_IDENT)
+ /* add new TP ID. */
+ if (!(param[0] & TP_MAGIC_IDENT))
return -1;
if (firmware_id)
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
index ecd0547964a5..2d7be0435957 100644
--- a/drivers/input/mouse/trackpoint.h
+++ b/drivers/input/mouse/trackpoint.h
@@ -21,8 +21,9 @@
#define TP_COMMAND 0xE2 /* Commands start with this */
#define TP_READ_ID 0xE1 /* Sent for device identification */
-#define TP_MAGIC_IDENT 0x01 /* Sent after a TP_READ_ID followed */
+#define TP_MAGIC_IDENT 0x03 /* Sent after a TP_READ_ID followed */
/* by the firmware ID */
+ /* Firmware ID includes 0x1, 0x2, 0x3 */
/*
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 8d9ba0c3827c..94ab494a6ade 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -40,7 +40,6 @@
MODULE_AUTHOR("Laurent Canet <canetl@xxxxxxxx>, Thibaut Varene <varenet@xxxxxxxxxxxxxxxx>, Helge Deller <deller@xxxxxx>");
MODULE_DESCRIPTION("HP GSC PS2 port driver");
MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
#define PFX "gscps2.c: "
@@ -439,6 +438,7 @@ static struct parisc_device_id gscps2_device_tbl[] = {
#endif
{ 0, } /* 0 terminated list */
};
+MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
static struct parisc_driver parisc_ps2_driver = {
.name = "gsc_ps2",
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 69f1b6adb904..48b726f4ad48 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2027,11 +2027,11 @@ static int __init state_next(void)
break;
case IOMMU_ACPI_FINISHED:
early_enable_iommus();
- register_syscore_ops(&amd_iommu_syscore_ops);
x86_platform.iommu_shutdown = disable_iommus;
init_state = IOMMU_ENABLED;
break;
case IOMMU_ENABLED:
+ register_syscore_ops(&amd_iommu_syscore_ops);
ret = amd_iommu_init_pci();
init_state = ret ? IOMMU_INIT_ERROR : IOMMU_PCI_INIT;
enable_iommus_v2();
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c
index c15c840987d2..94a15ae52212 100644
--- a/drivers/irqchip/irq-brcmstb-l2.c
+++ b/drivers/irqchip/irq-brcmstb-l2.c
@@ -176,6 +176,7 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
ct->chip.irq_suspend = brcmstb_l2_intc_suspend;
ct->chip.irq_resume = brcmstb_l2_intc_resume;
+ ct->chip.irq_pm_shutdown = brcmstb_l2_intc_suspend;
if (of_property_read_bool(np, "brcm,irq-can-wake")) {
data->can_wake = true;
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
index 92cf6fcd20ac..cb428b9ee441 100644
--- a/drivers/isdn/hardware/mISDN/mISDNipac.c
+++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
@@ -754,10 +754,10 @@ dbusy_timer_handler(struct isac_hw *isac)
}
static int
-open_dchannel(struct isac_hw *isac, struct channel_req *rq)
+open_dchannel_caller(struct isac_hw *isac, struct channel_req *rq, void *caller)
{
pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
- isac->dch.dev.id, __builtin_return_address(1));
+ isac->dch.dev.id, caller);
if (rq->protocol != ISDN_P_TE_S0)
return -EINVAL;
if (rq->adr.channel == 1)
@@ -771,6 +771,12 @@ open_dchannel(struct isac_hw *isac, struct channel_req *rq)
return 0;
}
+static int
+open_dchannel(struct isac_hw *isac, struct channel_req *rq)
+{
+ return open_dchannel_caller(isac, rq, __builtin_return_address(0));
+}
+
static const char *ISACVer[] =
{"2086/2186 V1.1", "2085 B1", "2085 B2",
"2085 V2.3"};
@@ -1547,7 +1553,7 @@ ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
case OPEN_CHANNEL:
rq = arg;
if (rq->protocol == ISDN_P_TE_S0)
- err = open_dchannel(isac, rq);
+ err = open_dchannel_caller(isac, rq, __builtin_return_address(0));
else
err = open_bchannel(ipac, rq);
if (err)
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
index de69f6828c76..741675525b53 100644
--- a/drivers/isdn/hardware/mISDN/w6692.c
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -1176,10 +1176,10 @@ w6692_l1callback(struct dchannel *dch, u32 cmd)
}
static int
-open_dchannel(struct w6692_hw *card, struct channel_req *rq)
+open_dchannel(struct w6692_hw *card, struct channel_req *rq, void *caller)
{
pr_debug("%s: %s dev(%d) open from %p\n", card->name, __func__,
- card->dch.dev.id, __builtin_return_address(1));
+ card->dch.dev.id, caller);
if (rq->protocol != ISDN_P_TE_S0)
return -EINVAL;
if (rq->adr.channel == 1)
@@ -1207,7 +1207,7 @@ w6692_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
case OPEN_CHANNEL:
rq = arg;
if (rq->protocol == ISDN_P_TE_S0)
- err = open_dchannel(card, rq);
+ err = open_dchannel(card, rq, __builtin_return_address(0));
else
err = open_bchannel(card, rq);
if (err)
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index 08ae5b492bc4..c0e44d210326 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -349,6 +349,7 @@ static void *alloc_buffer_data(struct dm_bufio_client *c, gfp_t gfp_mask,
* as if GFP_NOIO was specified.
*/
+ noio_flag = 0;
if (gfp_mask & __GFP_NORETRY)
noio_flag = memalloc_noio_save();
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 4f0773c8ad20..98a47dbf48c2 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -24,16 +24,6 @@
#define DM_MSG_PREFIX "core"
-#ifdef CONFIG_PRINTK
-/*
- * ratelimit state to be used in DMXXX_LIMIT().
- */
-DEFINE_RATELIMIT_STATE(dm_ratelimit_state,
- DEFAULT_RATELIMIT_INTERVAL,
- DEFAULT_RATELIMIT_BURST);
-EXPORT_SYMBOL(dm_ratelimit_state);
-#endif
-
/*
* Cookies are numeric values sent with CHANGE and REMOVE
* uevents while resuming, removing or renaming the device.
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 16789320135f..affe5d3e768b 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5240,6 +5240,8 @@ static void raid5_do_work(struct work_struct *work)
pr_debug("%d stripes handled\n", handled);
spin_unlock_irq(&conf->device_lock);
+
+ async_tx_issue_pending_all();
blk_finish_plug(&plug);
pr_debug("--- raid5worker inactive\n");
@@ -6741,12 +6743,10 @@ static void end_reshape(struct r5conf *conf)
{
if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
- struct md_rdev *rdev;
spin_lock_irq(&conf->device_lock);
conf->previous_raid_disks = conf->raid_disks;
- rdev_for_each(rdev, conf->mddev)
- rdev->data_offset = rdev->new_data_offset;
+ md_finish_reshape(conf->mddev);
smp_wmb();
conf->reshape_progress = MaxSector;
spin_unlock_irq(&conf->device_lock);
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index ff10c2e90a5a..93a374fcced8 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -1708,27 +1708,9 @@ static long vpfe_param_handler(struct file *file, void *priv,
switch (cmd) {
case VPFE_CMD_S_CCDC_RAW_PARAMS:
+ ret = -EINVAL;
v4l2_warn(&vpfe_dev->v4l2_dev,
- "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
- if (ccdc_dev->hw_ops.set_params) {
- ret = ccdc_dev->hw_ops.set_params(param);
- if (ret) {
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "Error setting parameters in CCDC\n");
- goto unlock_out;
- }
- ret = vpfe_get_ccdc_image_format(vpfe_dev,
- &vpfe_dev->fmt);
- if (ret < 0) {
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "Invalid image format at CCDC\n");
- goto unlock_out;
- }
- } else {
- ret = -EINVAL;
- v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
- "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
- }
+ "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
break;
default:
ret = -ENOTTY;
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 2af2326ab3d2..33d6c05352a2 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -257,7 +257,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
return 0;
case LIRC_GET_REC_RESOLUTION:
- val = dev->rx_resolution;
+ val = dev->rx_resolution / 1000;
break;
case LIRC_SET_WIDEBAND_RECEIVER:
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 04bd3b6de401..67ceb3010a10 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -772,7 +772,7 @@ static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd,
#endif
-#ifdef CONFIG_I2O_EXT_ADAPTEC
+#if defined(CONFIG_I2O_EXT_ADAPTEC) && !defined(CONFIG_64BIT)
static int i2o_cfg_passthru(unsigned long arg)
{
struct i2o_cmd_passthru __user *cmd =
@@ -1045,7 +1045,7 @@ static long i2o_cfg_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
ret = i2o_cfg_evt_get(arg, fp);
break;
-#ifdef CONFIG_I2O_EXT_ADAPTEC
+#if defined(CONFIG_I2O_EXT_ADAPTEC) && !defined(CONFIG_64BIT)
case I2OPASSTHRU:
ret = i2o_cfg_passthru(arg);
break;
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 1577e6418306..c39d119b4cbd 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -497,12 +497,12 @@ const struct dev_pm_ops arizona_pm_ops = {
EXPORT_SYMBOL_GPL(arizona_pm_ops);
#ifdef CONFIG_OF
-int arizona_of_get_type(struct device *dev)
+unsigned long arizona_of_get_type(struct device *dev)
{
const struct of_device_id *id = of_match_device(arizona_of_match, dev);
if (id)
- return (int)id->data;
+ return (unsigned long)id->data;
else
return 0;
}
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c
index beccb790c9ba..9d4156fb082a 100644
--- a/drivers/mfd/arizona-i2c.c
+++ b/drivers/mfd/arizona-i2c.c
@@ -24,11 +24,12 @@
#include "arizona.h"
static int arizona_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct arizona *arizona;
const struct regmap_config *regmap_config;
- int ret, type;
+ unsigned long type;
+ int ret;
if (i2c->dev.of_node)
type = arizona_of_get_type(&i2c->dev);
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index 1ca554b18bef..5145d78bf07e 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -28,7 +28,8 @@ static int arizona_spi_probe(struct spi_device *spi)
const struct spi_device_id *id = spi_get_device_id(spi);
struct arizona *arizona;
const struct regmap_config *regmap_config;
- int ret, type;
+ unsigned long type;
+ int ret;
if (spi->dev.of_node)
type = arizona_of_get_type(&spi->dev);
diff --git a/drivers/mfd/arizona.h b/drivers/mfd/arizona.h
index b4cef777df73..2951498ab9a1 100644
--- a/drivers/mfd/arizona.h
+++ b/drivers/mfd/arizona.h
@@ -46,9 +46,9 @@ int arizona_irq_init(struct arizona *arizona);
int arizona_irq_exit(struct arizona *arizona);
#ifdef CONFIG_OF
-int arizona_of_get_type(struct device *dev);
+unsigned long arizona_of_get_type(struct device *dev);
#else
-static inline int arizona_of_get_type(struct device *dev)
+static inline unsigned long arizona_of_get_type(struct device *dev)
{
return 0;
}
diff --git a/drivers/mtd/maps/pmcmsp-flash.c b/drivers/mtd/maps/pmcmsp-flash.c
index f9fa3fad728e..2051f28ddac6 100644
--- a/drivers/mtd/maps/pmcmsp-flash.c
+++ b/drivers/mtd/maps/pmcmsp-flash.c
@@ -139,15 +139,13 @@ static int __init init_msp_flash(void)
}
msp_maps[i].bankwidth = 1;
- msp_maps[i].name = kmalloc(7, GFP_KERNEL);
+ msp_maps[i].name = kstrndup(flash_name, 7, GFP_KERNEL);
if (!msp_maps[i].name) {
iounmap(msp_maps[i].virt);
kfree(msp_parts[i]);
goto cleanup_loop;
}
- msp_maps[i].name = strncpy(msp_maps[i].name, flash_name, 7);
-
for (j = 0; j < pcnt; j++) {
part_name[5] = '0' + i;
part_name[7] = '0' + j;
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c
index 146b6047ed2b..a84fdfb10518 100644
--- a/drivers/mtd/maps/rbtx4939-flash.c
+++ b/drivers/mtd/maps/rbtx4939-flash.c
@@ -35,8 +35,6 @@ static int rbtx4939_flash_remove(struct platform_device *dev)
return 0;
if (info->mtd) {
- struct rbtx4939_flash_data *pdata = dev_get_platdata(&dev->dev);
-
mtd_device_unregister(info->mtd);
map_destroy(info->mtd);
}
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 4f0d83648e5a..9a7d0f3081fe 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -2387,6 +2387,7 @@ static int __init ns_init_module(void)
return 0;
err_exit:
+ nandsim_debugfs_remove(nand);
free_nandsim(nand);
nand_release(nsmtd);
for (i = 0;i < ARRAY_SIZE(nand->partitions); ++i)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3fdfe317a6c5..b7e2fb72578d 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -331,6 +331,9 @@ config XEN_NETDEV_FRONTEND
config XEN_NETDEV_BACKEND
tristate "Xen backend network device"
depends on XEN_BACKEND
+ depends on !(PAGE_SIZE_64KB || ARM64_64K_PAGES || \
+ IA64_PAGE_SIZE_64KB || MICROBLAZE_64K_PAGES || \
+ PARISC_PAGE_SIZE_64KB || PPC_64K_PAGES)
help
This driver allows the kernel to act as a Xen network driver
domain which exports paravirtual network devices to other
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index 068dc7cad5fa..47b34f7c4512 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -101,7 +101,6 @@
MODULE_AUTHOR("Advanced Micro Devices, Inc.");
MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version "MODULE_VERS);
MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl);
module_param_array(speed_duplex, int, NULL, 0);
MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotiate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex");
module_param_array(coalesce, bool, NULL, 0);
@@ -109,13 +108,6 @@ MODULE_PARM_DESC(coalesce, "Enable or Disable interrupt coalescing, 1: Enable, 0
module_param_array(dynamic_ipg, bool, NULL, 0);
MODULE_PARM_DESC(dynamic_ipg, "Enable or Disable dynamic IPG, 1: Enable, 0: Disable");
-static DEFINE_PCI_DEVICE_TABLE(amd8111e_pci_tbl) = {
-
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD8111E_7462,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
- { 0, }
-
-};
/*
This function will read the PHY registers.
*/
@@ -1970,6 +1962,17 @@ static int amd8111e_probe_one(struct pci_dev *pdev,
}
+static const struct pci_device_id amd8111e_pci_tbl[] = {
+ {
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD8111E_7462,
+ },
+ {
+ .vendor = 0,
+ }
+};
+MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl);
+
static struct pci_driver amd8111e_driver = {
.name = MODULE_NAME,
.id_table = amd8111e_pci_tbl,
diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c
index abf3b1581c82..27245efe9f50 100644
--- a/drivers/net/ethernet/amd/nmclan_cs.c
+++ b/drivers/net/ethernet/amd/nmclan_cs.c
@@ -621,7 +621,7 @@ static int nmclan_config(struct pcmcia_device *link)
ret = pcmcia_request_io(link);
if (ret)
goto failed;
- ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
+ ret = pcmcia_request_irq(link, mace_interrupt);
if (ret)
goto failed;
ret = pcmcia_enable_device(link);
@@ -952,6 +952,8 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
do {
/* WARNING: MACE_IR is a READ/CLEAR port! */
status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
+ if (!(status & ~MACE_IMR_DEFAULT) && IntrCnt == MACE_MAX_IR_ITERATIONS)
+ return IRQ_NONE;
pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index ca5a20a48b14..0a89c66c0264 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -2372,6 +2372,7 @@ static int b44_init_one(struct ssb_device *sdev,
bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
spin_lock_init(&bp->lock);
+ u64_stats_init(&bp->hw_stats.syncp);
bp->rx_pending = B44_DEF_RX_RING_PENDING;
bp->tx_pending = B44_DEF_TX_RING_PENDING;
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 4d762138eb39..c2b5d3b74c5f 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -386,7 +386,7 @@ static void bcm_sysport_get_stats(struct net_device *dev,
static void bcm_sysport_free_cb(struct bcm_sysport_cb *cb)
{
- dev_kfree_skb_any(cb->skb);
+ dev_consume_skb_any(cb->skb);
cb->skb = NULL;
dma_unmap_addr_set(cb, dma_addr, 0);
}
@@ -1024,6 +1024,8 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
ring->cbs = kzalloc(sizeof(struct bcm_sysport_cb) * size, GFP_KERNEL);
if (!ring->cbs) {
+ dma_free_coherent(kdev, sizeof(struct dma_desc),
+ ring->desc_cpu, ring->desc_dma);
netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
return -ENOMEM;
}
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 18ef92e2d5dd..f22654e2060d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -900,12 +900,21 @@ static struct enet_cb *bcmgenet_get_txcb(struct bcmgenet_priv *priv,
return tx_cb_ptr;
}
-/* Simple helper to free a control block's resources */
-static void bcmgenet_free_cb(struct enet_cb *cb)
+static struct enet_cb *bcmgenet_put_txcb(struct bcmgenet_priv *priv,
+ struct bcmgenet_tx_ring *ring)
{
- dev_kfree_skb_any(cb->skb);
- cb->skb = NULL;
- dma_unmap_addr_set(cb, dma_addr, 0);
+ struct enet_cb *tx_cb_ptr;
+
+ tx_cb_ptr = ring->cbs;
+ tx_cb_ptr += ring->write_ptr - ring->cb_ptr;
+
+ /* Rewinding local write pointer */
+ if (ring->write_ptr == ring->cb_ptr)
+ ring->write_ptr = ring->end_ptr;
+ else
+ ring->write_ptr--;
+
+ return tx_cb_ptr;
}
static inline void bcmgenet_tx_ring16_int_disable(struct bcmgenet_priv *priv,
@@ -940,69 +949,116 @@ static inline void bcmgenet_tx_ring_int_disable(struct bcmgenet_priv *priv,
priv->int1_mask |= (1 << ring->index);
}
+/* Simple helper to free a transmit control block's resources
+ * Returns an skb when the last transmit control block associated with the
+ * skb is freed. The skb should be freed by the caller if necessary.
+ */
+static struct sk_buff *bcmgenet_free_tx_cb(struct device *dev,
+ struct enet_cb *cb)
+{
+ struct sk_buff *skb;
+
+ skb = cb->skb;
+
+ if (skb) {
+ cb->skb = NULL;
+ if (cb == GENET_CB(skb)->first_cb)
+ dma_unmap_single(dev, dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len),
+ DMA_TO_DEVICE);
+ else
+ dma_unmap_page(dev, dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len),
+ DMA_TO_DEVICE);
+ dma_unmap_addr_set(cb, dma_addr, 0);
+
+ if (cb == GENET_CB(skb)->last_cb)
+ return skb;
+
+ } else if (dma_unmap_addr(cb, dma_addr)) {
+ dma_unmap_page(dev,
+ dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len),
+ DMA_TO_DEVICE);
+ dma_unmap_addr_set(cb, dma_addr, 0);
+ }
+
+ return 0;
+}
+
+/* Simple helper to free a receive control block's resources */
+static struct sk_buff *bcmgenet_free_rx_cb(struct device *dev,
+ struct enet_cb *cb)
+{
+ struct sk_buff *skb;
+
+ skb = cb->skb;
+ cb->skb = NULL;
+
+ if (dma_unmap_addr(cb, dma_addr)) {
+ dma_unmap_single(dev, dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len), DMA_FROM_DEVICE);
+ dma_unmap_addr_set(cb, dma_addr, 0);
+ }
+
+ return skb;
+}
+
/* Unlocked version of the reclaim routine */
static void __bcmgenet_tx_reclaim(struct net_device *dev,
struct bcmgenet_tx_ring *ring)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
- struct device *kdev = &priv->pdev->dev;
- int last_tx_cn, last_c_index, num_tx_bds;
- struct enet_cb *tx_cb_ptr;
struct netdev_queue *txq;
+ unsigned int txbds_processed = 0;
+ unsigned int bytes_compl = 0;
+ unsigned int pkts_compl = 0;
+ unsigned int txbds_ready;
unsigned int c_index;
+ struct sk_buff *skb;
/* Compute how many buffers are transmited since last xmit call */
c_index = bcmgenet_tdma_ring_readl(priv, ring->index, TDMA_CONS_INDEX);
- txq = netdev_get_tx_queue(dev, ring->queue);
-
- last_c_index = ring->c_index;
- num_tx_bds = ring->size;
-
- c_index &= (num_tx_bds - 1);
+ c_index &= DMA_C_INDEX_MASK;
- if (c_index >= last_c_index)
- last_tx_cn = c_index - last_c_index;
+ if (likely(c_index >= ring->c_index))
+ txbds_ready = c_index - ring->c_index;
else
- last_tx_cn = num_tx_bds - last_c_index + c_index;
+ txbds_ready = (DMA_C_INDEX_MASK + 1) - ring->c_index + c_index;
netif_dbg(priv, tx_done, dev,
- "%s ring=%d index=%d last_tx_cn=%d last_index=%d\n",
- __func__, ring->index,
- c_index, last_tx_cn, last_c_index);
+ "%s ring=%d old_c_index=%u c_index=%u txbds_ready=%u\n",
+ __func__, ring->index, ring->c_index, c_index, txbds_ready);
/* Reclaim transmitted buffers */
- while (last_tx_cn-- > 0) {
- tx_cb_ptr = ring->cbs + last_c_index;
- if (tx_cb_ptr->skb) {
- dev->stats.tx_bytes += tx_cb_ptr->skb->len;
- dma_unmap_single(kdev,
- dma_unmap_addr(tx_cb_ptr, dma_addr),
- dma_unmap_len(tx_cb_ptr, dma_len),
- DMA_TO_DEVICE);
- bcmgenet_free_cb(tx_cb_ptr);
- } else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
- dev->stats.tx_bytes +=
- dma_unmap_len(tx_cb_ptr, dma_len);
- dma_unmap_page(kdev,
- dma_unmap_addr(tx_cb_ptr, dma_addr),
- dma_unmap_len(tx_cb_ptr, dma_len),
- DMA_TO_DEVICE);
- dma_unmap_addr_set(tx_cb_ptr, dma_addr, 0);
+ while (txbds_processed < txbds_ready) {
+ skb = bcmgenet_free_tx_cb(&priv->pdev->dev,
+ &priv->tx_cbs[ring->clean_ptr]);
+ if (skb) {
+ pkts_compl++;
+ bytes_compl += GENET_CB(skb)->bytes_sent;
+ dev_consume_skb_any(skb);
}
- dev->stats.tx_packets++;
- ring->free_bds += 1;
- last_c_index++;
- last_c_index &= (num_tx_bds - 1);
+ txbds_processed++;
+ if (likely(ring->clean_ptr < ring->end_ptr))
+ ring->clean_ptr++;
+ else
+ ring->clean_ptr = ring->cb_ptr;
}
+ ring->free_bds += txbds_processed;
+ ring->c_index = (ring->c_index + txbds_processed) & DMA_C_INDEX_MASK;
+
+ dev->stats.tx_packets += pkts_compl;
+ dev->stats.tx_bytes += bytes_compl;
+
if (ring->free_bds > (MAX_SKB_FRAGS + 1))
ring->int_disable(priv, ring);
+ txq = netdev_get_tx_queue(dev, ring->queue);
if (netif_tx_queue_stopped(txq))
netif_tx_wake_queue(txq);
-
- ring->c_index = c_index;
}
static void bcmgenet_tx_reclaim(struct net_device *dev,
@@ -1028,100 +1084,6 @@ static void bcmgenet_tx_reclaim_all(struct net_device *dev)
bcmgenet_tx_reclaim(dev, &priv->tx_rings[DESC_INDEX]);
}
-/* Transmits a single SKB (either head of a fragment or a single SKB)
- * caller must hold priv->lock
- */
-static int bcmgenet_xmit_single(struct net_device *dev,
- struct sk_buff *skb,
- u16 dma_desc_flags,
- struct bcmgenet_tx_ring *ring)
-{
- struct bcmgenet_priv *priv = netdev_priv(dev);
- struct device *kdev = &priv->pdev->dev;
- struct enet_cb *tx_cb_ptr;
- unsigned int skb_len;
- dma_addr_t mapping;
- u32 length_status;
- int ret;
-
- tx_cb_ptr = bcmgenet_get_txcb(priv, ring);
-
- if (unlikely(!tx_cb_ptr))
- BUG();
-
- tx_cb_ptr->skb = skb;
-
- skb_len = skb_headlen(skb);
-
- mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE);
- ret = dma_mapping_error(kdev, mapping);
- if (ret) {
- netif_err(priv, tx_err, dev, "Tx DMA map failed\n");
- dev_kfree_skb(skb);
- return ret;
- }
-
- dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping);
- dma_unmap_len_set(tx_cb_ptr, dma_len, skb_len);
- length_status = (skb_len << DMA_BUFLENGTH_SHIFT) | dma_desc_flags |
- (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT) |
- DMA_TX_APPEND_CRC;
-
- if (skb->ip_summed == CHECKSUM_PARTIAL)
- length_status |= DMA_TX_DO_CSUM;
-
- dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping, length_status);
-
- /* Decrement total BD count and advance our write pointer */
- ring->free_bds -= 1;
- ring->prod_index += 1;
- ring->prod_index &= DMA_P_INDEX_MASK;
-
- return 0;
-}
-
-/* Transmit a SKB fragement */
-static int bcmgenet_xmit_frag(struct net_device *dev,
- skb_frag_t *frag,
- u16 dma_desc_flags,
- struct bcmgenet_tx_ring *ring)
-{
- struct bcmgenet_priv *priv = netdev_priv(dev);
- struct device *kdev = &priv->pdev->dev;
- struct enet_cb *tx_cb_ptr;
- dma_addr_t mapping;
- int ret;
-
- tx_cb_ptr = bcmgenet_get_txcb(priv, ring);
-
- if (unlikely(!tx_cb_ptr))
- BUG();
- tx_cb_ptr->skb = NULL;
-
- mapping = skb_frag_dma_map(kdev, frag, 0,
- skb_frag_size(frag), DMA_TO_DEVICE);
- ret = dma_mapping_error(kdev, mapping);
- if (ret) {
- netif_err(priv, tx_err, dev, "%s: Tx DMA map failed\n",
- __func__);
- return ret;
- }
-
- dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping);
- dma_unmap_len_set(tx_cb_ptr, dma_len, frag->size);
-
- dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping,
- (frag->size << DMA_BUFLENGTH_SHIFT) | dma_desc_flags |
- (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT));
-
-
- ring->free_bds -= 1;
- ring->prod_index += 1;
- ring->prod_index &= DMA_P_INDEX_MASK;
-
- return 0;
-}
-
/* Reallocate the SKB to put enough headroom in front of it and insert
* the transmit checksum offsets in the descriptors
*/
@@ -1187,11 +1149,16 @@ static int bcmgenet_put_tx_csum(struct net_device *dev, struct sk_buff *skb)
static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
+ struct device *kdev = &priv->pdev->dev;
struct bcmgenet_tx_ring *ring = NULL;
+ struct enet_cb *tx_cb_ptr;
struct netdev_queue *txq;
unsigned long flags = 0;
int nr_frags, index;
- u16 dma_desc_flags;
+ dma_addr_t mapping;
+ unsigned int size;
+ skb_frag_t *frag;
+ u32 len_stat;
int ret;
int i;
@@ -1226,6 +1193,11 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
+ /* Retain how many bytes will be sent on the wire, without TSB inserted
+ * by transmit checksum offload
+ */
+ GENET_CB(skb)->bytes_sent = skb->len;
+
/* set the SKB transmit checksum */
if (priv->desc_64b_en) {
ret = bcmgenet_put_tx_csum(dev, skb);
@@ -1235,33 +1207,59 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
- dma_desc_flags = DMA_SOP;
- if (nr_frags == 0)
- dma_desc_flags |= DMA_EOP;
+ for (i = 0; i <= nr_frags; i++) {
+ tx_cb_ptr = bcmgenet_get_txcb(priv, ring);
- /* Transmit single SKB or head of fragment list */
- ret = bcmgenet_xmit_single(dev, skb, dma_desc_flags, ring);
- if (ret) {
- ret = NETDEV_TX_OK;
- goto out;
- }
+ if (unlikely(!tx_cb_ptr))
+ BUG();
- /* xmit fragment */
- for (i = 0; i < nr_frags; i++) {
- ret = bcmgenet_xmit_frag(dev,
- &skb_shinfo(skb)->frags[i],
- (i == nr_frags - 1) ? DMA_EOP : 0, ring);
+ if (!i) {
+ /* Transmit single SKB or head of fragment list */
+ GENET_CB(skb)->first_cb = tx_cb_ptr;
+ size = skb_headlen(skb);
+ mapping = dma_map_single(kdev, skb->data, size,
+ DMA_TO_DEVICE);
+ } else {
+ /* xmit fragment */
+ frag = &skb_shinfo(skb)->frags[i - 1];
+ size = skb_frag_size(frag);
+ mapping = skb_frag_dma_map(kdev, frag, 0, size,
+ DMA_TO_DEVICE);
+ }
+
+ ret = dma_mapping_error(kdev, mapping);
if (ret) {
+ netif_err(priv, tx_err, dev, "Tx DMA map failed\n");
ret = NETDEV_TX_OK;
- goto out;
+ goto out_unmap_frags;
+ }
+ dma_unmap_addr_set(tx_cb_ptr, dma_addr, mapping);
+ dma_unmap_len_set(tx_cb_ptr, dma_len, size);
+
+ tx_cb_ptr->skb = skb;
+
+ len_stat = (size << DMA_BUFLENGTH_SHIFT) |
+ (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT);
+
+ if (!i) {
+ len_stat |= DMA_TX_APPEND_CRC | DMA_SOP;
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ len_stat |= DMA_TX_DO_CSUM;
}
+ if (i == nr_frags)
+ len_stat |= DMA_EOP;
+
+ dmadesc_set(priv, tx_cb_ptr->bd_addr, mapping, len_stat);
}
+ GENET_CB(skb)->last_cb = tx_cb_ptr;
skb_tx_timestamp(skb);
- /* we kept a software copy of how much we should advance the TDMA
- * producer index, now write it down to the hardware
- */
+ /* Decrement total BD count and advance our write pointer */
+ ring->free_bds -= nr_frags + 1;
+ ring->prod_index += nr_frags + 1;
+ ring->prod_index &= DMA_P_INDEX_MASK;
+
bcmgenet_tdma_ring_writel(priv, ring->index,
ring->prod_index, TDMA_PROD_INDEX);
@@ -1274,36 +1272,55 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&ring->lock, flags);
return ret;
-}
+out_unmap_frags:
+ /* Back up for failed control block mapping */
+ bcmgenet_put_txcb(priv, ring);
+
+ /* Unmap successfully mapped control blocks */
+ while (i-- > 0) {
+ tx_cb_ptr = bcmgenet_put_txcb(priv, ring);
+ bcmgenet_free_tx_cb(kdev, tx_cb_ptr);
+ }
-static int bcmgenet_rx_refill(struct bcmgenet_priv *priv,
- struct enet_cb *cb)
+ dev_kfree_skb(skb);
+ goto out;
+}
+
+static struct sk_buff *bcmgenet_rx_refill(struct bcmgenet_priv *priv,
+ struct enet_cb *cb)
{
struct device *kdev = &priv->pdev->dev;
struct sk_buff *skb;
+ struct sk_buff *rx_skb;
dma_addr_t mapping;
- int ret;
+ /* Allocate a new Rx skb */
skb = netdev_alloc_skb(priv->dev,
priv->rx_buf_len + SKB_ALIGNMENT);
- if (!skb)
- return -ENOMEM;
+ if (!skb) {
+ netif_err(priv, rx_err, priv->dev,
+ "%s: Rx skb allocation failed\n", __func__);
+ return NULL;
+ }
- /* a caller did not release this control block */
- WARN_ON(cb->skb != NULL);
- cb->skb = skb;
- mapping = dma_map_single(kdev, skb->data,
- priv->rx_buf_len, DMA_FROM_DEVICE);
- ret = dma_mapping_error(kdev, mapping);
- if (ret) {
- bcmgenet_free_cb(cb);
+ /* DMA-map the new Rx skb */
+ mapping = dma_map_single(kdev, skb->data, priv->rx_buf_len,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(kdev, mapping)) {
+ dev_kfree_skb_any(skb);
netif_err(priv, rx_err, priv->dev,
- "%s DMA map failed\n", __func__);
- return ret;
+ "%s: Rx skb DMA mapping failed\n", __func__);
+ return NULL;
}
+ /* Grab the current Rx skb from the ring and DMA-unmap it */
+ rx_skb = bcmgenet_free_rx_cb(kdev, cb);
+
+ /* Put the new Rx skb on the ring */
+ cb->skb = skb;
dma_unmap_addr_set(cb, dma_addr, mapping);
+ dma_unmap_len_set(cb, dma_len, priv->rx_buf_len);
/* assign packet, prepare descriptor, and advance pointer */
dmadesc_set_addr(priv, priv->rx_bd_assign_ptr, mapping);
@@ -1315,7 +1332,8 @@ static int bcmgenet_rx_refill(struct bcmgenet_priv *priv,
priv->rx_bd_assign_ptr = priv->rx_bds +
(priv->rx_bd_assign_index * DMA_DESC_SIZE);
- return 0;
+ /* Return the current Rx skb to caller */
+ return rx_skb;
}
/* bcmgenet_desc_rx - descriptor based rx process.
@@ -1330,7 +1348,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
struct sk_buff *skb;
u32 dma_length_status;
unsigned long dma_flag;
- int len, err;
+ int len;
unsigned int rxpktprocessed = 0, rxpkttoprocess;
unsigned int p_index;
unsigned int chksum_ok = 0;
@@ -1351,14 +1369,14 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
while ((rxpktprocessed < rxpkttoprocess) &&
(rxpktprocessed < budget)) {
- /* Unmap the packet contents such that we can use the
- * RSV from the 64 bytes descriptor when enabled and save
- * a 32-bits register read
- */
cb = &priv->rx_cbs[priv->rx_read_ptr];
- skb = cb->skb;
- dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr),
- priv->rx_buf_len, DMA_FROM_DEVICE);
+ skb = bcmgenet_rx_refill(priv, cb);
+
+ if (unlikely(!skb)) {
+ dev->stats.rx_dropped++;
+ dev->stats.rx_errors++;
+ goto next;
+ }
if (!priv->desc_64b_en) {
dma_length_status = dmadesc_get_length_status(priv,
@@ -1382,27 +1400,15 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
__func__, p_index, priv->rx_c_index, priv->rx_read_ptr,
dma_length_status);
- rxpktprocessed++;
-
- priv->rx_read_ptr++;
- priv->rx_read_ptr &= (priv->num_rx_bds - 1);
-
- /* out of memory, just drop packets at the hardware level */
- if (unlikely(!skb)) {
- dev->stats.rx_dropped++;
- dev->stats.rx_errors++;
- goto refill;
- }
-
if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
netif_err(priv, rx_status, dev,
"Droping fragmented packet!\n");
dev->stats.rx_dropped++;
dev->stats.rx_errors++;
- dev_kfree_skb_any(cb->skb);
- cb->skb = NULL;
- goto refill;
+ dev_kfree_skb_any(skb);
+ goto next;
}
+
/* report errors */
if (unlikely(dma_flag & (DMA_RX_CRC_ERROR |
DMA_RX_OV |
@@ -1421,11 +1427,8 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
dev->stats.rx_length_errors++;
dev->stats.rx_dropped++;
dev->stats.rx_errors++;
-
- /* discard the packet and advance consumer index.*/
- dev_kfree_skb_any(cb->skb);
- cb->skb = NULL;
- goto refill;
+ dev_kfree_skb_any(skb);
+ goto next;
} /* error packet */
chksum_ok = (dma_flag & priv->dma_rx_chk_bit) &&
@@ -1458,14 +1461,12 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
/* Notify kernel */
napi_gro_receive(&priv->napi, skb);
- cb->skb = NULL;
netif_dbg(priv, rx_status, dev, "pushed up to kernel\n");
- /* refill RX path on the current control block */
-refill:
- err = bcmgenet_rx_refill(priv, cb);
- if (err)
- netif_err(priv, rx_err, dev, "Rx refill failed\n");
+next:
+ rxpktprocessed++;
+ priv->rx_read_ptr++;
+ priv->rx_read_ptr &= (priv->num_rx_bds - 1);
}
return rxpktprocessed;
@@ -1475,7 +1476,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_priv *priv,
static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv)
{
struct enet_cb *cb;
- int ret = 0;
+ struct sk_buff *skb;
int i;
netif_dbg(priv, hw, priv->dev, "%s:\n", __func__);
@@ -1483,36 +1484,28 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv)
/* loop here for each buffer needing assign */
for (i = 0; i < priv->num_rx_bds; i++) {
cb = &priv->rx_cbs[priv->rx_bd_assign_index];
- if (cb->skb)
- continue;
-
- ret = bcmgenet_rx_refill(priv, cb);
- if (ret)
- break;
-
+ skb = bcmgenet_rx_refill(priv, cb);
+ if (skb)
+ dev_consume_skb_any(skb);
+ if (!cb->skb)
+ return -ENOMEM;
}
- return ret;
+ return 0;
}
static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
{
- struct device *kdev = &priv->pdev->dev;
+ struct sk_buff *skb;
struct enet_cb *cb;
int i;
for (i = 0; i < priv->num_rx_bds; i++) {
cb = &priv->rx_cbs[i];
- if (dma_unmap_addr(cb, dma_addr)) {
- dma_unmap_single(kdev,
- dma_unmap_addr(cb, dma_addr),
- priv->rx_buf_len, DMA_FROM_DEVICE);
- dma_unmap_addr_set(cb, dma_addr, 0);
- }
-
- if (cb->skb)
- bcmgenet_free_cb(cb);
+ skb = bcmgenet_free_rx_cb(&priv->pdev->dev, cb);
+ if (skb)
+ dev_consume_skb_any(skb);
}
}
@@ -1640,6 +1633,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
}
ring->cbs = priv->tx_cbs + write_ptr;
ring->size = size;
+ ring->clean_ptr = write_ptr;
ring->c_index = 0;
ring->free_bds = size;
ring->write_ptr = write_ptr;
@@ -1788,6 +1782,8 @@ static void bcmgenet_init_multiq(struct net_device *dev)
static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
{
+ struct sk_buff *skb;
+ struct enet_cb *cb;
int i;
/* disable DMA */
@@ -1795,10 +1791,10 @@ static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
bcmgenet_tdma_writel(priv, 0, DMA_CTRL);
for (i = 0; i < priv->num_tx_bds; i++) {
- if (priv->tx_cbs[i].skb != NULL) {
- dev_kfree_skb(priv->tx_cbs[i].skb);
- priv->tx_cbs[i].skb = NULL;
- }
+ cb = priv->tx_cbs + i;
+ skb = bcmgenet_free_tx_cb(&priv->pdev->dev, cb);
+ if (skb)
+ dev_kfree_skb(skb);
}
bcmgenet_free_rx_buffers(priv);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 2317e3725859..2e1e2180690f 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -504,12 +504,21 @@ struct bcmgenet_hw_params {
u32 flags;
};
+struct bcmgenet_skb_cb {
+ struct enet_cb *first_cb; /* First control block of SKB */
+ struct enet_cb *last_cb; /* Last control block of SKB */
+ unsigned int bytes_sent; /* bytes on the wire (no TSB) */
+};
+
+#define GENET_CB(skb) ((struct bcmgenet_skb_cb *)((skb)->cb))
+
struct bcmgenet_tx_ring {
spinlock_t lock; /* ring lock */
unsigned int index; /* ring index */
unsigned int queue; /* queue index */
struct enet_cb *cbs; /* tx ring buffer control block*/
unsigned int size; /* size of each tx ring */
+ unsigned int clean_ptr; /* Tx ring clean pointer */
unsigned int c_index; /* last consumer index of each ring*/
unsigned int free_bds; /* # of free bds for each ring */
unsigned int write_ptr; /* Tx ring write pointer SW copy */
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index 861660841ce2..eab3142bd795 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -98,8 +98,7 @@ static int csr0 = 0x01A00000 | 0x4800;
#elif defined(__mips__)
static int csr0 = 0x00200000 | 0x4000;
#else
-#warning Processor architecture undefined!
-static int csr0 = 0x00A00000 | 0x4800;
+static int csr0;
#endif
/* Operational parameters that usually are not changed. */
@@ -1982,6 +1981,12 @@ static int __init tulip_init (void)
pr_info("%s", version);
#endif
+ if (!csr0) {
+ pr_warn("tulip: unknown CPU architecture, using default csr0\n");
+ /* default to 8 longword cache line alignment */
+ csr0 = 0x00A00000 | 0x4800;
+ }
+
/* copy module parms into globals */
tulip_rx_copybreak = rx_copybreak;
tulip_max_interrupt_work = max_interrupt_work;
diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c
index 80afec335a11..f6b8edf6516e 100644
--- a/drivers/net/ethernet/dec/tulip/uli526x.c
+++ b/drivers/net/ethernet/dec/tulip/uli526x.c
@@ -1115,7 +1115,7 @@ static void uli526x_timer(unsigned long data)
netif_carrier_off(dev);
}
}
- db->init=0;
+ db->init = 0;
/* Timer active again */
db->timer.expires = ULI526X_TIMER_WUT;
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c
index 62fe512bb216..345f2fe8755c 100644
--- a/drivers/net/ethernet/dec/tulip/winbond-840.c
+++ b/drivers/net/ethernet/dec/tulip/winbond-840.c
@@ -907,7 +907,7 @@ static void init_registers(struct net_device *dev)
#elif defined(CONFIG_SPARC) || defined (CONFIG_PARISC)
i |= 0x4800;
#else
-#warning Processor architecture undefined
+ dev_warn(&dev->dev, "unknown CPU architecture, using default csr0 setting\n");
i |= 0x4800;
#endif
iowrite32(i, ioaddr + PCIBusCfg);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 1e187fb760f8..7329ab75afb5 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -26,7 +26,6 @@
#include <net/vxlan.h>
MODULE_VERSION(DRV_VER);
-MODULE_DEVICE_TABLE(pci, be_dev_ids);
MODULE_DESCRIPTION(DRV_DESC " " DRV_VER);
MODULE_AUTHOR("Emulex Corporation");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 060c5510b0c4..05e42d3d8a63 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -984,7 +984,7 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link)
u16 max_snoop, max_nosnoop;
u16 max_ltr_enc; /* max LTR latency encoded */
s64 lat_ns; /* latency (ns) */
- s64 value;
+ u64 value;
u32 rxa;
if (!hw->adapter->max_frame_size) {
@@ -1011,12 +1011,13 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link)
*/
lat_ns = ((s64)rxa * 1024 -
(2 * (s64)hw->adapter->max_frame_size)) * 8 * 1000;
- if (lat_ns < 0)
- lat_ns = 0;
- else
- do_div(lat_ns, speed);
+ if (lat_ns < 0) {
+ value = 0;
+ } else {
+ value = lat_ns;
+ do_div(value, speed);
+ }
- value = lat_ns;
while (value > PCI_LTR_VALUE_MASK) {
scale++;
value = DIV_ROUND_UP(value, (1 << 5));
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
index cffdfc21290f..decf6faaa89d 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -754,7 +754,7 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
{
struct i40e_tx_desc *txd;
union i40e_rx_desc *rxd;
- struct i40e_ring ring;
+ struct i40e_ring *ring;
struct i40e_vsi *vsi;
int i;
@@ -773,29 +773,32 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
vsi_seid);
return;
}
- if (is_rx_ring)
- ring = *vsi->rx_rings[ring_id];
- else
- ring = *vsi->tx_rings[ring_id];
+
+ ring = kmemdup(is_rx_ring
+ ? vsi->rx_rings[ring_id] : vsi->tx_rings[ring_id],
+ sizeof(*ring), GFP_KERNEL);
+ if (!ring)
+ return;
+
if (cnt == 2) {
dev_info(&pf->pdev->dev, "vsi = %02i %s ring = %02i\n",
vsi_seid, is_rx_ring ? "rx" : "tx", ring_id);
- for (i = 0; i < ring.count; i++) {
+ for (i = 0; i < ring->count; i++) {
if (!is_rx_ring) {
- txd = I40E_TX_DESC(&ring, i);
+ txd = I40E_TX_DESC(ring, i);
dev_info(&pf->pdev->dev,
" d[%03i] = 0x%016llx 0x%016llx\n",
i, txd->buffer_addr,
txd->cmd_type_offset_bsz);
} else if (sizeof(union i40e_rx_desc) ==
sizeof(union i40e_16byte_rx_desc)) {
- rxd = I40E_RX_DESC(&ring, i);
+ rxd = I40E_RX_DESC(ring, i);
dev_info(&pf->pdev->dev,
" d[%03i] = 0x%016llx 0x%016llx\n",
i, rxd->read.pkt_addr,
rxd->read.hdr_addr);
} else {
- rxd = I40E_RX_DESC(&ring, i);
+ rxd = I40E_RX_DESC(ring, i);
dev_info(&pf->pdev->dev,
" d[%03i] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
i, rxd->read.pkt_addr,
@@ -804,26 +807,26 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
}
}
} else if (cnt == 3) {
- if (desc_n >= ring.count || desc_n < 0) {
+ if (desc_n >= ring->count || desc_n < 0) {
dev_info(&pf->pdev->dev,
"descriptor %d not found\n", desc_n);
return;
}
if (!is_rx_ring) {
- txd = I40E_TX_DESC(&ring, desc_n);
+ txd = I40E_TX_DESC(ring, desc_n);
dev_info(&pf->pdev->dev,
"vsi = %02i tx ring = %02i d[%03i] = 0x%016llx 0x%016llx\n",
vsi_seid, ring_id, desc_n,
txd->buffer_addr, txd->cmd_type_offset_bsz);
} else if (sizeof(union i40e_rx_desc) ==
sizeof(union i40e_16byte_rx_desc)) {
- rxd = I40E_RX_DESC(&ring, desc_n);
+ rxd = I40E_RX_DESC(ring, desc_n);
dev_info(&pf->pdev->dev,
"vsi = %02i rx ring = %02i d[%03i] = 0x%016llx 0x%016llx\n",
vsi_seid, ring_id, desc_n,
rxd->read.pkt_addr, rxd->read.hdr_addr);
} else {
- rxd = I40E_RX_DESC(&ring, desc_n);
+ rxd = I40E_RX_DESC(ring, desc_n);
dev_info(&pf->pdev->dev,
"vsi = %02i rx ring = %02i d[%03i] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
vsi_seid, ring_id, desc_n,
@@ -833,6 +836,7 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
} else {
dev_info(&pf->pdev->dev, "dump desc rx/tx <vsi_seid> <ring_id> [<desc_n>]\n");
}
+ kfree(ring);
}
/**
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index e49f31dbd5d8..7b1be746dd30 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -914,6 +914,8 @@ int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring)
if (!tx_ring->tx_bi)
goto err;
+ u64_stats_init(&tx_ring->syncp);
+
/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(struct i40e_tx_desc);
/* add u32 for head writeback, align after this takes care of
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 75467f83772c..e626b73ca00e 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -2535,6 +2535,8 @@ int ixgbevf_setup_tx_resources(struct ixgbevf_ring *tx_ring)
if (!tx_ring->tx_buffer_info)
goto err;
+ u64_stats_init(&tx_ring->syncp);
+
/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
@@ -2595,6 +2597,8 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_ring *rx_ring)
if (!rx_ring->rx_buffer_info)
goto err;
+ u64_stats_init(&rx_ring->syncp);
+
/* Round up to nearest 4K */
rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
rx_ring->size = ALIGN(rx_ring->size, 4096);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 68d763d2d030..f07b814d717c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -142,6 +142,7 @@ static void mlx4_en_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
struct mlx4_en_priv *priv = netdev_priv(netdev);
+ struct mlx4_caps *caps = &priv->mdev->dev->caps;
int err = 0;
u64 config = 0;
u64 mask;
@@ -154,24 +155,24 @@ static void mlx4_en_get_wol(struct net_device *netdev,
mask = (priv->port == 1) ? MLX4_DEV_CAP_FLAG_WOL_PORT1 :
MLX4_DEV_CAP_FLAG_WOL_PORT2;
- if (!(priv->mdev->dev->caps.flags & mask)) {
+ if (!(caps->flags & mask)) {
wol->supported = 0;
wol->wolopts = 0;
return;
}
+ if (caps->wol_port[priv->port])
+ wol->supported = WAKE_MAGIC;
+ else
+ wol->supported = 0;
+
err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);
if (err) {
en_err(priv, "Failed to get WoL information\n");
return;
}
- if (config & MLX4_EN_WOL_MAGIC)
- wol->supported = WAKE_MAGIC;
- else
- wol->supported = 0;
-
- if (config & MLX4_EN_WOL_ENABLED)
+ if ((config & MLX4_EN_WOL_ENABLED) && (config & MLX4_EN_WOL_MAGIC))
wol->wolopts = WAKE_MAGIC;
else
wol->wolopts = 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 1006e770c109..e2bdd5626fe2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1535,17 +1535,13 @@ static int mlx4_en_init_affinity_hint(struct mlx4_en_priv *priv, int ring_idx)
{
struct mlx4_en_rx_ring *ring = priv->rx_ring[ring_idx];
int numa_node = priv->mdev->dev->numa_node;
- int ret = 0;
if (!zalloc_cpumask_var(&ring->affinity_mask, GFP_KERNEL))
return -ENOMEM;
- ret = cpumask_set_cpu_local_first(ring_idx, numa_node,
- ring->affinity_mask);
- if (ret)
- free_cpumask_var(ring->affinity_mask);
-
- return ret;
+ cpumask_set_cpu(cpumask_local_spread(ring_idx, numa_node),
+ ring->affinity_mask);
+ return 0;
}
static void mlx4_en_free_affinity_hint(struct mlx4_en_priv *priv, int ring_idx)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index c5be6d890e94..a3d86e31f34c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -133,9 +133,9 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
ring->queue_index = queue_index;
if (queue_index < priv->num_tx_rings_p_up)
- cpumask_set_cpu_local_first(queue_index,
- priv->mdev->dev->numa_node,
- &ring->affinity_mask);
+ cpumask_set_cpu(cpumask_local_spread(queue_index,
+ priv->mdev->dev->numa_node),
+ &ring->affinity_mask);
*pring = ring;
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 688e1eabab29..781e590efe8e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -532,6 +532,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
#define QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET 0x3e
#define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f
#define QUERY_DEV_CAP_EXT_FLAGS_OFFSET 0x40
+#define QUERY_DEV_CAP_WOL_OFFSET 0x43
#define QUERY_DEV_CAP_FLAGS_OFFSET 0x44
#define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48
#define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49
@@ -658,6 +659,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
MLX4_GET(ext_flags, outbox, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
MLX4_GET(flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
dev_cap->flags = flags | (u64)ext_flags << 32;
+ MLX4_GET(field, outbox, QUERY_DEV_CAP_WOL_OFFSET);
+ dev_cap->wol_port[1] = !!(field & 0x20);
+ dev_cap->wol_port[2] = !!(field & 0x40);
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET);
dev_cap->reserved_uars = field >> 4;
MLX4_GET(field, outbox, QUERY_DEV_CAP_UAR_SZ_OFFSET);
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h
index 1fce03ebe5c4..d60c64bda8c2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.h
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.h
@@ -120,6 +120,7 @@ struct mlx4_dev_cap {
u8 log_max_macs[MLX4_MAX_PORTS + 1];
u8 log_max_vlans[MLX4_MAX_PORTS + 1];
u32 max_counters;
+ bool wol_port[MLX4_MAX_PORTS + 1];
};
struct mlx4_func_cap {
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index c1c21231f444..0996af50ad5b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -279,6 +279,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.stat_rate_support = dev_cap->stat_rate_support;
dev->caps.max_gso_sz = dev_cap->max_gso_sz;
dev->caps.max_rss_tbl_sz = dev_cap->max_rss_tbl_sz;
+ dev->caps.wol_port[1] = dev_cap->wol_port[1];
+ dev->caps.wol_port[2] = dev_cap->wol_port[2];
/* Sense port always allowed on supported devices for ConnectX-1 and -2 */
if (mlx4_priv(dev)->pci_dev_data & MLX4_PCI_DEV_FORCE_SENSE_PORT)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 3ee3dcedf74a..30fc1de78c0e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -547,6 +547,10 @@ static void cb_timeout_handler(struct work_struct *work)
mlx5_cmd_comp_handler(dev, 1UL << ent->idx);
}
+static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);
+static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,
+ struct mlx5_cmd_msg *msg);
+
static void cmd_work_handler(struct work_struct *work)
{
struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
@@ -555,16 +559,27 @@ static void cmd_work_handler(struct work_struct *work)
unsigned long cb_timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC);
struct mlx5_cmd_layout *lay;
struct semaphore *sem;
+ int alloc_ret;
sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
down(sem);
if (!ent->page_queue) {
- ent->idx = alloc_ent(cmd);
- if (ent->idx < 0) {
+ alloc_ret = alloc_ent(cmd);
+ if (alloc_ret < 0) {
mlx5_core_err(dev, "failed to allocate command entry\n");
+ if (ent->callback) {
+ ent->callback(-EAGAIN, ent->context);
+ mlx5_free_cmd_msg(dev, ent->out);
+ free_msg(dev, ent->in);
+ free_cmd(ent);
+ } else {
+ ent->ret = -EAGAIN;
+ complete(&ent->done);
+ }
up(sem);
return;
}
+ ent->idx = alloc_ret;
} else {
ent->idx = cmd->max_reg_cmds;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
index 10e1f1a18255..4878025e231c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c
@@ -300,11 +300,11 @@ static u64 qp_read_field(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp,
param = qp->pid;
break;
case QP_STATE:
- param = (u64)mlx5_qp_state_str(be32_to_cpu(ctx->flags) >> 28);
+ param = (unsigned long)mlx5_qp_state_str(be32_to_cpu(ctx->flags) >> 28);
*is_str = 1;
break;
case QP_XPORT:
- param = (u64)mlx5_qp_type_str((be32_to_cpu(ctx->flags) >> 16) & 0xff);
+ param = (unsigned long)mlx5_qp_type_str((be32_to_cpu(ctx->flags) >> 16) & 0xff);
*is_str = 1;
break;
case QP_MTU:
@@ -464,7 +464,7 @@ static ssize_t dbg_read(struct file *filp, char __user *buf, size_t count,
if (is_str)
- ret = snprintf(tbuf, sizeof(tbuf), "%s\n", (const char *)field);
+ ret = snprintf(tbuf, sizeof(tbuf), "%s\n", (const char *)(unsigned long)field);
else
ret = snprintf(tbuf, sizeof(tbuf), "0x%llx\n", field);
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
index 7a0deadd53bf..75682df75c89 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -2224,8 +2224,6 @@ static irqreturn_t vxge_isr_napi(int irq, void *dev_id)
return IRQ_NONE;
}
-#ifdef CONFIG_PCI_MSI
-
static irqreturn_t vxge_tx_msix_handle(int irq, void *dev_id)
{
struct vxge_fifo *fifo = (struct vxge_fifo *)dev_id;
@@ -2443,16 +2441,13 @@ static void vxge_rem_msix_isr(struct vxgedev *vdev)
if (vdev->config.intr_type == MSI_X)
pci_disable_msix(vdev->pdev);
}
-#endif
static void vxge_rem_isr(struct vxgedev *vdev)
{
-#ifdef CONFIG_PCI_MSI
- if (vdev->config.intr_type == MSI_X) {
+ if (IS_ENABLED(CONFIG_PCI_MSI) &&
+ vdev->config.intr_type == MSI_X) {
vxge_rem_msix_isr(vdev);
- } else
-#endif
- if (vdev->config.intr_type == INTA) {
+ } else if (vdev->config.intr_type == INTA) {
synchronize_irq(vdev->pdev->irq);
free_irq(vdev->pdev->irq, vdev);
}
@@ -2461,11 +2456,10 @@ static void vxge_rem_isr(struct vxgedev *vdev)
static int vxge_add_isr(struct vxgedev *vdev)
{
int ret = 0;
-#ifdef CONFIG_PCI_MSI
int vp_idx = 0, intr_idx = 0, intr_cnt = 0, msix_idx = 0, irq_req = 0;
int pci_fun = PCI_FUNC(vdev->pdev->devfn);
- if (vdev->config.intr_type == MSI_X)
+ if (IS_ENABLED(CONFIG_PCI_MSI) && vdev->config.intr_type == MSI_X)
ret = vxge_enable_msix(vdev);
if (ret) {
@@ -2476,7 +2470,7 @@ static int vxge_add_isr(struct vxgedev *vdev)
vdev->config.intr_type = INTA;
}
- if (vdev->config.intr_type == MSI_X) {
+ if (IS_ENABLED(CONFIG_PCI_MSI) && vdev->config.intr_type == MSI_X) {
for (intr_idx = 0;
intr_idx < (vdev->no_of_vpath *
VXGE_HW_VPATH_MSIX_ACTIVE); intr_idx++) {
@@ -2577,9 +2571,8 @@ static int vxge_add_isr(struct vxgedev *vdev)
vdev->vxge_entries[intr_cnt].in_use = 1;
vdev->vxge_entries[intr_cnt].arg = &vdev->vpaths[0];
}
-INTA_MODE:
-#endif
+INTA_MODE:
if (vdev->config.intr_type == INTA) {
snprintf(vdev->desc[0], VXGE_INTR_STRLEN,
"%s:vxge:INTA", vdev->ndev->name);
@@ -3890,12 +3883,12 @@ static void vxge_device_config_init(struct vxge_hw_device_config *device_config,
if (max_mac_vpath > VXGE_MAX_MAC_ADDR_COUNT)
max_mac_vpath = VXGE_MAX_MAC_ADDR_COUNT;
-#ifndef CONFIG_PCI_MSI
- vxge_debug_init(VXGE_ERR,
- "%s: This Kernel does not support "
- "MSI-X. Defaulting to INTA", VXGE_DRIVER_NAME);
- *intr_type = INTA;
-#endif
+ if (!IS_ENABLED(CONFIG_PCI_MSI)) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: This Kernel does not support "
+ "MSI-X. Defaulting to INTA", VXGE_DRIVER_NAME);
+ *intr_type = INTA;
+ }
/* Configure whether MSI-X or IRQL. */
switch (*intr_type) {
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
index db4280ce9c09..6adcd25e17df 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
@@ -2332,7 +2332,7 @@ netxen_md_rdqueue(struct netxen_adapter *adapter,
loop_cnt++) {
NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, queue_id);
read_addr = queueEntry->read_addr;
- for (k = 0; k < read_cnt; k--) {
+ for (k = 0; k < read_cnt; k++) {
NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0,
&read_value);
*data_buff++ = read_value;
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
index 829be21f97b2..be258d90de9e 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
@@ -724,7 +724,7 @@ static void ql_build_coredump_seg_header(
seg_hdr->cookie = MPI_COREDUMP_COOKIE;
seg_hdr->segNum = seg_number;
seg_hdr->segSize = seg_size;
- memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
+ strncpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
}
/*
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 61623e9af574..b1f22e199c3e 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5860,8 +5860,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
tp->TxDescArray + entry);
if (skb) {
- tp->dev->stats.tx_dropped++;
- dev_kfree_skb_any(skb);
+ dev_consume_skb_any(skb);
tx_skb->skb = NULL;
}
}
@@ -6169,7 +6168,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
tp->tx_stats.packets++;
tp->tx_stats.bytes += tx_skb->skb->len;
u64_stats_update_end(&tp->tx_stats.syncp);
- dev_kfree_skb_any(tx_skb->skb);
+ dev_consume_skb_any(tx_skb->skb);
tx_skb->skb = NULL;
}
dirty_tx++;
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index 7399a52f7c26..755ddd586189 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -543,7 +543,8 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- int queue, len;
+ int queue;
+ unsigned int len;
struct cpmac_desc *desc;
struct cpmac_priv *priv = netdev_priv(dev);
@@ -553,7 +554,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(skb_padto(skb, ETH_ZLEN)))
return NETDEV_TX_OK;
- len = max(skb->len, ETH_ZLEN);
+ len = max_t(unsigned int, skb->len, ETH_ZLEN);
queue = skb_get_queue_mapping(skb);
netif_stop_subqueue(dev, queue);
@@ -1226,7 +1227,7 @@ int cpmac_init(void)
goto fail_alloc;
}
-#warning FIXME: unhardcode gpio&reset bits
+ /* FIXME: unhardcode gpio&reset bits */
ar7_gpio_disable(26);
ar7_gpio_disable(27);
ar7_device_reset(AR7_RESET_BIT_CPMAC_LO);
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 4ef818a7a6c6..8a6e5c2d6f95 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -72,7 +72,7 @@ void temac_iow(struct temac_local *lp, int offset, u32 value)
int temac_indirect_busywait(struct temac_local *lp)
{
- long end = jiffies + 2;
+ unsigned long end = jiffies + 2;
while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) {
if (time_before_eq(end, jiffies)) {
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
index d4abf478e2bb..3b67d60d4378 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
@@ -19,7 +19,7 @@
/* Wait till MDIO interface is ready to accept a new transaction.*/
int axienet_mdio_wait_until_ready(struct axienet_local *lp)
{
- long end = jiffies + 2;
+ unsigned long end = jiffies + 2;
while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) &
XAE_MDIO_MCR_READY_MASK)) {
if (time_before_eq(end, jiffies)) {
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 06b5e4132040..af36c7b560df 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -707,7 +707,7 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id)
static int xemaclite_mdio_wait(struct net_local *lp)
{
- long end = jiffies + 2;
+ unsigned long end = jiffies + 2;
/* wait for the MDIO interface to not be busy or timeout
after some time.
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index ff0e464441d0..ae86b89c9ca4 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -777,9 +777,14 @@ static void netvsc_link_change(struct work_struct *w)
struct rndis_device *rdev;
bool notify;
- rtnl_lock();
-
ndev_ctx = container_of(w, struct net_device_context, dwork.work);
+
+ /* if changes are happening, comeback later */
+ if (!rtnl_trylock()) {
+ schedule_delayed_work(&ndev_ctx->dwork, 2 * HZ);
+ return;
+ }
+
net_device = hv_get_drvdata(ndev_ctx->device_ctx);
rdev = net_device->extension;
net = net_device->ndev;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 699908de314a..c9b0586d7b58 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -607,7 +607,7 @@ static int brcmf_fws_hanger_pushpkt(struct brcmf_fws_hanger *h,
return 0;
}
-static int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h,
+static inline int brcmf_fws_hanger_poppkt(struct brcmf_fws_hanger *h,
u32 slot_id, struct sk_buff **pktout,
bool remove_item)
{
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 1d6ff00a4194..26c5f3bdf2c5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -2692,6 +2692,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
s32 status;
s32 err = 0;
struct brcmf_escan_result_le *escan_result_le;
+ u32 escan_buflen;
struct brcmf_bss_info_le *bss_info_le;
struct brcmf_bss_info_le *bss = NULL;
u32 bi_length;
@@ -2708,11 +2709,23 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
if (status == BRCMF_E_STATUS_PARTIAL) {
brcmf_dbg(SCAN, "ESCAN Partial result\n");
+ if (e->datalen < sizeof(*escan_result_le)) {
+ brcmf_err("invalid event data length\n");
+ goto exit;
+ }
escan_result_le = (struct brcmf_escan_result_le *) data;
if (!escan_result_le) {
brcmf_err("Invalid escan result (NULL pointer)\n");
goto exit;
}
+ escan_buflen = le32_to_cpu(escan_result_le->buflen);
+ if (escan_buflen > WL_ESCAN_BUF_SIZE ||
+ escan_buflen > e->datalen ||
+ escan_buflen < sizeof(*escan_result_le)) {
+ brcmf_err("Invalid escan buffer length: %d\n",
+ escan_buflen);
+ goto exit;
+ }
if (le16_to_cpu(escan_result_le->bss_count) != 1) {
brcmf_err("Invalid bss_count %d: ignoring\n",
escan_result_le->bss_count);
@@ -2729,9 +2742,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
}
bi_length = le32_to_cpu(bss_info_le->length);
- if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
- WL_ESCAN_RESULTS_FIXED_SIZE)) {
- brcmf_err("Invalid bss_info length %d: ignoring\n",
+ if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
+ brcmf_err("Ignoring invalid bss_info length: %d\n",
bi_length);
goto exit;
}
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 6df3ee561d52..515aa3f993f3 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -836,25 +836,30 @@ static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len,
spin_lock_bh(&local->baplock);
res = hfa384x_setup_bap(dev, BAP0, rid, 0);
- if (!res)
- res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec));
+ if (res)
+ goto unlock;
+
+ res = hfa384x_from_bap(dev, BAP0, &rec, sizeof(rec));
+ if (res)
+ goto unlock;
if (le16_to_cpu(rec.len) == 0) {
/* RID not available */
res = -ENODATA;
+ goto unlock;
}
rlen = (le16_to_cpu(rec.len) - 1) * 2;
- if (!res && exact_len && rlen != len) {
+ if (exact_len && rlen != len) {
printk(KERN_DEBUG "%s: hfa384x_get_rid - RID len mismatch: "
"rid=0x%04x, len=%d (expected %d)\n",
dev->name, rid, rlen, len);
res = -ENODATA;
}
- if (!res)
- res = hfa384x_from_bap(dev, BAP0, buf, len);
+ res = hfa384x_from_bap(dev, BAP0, buf, len);
+unlock:
spin_unlock_bh(&local->baplock);
mutex_unlock(&local->rid_bap_mtx);
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index b598e2803500..fbfd77440049 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -1019,12 +1019,13 @@ il3945_hw_txq_ctx_free(struct il_priv *il)
int txq_id;
/* Tx queues */
- if (il->txq)
+ if (il->txq) {
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
if (txq_id == IL39_CMD_QUEUE_NUM)
il_cmd_queue_free(il);
else
il_tx_queue_free(il, txq_id);
+ }
/* free tx queue structure */
il_free_txq_mem(il);
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 3255a1723d17..d079b9a4c30c 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -1190,11 +1190,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
next_reclaimed;
IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
next_reclaimed);
+ iwlagn_check_ratid_empty(priv, sta_id, tid);
}
iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
- iwlagn_check_ratid_empty(priv, sta_id, tid);
freed = 0;
/* process frames */
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 1fb01ea2e704..28b783ab04c9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -114,7 +114,8 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
add_sta_cmd.add_modify = update ? 1 : 0;
add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK |
- STA_FLG_MIMO_EN_MSK);
+ STA_FLG_MIMO_EN_MSK |
+ STA_FLG_RTS_MIMO_PROT);
switch (sta->bandwidth) {
case IEEE80211_STA_RX_BW_160:
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 4e782f18ae34..293b4e3b6d02 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -1571,6 +1571,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
wl->state = WL1251_STATE_OFF;
mutex_init(&wl->mutex);
+ spin_lock_init(&wl->wl_lock);
wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
diff --git a/drivers/of/device.c b/drivers/of/device.c
index dafb9736ab9b..f659da36cdda 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -128,6 +128,7 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
return tsize;
}
+EXPORT_SYMBOL_GPL(of_device_get_modalias);
/**
* of_device_uevent - Display OF related uevent information
@@ -190,3 +191,4 @@ int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
+EXPORT_SYMBOL_GPL(of_device_uevent_modalias);
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index cf77ab14b681..1a5d765b6af6 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -954,7 +954,7 @@ static int __init dino_probe(struct parisc_device *dev)
dino_dev->hba.dev = dev;
dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096);
- dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */
+ dino_dev->hba.lmmio_space_offset = PCI_F_EXTEND;
spin_lock_init(&dino_dev->dinosaur_pen);
dino_dev->hba.iommu = ccio_get_iommu(dev);
diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index fa1ff7c7e357..ee6afe52a7d1 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -800,6 +800,7 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
SUNXI_FUNCTION(0x2, "lcd1"), /* D16 */
SUNXI_FUNCTION(0x3, "pata"), /* ATAD12 */
SUNXI_FUNCTION(0x4, "keypad"), /* IN6 */
+ SUNXI_FUNCTION(0x5, "sim"), /* DET */
SUNXI_FUNCTION_IRQ(0x6, 16), /* EINT16 */
SUNXI_FUNCTION(0x7, "csi1")), /* D16 */
SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 17),
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index ce364a41842a..6c7057aab262 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -1347,9 +1347,9 @@ static int __init samsung_sabi_init(struct samsung_laptop *samsung)
const struct sabi_config *config = NULL;
const struct sabi_commands *commands;
unsigned int ifaceP;
+ int loca = 0xffff;
int ret = 0;
int i;
- int loca;
samsung->f0000_segment = ioremap_nocache(0xf0000, 0xffff);
if (!samsung->f0000_segment) {
diff --git a/drivers/power/reset/xgene-reboot.c b/drivers/power/reset/xgene-reboot.c
index ecd55f81b9d1..6b49be6867ab 100644
--- a/drivers/power/reset/xgene-reboot.c
+++ b/drivers/power/reset/xgene-reboot.c
@@ -40,7 +40,7 @@ struct xgene_reboot_context {
static struct xgene_reboot_context *xgene_restart_ctx;
-static void xgene_restart(char str, const char *cmd)
+static void xgene_restart(enum reboot_mode mode, const char *cmd)
{
struct xgene_reboot_context *ctx = xgene_restart_ctx;
unsigned long timeout;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 8de493a18d9e..3beb591b8ad8 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2816,7 +2816,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
struct rtable *rt = (struct rtable *) dst;
__be32 *pkey = &ip_hdr(skb)->daddr;
- if (rt->rt_gateway)
+ if (rt && rt->rt_gateway)
pkey = &rt->rt_gateway;
/* IPv4 */
@@ -2827,7 +2827,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
struct rt6_info *rt = (struct rt6_info *) dst;
struct in6_addr *pkey = &ipv6_hdr(skb)->daddr;
- if (!ipv6_addr_any(&rt->rt6i_gateway))
+ if (rt && !ipv6_addr_any(&rt->rt6i_gateway))
pkey = &rt->rt6i_gateway;
/* IPv6 */
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index d8145888e66a..ee00d9e459c8 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -49,7 +49,7 @@
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
-/* FIXME:
+/* Fixed in linux-4.2, not backported to 3.16:
*
* 1. Although all of the necessary command mapping places have the
* appropriate dma_map.. APIs, the driver still processes its internal
@@ -68,7 +68,6 @@
* 7. advansys_info is not safe against multiple simultaneous callers
* 8. Add module_param to override ISA/VLB ioport array
*/
-#warning this driver is still not properly converted to the DMA API
/* Enable driver /proc statistics. */
#define ADVANSYS_STATS
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
index edb43fda9f36..c831e30411fa 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.c
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -983,7 +983,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha,
{
int err, i;
u32 offs, size;
- struct asd_ll_el *el;
+ struct asd_ll_el *el = NULL;
struct asd_ctrla_phy_settings *ps;
struct asd_ctrla_phy_settings dflt_ps;
@@ -1004,6 +1004,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha,
size = sizeof(struct asd_ctrla_phy_settings);
ps = &dflt_ps;
+ goto out_process;
}
if (size == 0)
@@ -1028,7 +1029,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha,
ASD_DPRINTK("couldn't find ctrla phy settings struct\n");
goto out2;
}
-
+out_process:
err = asd_process_ctrla_phy_settings(asd_ha, ps);
if (err) {
ASD_DPRINTK("couldn't process ctrla phy settings\n");
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 803fd64d0966..d5068e43cfc5 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -48,7 +48,6 @@ static unsigned int be_iopoll_budget = 10;
static unsigned int be_max_phys_size = 64;
static unsigned int enable_msix = 1;
-MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
MODULE_VERSION(BUILD_STR);
MODULE_AUTHOR("Emulex Corporation");
@@ -3153,7 +3152,7 @@ be_sgl_create_contiguous(void *virtual_address,
{
WARN_ON(!virtual_address);
WARN_ON(!physical_address);
- WARN_ON(!length > 0);
+ WARN_ON(!length);
WARN_ON(!sgl);
sgl->va = virtual_address;
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index 315d6d6dcfc8..4e7104461f09 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -3665,19 +3665,19 @@ bfa_cb_sfp_state_query(struct bfa_sfp_s *sfp)
if (sfp->state_query_cbfn)
sfp->state_query_cbfn(sfp->state_query_cbarg,
sfp->status);
- sfp->media = NULL;
- }
+ sfp->media = NULL;
+ }
- if (sfp->portspeed) {
- sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed);
- if (sfp->state_query_cbfn)
- sfp->state_query_cbfn(sfp->state_query_cbarg,
- sfp->status);
- sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
- }
+ if (sfp->portspeed) {
+ sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed);
+ if (sfp->state_query_cbfn)
+ sfp->state_query_cbfn(sfp->state_query_cbarg,
+ sfp->status);
+ sfp->portspeed = BFA_PORT_SPEED_UNKNOWN;
+ }
- sfp->state_query_lock = 0;
- sfp->state_query_cbfn = NULL;
+ sfp->state_query_lock = 0;
+ sfp->state_query_cbfn = NULL;
}
/*
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 52a216f21ae5..946084014316 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -206,10 +206,6 @@ module_param(ips, charp, 0);
#define IPS_VERSION_HIGH IPS_VER_MAJOR_STRING "." IPS_VER_MINOR_STRING
#define IPS_VERSION_LOW "." IPS_VER_BUILD_STRING " "
-#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
-#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
-#endif
-
#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
DMA_NONE == scb->scsi_cmd->sc_data_direction) ? \
PCI_DMA_BIDIRECTIONAL : \
@@ -6789,6 +6785,11 @@ ips_remove_device(struct pci_dev *pci_dev)
static int __init
ips_module_init(void)
{
+#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
+ printk(KERN_ERR "ips: This driver has only been tested on the x86/ia64/x86_64 platforms\n");
+ add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
+#endif
+
if (pci_register_driver(&ips_pci_driver) < 0)
return -ENODEV;
ips_driver_template.module = THIS_MODULE;
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 42b1f3318e59..eab05c5f8b0e 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -737,8 +737,8 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf
mv_dprintk("device %016llx not ready.\n",
SAS_ADDR(dev->sas_addr));
- rc = SAS_PHY_DOWN;
- return rc;
+ rc = SAS_PHY_DOWN;
+ return rc;
}
tei.port = dev->port->lldd_port;
if (tei.port && !tei.port->port_attached && !tmf) {
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
index 6209110f295d..7199753591b2 100644
--- a/drivers/scsi/scsi_tgt_if.c
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -286,7 +286,7 @@ static int uspace_ring_map(struct vm_area_struct *vma, unsigned long addr,
int i, err;
for (i = 0; i < TGT_RING_PAGES; i++) {
- struct page *page = virt_to_page(ring->tr_pages[i]);
+ struct page *page = virt_to_page((void *)ring->tr_pages[i]);
err = vm_insert_page(vma, addr, page);
if (err)
return err;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index daa67f509133..d24de1bb33a5 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4115,11 +4115,11 @@ static int st_probe(struct device *dev)
kref_init(&tpnt->kref);
tpnt->disk = disk;
disk->private_data = &tpnt->driver;
- disk->queue = SDp->request_queue;
/* SCSI tape doesn't register this gendisk via add_disk(). Manually
* take queue reference that release_disk() expects. */
- if (!blk_get_queue(disk->queue))
+ if (!blk_get_queue(SDp->request_queue))
goto out_put_disk;
+ disk->queue = SDp->request_queue;
tpnt->driver = &st_template;
tpnt->device = SDp;
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 7bfd64f7d76b..27ebf096e703 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -1020,7 +1020,7 @@ static int atmel_spi_setup(struct spi_device *spi)
csr |= SPI_BF(DLYBCT, 0);
/* chipselect must have been muxed as GPIO (e.g. in board setup) */
- npcs_pin = (unsigned int)spi->controller_data;
+ npcs_pin = (unsigned long)spi->controller_data;
if (gpio_is_valid(spi->cs_gpio))
npcs_pin = spi->cs_gpio;
@@ -1255,7 +1255,7 @@ static int atmel_spi_transfer_one_message(struct spi_master *master,
static void atmel_spi_cleanup(struct spi_device *spi)
{
struct atmel_spi_device *asd = spi->controller_state;
- unsigned gpio = (unsigned) spi->controller_data;
+ unsigned gpio = (unsigned long) spi->controller_data;
if (!asd)
return;
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 02798036df8f..53a908e4219f 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1417,7 +1417,7 @@ static void do_interrupt_dma_transfer(struct pl022 *pl022)
* Default is to enable all interrupts except RX -
* this will be enabled once TX is complete
*/
- u32 irqflags = ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM;
+ u32 irqflags = (u32)(ENABLE_ALL_INTERRUPTS & ~SSP_IMSC_MASK_RXIM);
/* Enable target chip, if not already active */
if (!pl022->next_msg_cs_active)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 10112745bb17..ddee9df1547d 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -630,7 +630,6 @@ static int rspi_rz_transfer_one(struct spi_master *master,
struct spi_transfer *xfer)
{
struct rspi_data *rspi = spi_master_get_devdata(master);
- int ret;
rspi_rz_receive_init(rspi);
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 3b5780710d50..b93b404f6955 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -354,11 +354,23 @@ static int spmi_drv_remove(struct device *dev)
return 0;
}
+static int spmi_drv_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ int ret;
+
+ ret = of_device_uevent_modalias(dev, env);
+ if (ret != -ENODEV)
+ return ret;
+
+ return 0;
+}
+
static struct bus_type spmi_bus_type = {
.name = "spmi",
.match = spmi_device_match,
.probe = spmi_drv_probe,
.remove = spmi_drv_remove,
+ .uevent = spmi_drv_uevent,
};
/**
diff --git a/drivers/staging/bcm/Kconfig b/drivers/staging/bcm/Kconfig
index 8acf4b24a7c9..94e04701e008 100644
--- a/drivers/staging/bcm/Kconfig
+++ b/drivers/staging/bcm/Kconfig
@@ -1,6 +1,7 @@
config BCM_WIMAX
tristate "Beceem BCS200/BCS220-3 and BCSM250 wimax support"
depends on USB && NET
+ depends on !64BIT
help
This is an experimental driver for the Beceem WIMAX chipset used
by Sprint 4G.
diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c
index 4135cb0ed9f5..cd7a6dbdddb8 100644
--- a/drivers/staging/dgnc/dgnc_tty.c
+++ b/drivers/staging/dgnc/dgnc_tty.c
@@ -481,13 +481,18 @@ void dgnc_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *buf, int
int nbuf;
int i;
int tmpbuflen;
- char tmpbuf[TMPBUFLEN];
- char *p = tmpbuf;
+ char *tmpbuf;
+ char *p;
int too_much_data;
+ tmpbuf = kzalloc(TMPBUFLEN, GFP_KERNEL);
+ if (!tmpbuf)
+ return;
+ p = tmpbuf;
+
/* Leave if sniff not open */
if (!(ch->ch_sniff_flags & SNIFF_OPEN))
- return;
+ goto exit;
do_gettimeofday(&tv);
@@ -534,7 +539,7 @@ void dgnc_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *buf, int
* function was probably called by the interrupt/timer routines!
*/
if (n == 0)
- return;
+ goto exit;
/*
* Copy as much data as will fit.
@@ -579,6 +584,9 @@ void dgnc_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *buf, int
}
} while (too_much_data);
+
+exit:
+ kfree(tmpbuf);
}
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 83bb44b38152..26b2cdca29ad 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -236,7 +236,7 @@ static int ad7192_setup(struct ad7192_state *st,
st->mclk = pdata->ext_clk_Hz;
else
st->mclk = AD7192_INT_FREQ_MHz;
- break;
+ break;
default:
ret = -EINVAL;
goto out;
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 7fbaba41c872..483a8350aa1f 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -462,7 +462,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad2s1210_state *st = iio_priv(indio_dev);
- bool negative;
+ u16 negative;
int ret = 0;
u16 pos;
s16 vel;
diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c
index 18c9ccd460b7..6943449a8a48 100644
--- a/drivers/staging/imx-drm/imx-hdmi.c
+++ b/drivers/staging/imx-drm/imx-hdmi.c
@@ -968,7 +968,7 @@ static void hdmi_config_AVI(struct imx_hdmi *hdmi)
else
pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
- under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
+ under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
/*
* Active format identification data is present in the AVI InfoFrame.
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 17cfa99b4fc0..764953089f64 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -1489,7 +1489,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
if (attr->ia_valid & (ATTR_SIZE |
ATTR_ATIME | ATTR_ATIME_SET |
- ATTR_MTIME | ATTR_MTIME_SET))
+ ATTR_MTIME | ATTR_MTIME_SET)) {
/* For truncate and utimes sending attributes to OSTs, setting
* mtime/atime to the past will be performed under PW [0:EOF]
* extent lock (new_size:EOF for truncate). It may seem
@@ -1501,6 +1501,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
rc = ll_setattr_ost(inode, attr);
if (attr->ia_valid & ATTR_SIZE)
up_write(&lli->lli_trunc_sem);
+ }
out:
if (op_data) {
if (op_data->op_ioepoch) {
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
index d9552ba2c15d..208c9ba4e236 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
@@ -59,7 +59,9 @@ static struct usb_device_id rtw_usb_id_tbl[] = {
{USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
{USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
{USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
+ {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
{USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
+ {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */
{} /* Terminating entry */
};
diff --git a/drivers/staging/rtl8192ee/pci.c b/drivers/staging/rtl8192ee/pci.c
index 3fe9b7ba01d6..1686b360e088 100644
--- a/drivers/staging/rtl8192ee/pci.c
+++ b/drivers/staging/rtl8192ee/pci.c
@@ -882,8 +882,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
} else {
if (err_count++ < 10) {
- pr_info("skb->end (%d) - skb->tail (%d) > len (%d)\n",
- skb->end, skb->tail, len);
+ pr_info("skb end: %d) - tailroom (%d) > len (%d)\n",
+ skb_end_offset(skb), skb_tailroom(skb), len);
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_EMERG,
"RX desc\n",
(u8 *)pdesc, 32);
diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c
index 579a4a8c8276..013ebd9629f3 100644
--- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c
@@ -546,7 +546,7 @@ void WMMOnAssocRsp23a(struct rtw_adapter *padapter)
else
aSifsTime = 16;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < 4; i++) {
ACI = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 5) & 0x03;
ACM = (pmlmeinfo->WMM_param.ac_param[i].ACI_AIFSN >> 4) & 0x01;
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index e3ae2599a2b7..88ffe31053ed 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -2933,11 +2933,13 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
rc = -EOPNOTSUPP;
break;
-
case SIOCGIWAPLIST: {
- char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
+ char *buffer = kzalloc(IW_MAX_AP * (sizeof(struct sockaddr) +
+ sizeof(struct iw_quality)), GFP_KERNEL);
- if (wrq->u.data.pointer) {
+ if (!buffer) {
+ rc = -ENOMEM;
+ } else if (wrq->u.data.pointer) {
rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
if (rc == 0) {
if (copy_to_user(wrq->u.data.pointer,
@@ -2947,6 +2949,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
rc = -EFAULT;
}
}
+ kfree(buffer);
}
break;
@@ -2993,7 +2996,6 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
break;
-
case SIOCSIWENCODEEXT: {
char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c
index f7870355c69f..45182ea4172f 100644
--- a/drivers/staging/wlan-ng/prism2fw.c
+++ b/drivers/staging/wlan-ng/prism2fw.c
@@ -763,30 +763,35 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks,
static int read_cardpda(struct pda *pda, wlandevice_t *wlandev)
{
int result = 0;
- struct p80211msg_p2req_readpda msg;
+ struct p80211msg_p2req_readpda *msg;
+
+ msg = kzalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
/* set up the msg */
- msg.msgcode = DIDmsg_p2req_readpda;
- msg.msglen = sizeof(msg);
- strcpy(msg.devname, wlandev->name);
- msg.pda.did = DIDmsg_p2req_readpda_pda;
- msg.pda.len = HFA384x_PDA_LEN_MAX;
- msg.pda.status = P80211ENUM_msgitem_status_no_value;
- msg.resultcode.did = DIDmsg_p2req_readpda_resultcode;
- msg.resultcode.len = sizeof(u32);
- msg.resultcode.status = P80211ENUM_msgitem_status_no_value;
-
- if (prism2mgmt_readpda(wlandev, &msg) != 0) {
+ msg->msgcode = DIDmsg_p2req_readpda;
+ msg->msglen = sizeof(msg);
+ strcpy(msg->devname, wlandev->name);
+ msg->pda.did = DIDmsg_p2req_readpda_pda;
+ msg->pda.len = HFA384x_PDA_LEN_MAX;
+ msg->pda.status = P80211ENUM_msgitem_status_no_value;
+ msg->resultcode.did = DIDmsg_p2req_readpda_resultcode;
+ msg->resultcode.len = sizeof(u32);
+ msg->resultcode.status = P80211ENUM_msgitem_status_no_value;
+
+ if (prism2mgmt_readpda(wlandev, msg) != 0) {
/* prism2mgmt_readpda prints an errno if appropriate */
result = -1;
- } else if (msg.resultcode.data == P80211ENUM_resultcode_success) {
- memcpy(pda->buf, msg.pda.data, HFA384x_PDA_LEN_MAX);
+ } else if (msg->resultcode.data == P80211ENUM_resultcode_success) {
+ memcpy(pda->buf, msg->pda.data, HFA384x_PDA_LEN_MAX);
result = mkpdrlist(pda);
} else {
/* resultcode must've been something other than success */
result = -1;
}
+ kfree(msg);
return result;
}
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 1a4f09ab3866..e137dc7cfc72 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -431,6 +431,7 @@ int iscsit_reset_np_thread(
return 0;
}
np->np_thread_state = ISCSI_NP_THREAD_RESET;
+ atomic_inc(&np->np_reset_count);
if (np->np_thread) {
spin_unlock_bh(&np->np_thread_lock);
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
index f8e14dda29f6..725c682b7692 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -792,6 +792,7 @@ struct iscsi_np {
int np_sock_type;
enum np_thread_state_table np_thread_state;
bool enabled;
+ atomic_t np_reset_count;
enum iscsi_timer_flags_table np_login_timer_flags;
u32 np_exports;
enum np_flags_table np_flags;
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 850c977b6df3..2ab8081267f9 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -1277,9 +1277,11 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
flush_signals(current);
spin_lock_bh(&np->np_thread_lock);
- if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+ if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
+ spin_unlock_bh(&np->np_thread_lock);
complete(&np->np_restart_comp);
+ return 1;
} else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) {
spin_unlock_bh(&np->np_thread_lock);
goto exit;
@@ -1312,7 +1314,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
goto exit;
} else if (rc < 0) {
spin_lock_bh(&np->np_thread_lock);
- if (np->np_thread_state == ISCSI_NP_THREAD_RESET) {
+ if (atomic_dec_if_positive(&np->np_reset_count) >= 0) {
+ np->np_thread_state = ISCSI_NP_THREAD_ACTIVE;
spin_unlock_bh(&np->np_thread_lock);
complete(&np->np_restart_comp);
iscsit_put_transport(conn->conn_transport);
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c
index 858291ca889c..c03ecaa0af7f 100644
--- a/drivers/tty/isicom.c
+++ b/drivers/tty/isicom.c
@@ -1055,7 +1055,7 @@ static int isicom_send_break(struct tty_struct *tty, int length)
outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
outw((length & 0xff) << 8 | 0x00, base);
- outw((length & 0xff00), base);
+ outw((length & 0xff00u), base);
InterruptTheCard(base);
unlock_card(card);
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c
index cd0429369557..b5b1b195ff2c 100644
--- a/drivers/tty/nozomi.c
+++ b/drivers/tty/nozomi.c
@@ -823,7 +823,7 @@ static int receive_data(enum port_type index, struct nozomi *dc)
struct tty_struct *tty = tty_port_tty_get(&port->port);
int i, ret;
- read_mem32((u32 *) &size, addr, 4);
+ size = __le32_to_cpu(readl(addr));
/* DBG1( "%d bytes port: %d", size, index); */
if (tty && test_bit(TTY_THROTTLED, &tty->flags)) {
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 2c34b1e444a4..ef71827f92a3 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1772,6 +1772,9 @@ static const struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
},
+ { USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */
+ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+ },
{ USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
.driver_info = CLEAR_HALT_CONDITIONS,
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 627038883c55..063d9767d6fe 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -607,15 +607,23 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
} else if (header->bDescriptorType ==
USB_DT_INTERFACE_ASSOCIATION) {
+ struct usb_interface_assoc_descriptor *d;
+
+ d = (struct usb_interface_assoc_descriptor *)header;
+ if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) {
+ dev_warn(ddev,
+ "config %d has an invalid interface association descriptor of length %d, skipping\n",
+ cfgno, d->bLength);
+ continue;
+ }
+
if (iad_num == USB_MAXIADS) {
dev_warn(ddev, "found more Interface "
"Association Descriptors "
"than allocated for in "
"configuration %d\n", cfgno);
} else {
- config->intf_assoc[iad_num] =
- (struct usb_interface_assoc_descriptor
- *)header;
+ config->intf_assoc[iad_num] = d;
iad_num++;
}
@@ -916,10 +924,12 @@ int usb_get_bos_descriptor(struct usb_device *dev)
for (i = 0; i < num; i++) {
buffer += length;
cap = (struct usb_dev_cap_header *)buffer;
- length = cap->bLength;
- if (total_len < length)
+ if (total_len < sizeof(*cap) || total_len < cap->bLength) {
+ dev->bos->desc->bNumDeviceCaps = i;
break;
+ }
+ length = cap->bLength;
total_len -= length;
if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 495f6949ebf6..865bc662b28c 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2402,6 +2402,8 @@ void usb_hc_died (struct usb_hcd *hcd)
}
if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) {
hcd = hcd->shared_hcd;
+ clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
+ set_bit(HCD_FLAG_DEAD, &hcd->flags);
if (hcd->rh_registered) {
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 25892de366b4..598e9adf8858 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4602,7 +4602,8 @@ hub_power_remaining (struct usb_hub *hub)
static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
u16 portchange)
{
- int status, i;
+ int status = -ENODEV;
+ int i;
unsigned unit_load;
struct usb_device *hdev = hub->hdev;
struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
@@ -4799,9 +4800,10 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
done:
hub_port_disable(hub, port1, 1);
- if (hcd->driver->relinquish_port && !hub->hdev->parent)
- hcd->driver->relinquish_port(hcd, port1);
-
+ if (hcd->driver->relinquish_port && !hub->hdev->parent) {
+ if (status != -ENOTCONN && status != -ENODEV)
+ hcd->driver->relinquish_port(hcd, port1);
+ }
}
/* Handle physical or logical connection change events.
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 59106b01dc20..88a49b1f8bbb 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -147,6 +147,9 @@ static const struct usb_device_id usb_quirk_list[] = {
/* appletouch */
{ USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */
+ { USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM },
+
/* Avision AV600U */
{ USB_DEVICE(0x0638, 0x0a13), .driver_info =
USB_QUIRK_STRING_FETCH_255 },
@@ -246,6 +249,7 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
{ USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME },
{ USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME },
{ USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME },
+ { USB_DEVICE(0x03f0, 0x2b4a), .driver_info = USB_QUIRK_RESET_RESUME },
/* Logitech Optical Mouse M90/M100 */
{ USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index f4e6b945136c..94039dc5de72 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -78,6 +78,16 @@
#define USB_INTEL_USB3_PSSEN 0xD8
#define USB_INTEL_USB3PRM 0xDC
+/* ASMEDIA quirk use */
+#define ASMT_DATA_WRITE0_REG 0xF8
+#define ASMT_DATA_WRITE1_REG 0xFC
+#define ASMT_CONTROL_REG 0xE0
+#define ASMT_CONTROL_WRITE_BIT 0x02
+#define ASMT_WRITEREG_CMD 0x10423
+#define ASMT_FLOWCTL_ADDR 0xFA30
+#define ASMT_FLOWCTL_DATA 0xBA
+#define ASMT_PSEUDO_DATA 0
+
/*
* amd_chipset_gen values represent AMD different chipset generations
*/
@@ -89,6 +99,7 @@ enum amd_chipset_gen {
AMD_CHIPSET_HUDSON2,
AMD_CHIPSET_BOLTON,
AMD_CHIPSET_YANGTZE,
+ AMD_CHIPSET_TAISHAN,
AMD_CHIPSET_UNKNOWN,
};
@@ -132,6 +143,11 @@ static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo)
pinfo->sb_type.gen = AMD_CHIPSET_SB700;
else if (rev >= 0x40 && rev <= 0x4f)
pinfo->sb_type.gen = AMD_CHIPSET_SB800;
+ }
+ pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
+ 0x145c, NULL);
+ if (pinfo->smbus_dev) {
+ pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN;
} else {
pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL);
@@ -253,11 +269,12 @@ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev)
{
/* Make sure amd chipset type has already been initialized */
usb_amd_find_chipset_info();
- if (amd_chipset.sb_type.gen != AMD_CHIPSET_YANGTZE)
- return 0;
-
- dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
- return 1;
+ if (amd_chipset.sb_type.gen == AMD_CHIPSET_YANGTZE ||
+ amd_chipset.sb_type.gen == AMD_CHIPSET_TAISHAN) {
+ dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
+ return 1;
+ }
+ return 0;
}
EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk);
@@ -415,6 +432,50 @@ void usb_amd_quirk_pll_disable(void)
}
EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable);
+static int usb_asmedia_wait_write(struct pci_dev *pdev)
+{
+ unsigned long retry_count;
+ unsigned char value;
+
+ for (retry_count = 1000; retry_count > 0; --retry_count) {
+
+ pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value);
+
+ if (value == 0xff) {
+ dev_err(&pdev->dev, "%s: check_ready ERROR", __func__);
+ return -EIO;
+ }
+
+ if ((value & ASMT_CONTROL_WRITE_BIT) == 0)
+ return 0;
+
+ usleep_range(40, 60);
+ }
+
+ dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__);
+ return -ETIMEDOUT;
+}
+
+void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev)
+{
+ if (usb_asmedia_wait_write(pdev) != 0)
+ return;
+
+ /* send command and address to device */
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD);
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR);
+ pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+
+ if (usb_asmedia_wait_write(pdev) != 0)
+ return;
+
+ /* send data to device */
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA);
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA);
+ pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+}
+EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol);
+
void usb_amd_quirk_pll_enable(void)
{
usb_amd_quirk_pll(0);
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h
index c622ddf21c94..6463fdb403c2 100644
--- a/drivers/usb/host/pci-quirks.h
+++ b/drivers/usb/host/pci-quirks.h
@@ -11,6 +11,7 @@ bool usb_amd_prefetch_quirk(void);
void usb_amd_dev_put(void);
void usb_amd_quirk_pll_disable(void);
void usb_amd_quirk_pll_enable(void);
+void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev);
void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
void sb800_prefetch(struct device *dev, int on);
@@ -18,6 +19,7 @@ void sb800_prefetch(struct device *dev, int on);
struct pci_dev;
static inline void usb_amd_quirk_pll_disable(void) {}
static inline void usb_amd_quirk_pll_enable(void) {}
+static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
static inline void usb_amd_dev_put(void) {}
static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
static inline void sb800_prefetch(struct device *dev, int on) {}
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 48562be0f07f..76628f9e39ba 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -644,6 +644,9 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
clear_bit(wIndex, &bus_state->resuming_ports);
set_bit(wIndex, &bus_state->rexit_ports);
+
+ xhci_test_and_clear_bit(xhci, port_array, wIndex,
+ PORT_PLC);
xhci_set_link_state(xhci, port_array, wIndex,
XDEV_U0);
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 60edc9668935..cc40aa7529e2 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -52,6 +52,8 @@
#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb
#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc
+#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
+
static const char hcd_name[] = "xhci_hcd";
/* called after powerup, by probe or system-pm "wakeup" */
@@ -198,6 +200,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
pdev->device == 0x1142)
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+ pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI)
+ xhci->quirks |= XHCI_ASMEDIA_MODIFY_FLOWCONTROL;
+
if (xhci->quirks & XHCI_RESET_ON_RESUME)
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"QUIRK: Resetting on resume");
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 97a3955650c9..e69c7df4b9a9 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -821,13 +821,16 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci,
(ep->ep_state & EP_GETTING_NO_STREAMS)) {
int stream_id;
- for (stream_id = 0; stream_id < ep->stream_info->num_streams;
+ for (stream_id = 1; stream_id < ep->stream_info->num_streams;
stream_id++) {
+ ring = ep->stream_info->stream_rings[stream_id];
+ if (!ring)
+ continue;
+
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"Killing URBs for slot ID %u, ep index %u, stream %u",
- slot_id, ep_index, stream_id + 1);
- xhci_kill_ring_urbs(xhci,
- ep->stream_info->stream_rings[stream_id]);
+ slot_id, ep_index, stream_id);
+ xhci_kill_ring_urbs(xhci, ring);
}
} else {
ring = ep->ring;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index af2be1476d8a..45654fffa7a5 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -191,6 +191,9 @@ int xhci_reset(struct xhci_hcd *xhci)
if (ret)
return ret;
+ if (xhci->quirks & XHCI_ASMEDIA_MODIFY_FLOWCONTROL)
+ usb_asmedia_modifyflowcontrol(to_pci_dev(xhci_to_hcd(xhci)->self.controller));
+
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Wait for controller to be ready for doorbell rings");
/*
@@ -659,8 +662,10 @@ int xhci_run(struct usb_hcd *hcd)
command = xhci_alloc_command(xhci, false, false, GFP_KERNEL);
if (!command)
return -ENOMEM;
- xhci_queue_vendor_command(xhci, command, 0, 0, 0,
+ ret = xhci_queue_vendor_command(xhci, command, 0, 0, 0,
TRB_TYPE(TRB_NEC_GET_FW));
+ if (ret)
+ xhci_free_command(xhci, command);
}
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Finished xhci_run for USB2 roothub");
@@ -1116,6 +1121,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
compliance_mode_recovery_timer_init(xhci);
+ if (xhci->quirks & XHCI_ASMEDIA_MODIFY_FLOWCONTROL)
+ usb_asmedia_modifyflowcontrol(to_pci_dev(hcd->self.controller));
+
/* Re-enable port polling. */
xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 92e852cc3944..746ffa720ae4 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1570,6 +1570,7 @@ struct xhci_hcd {
#define XHCI_PME_STUCK_QUIRK (1 << 20)
#define XHCI_MISSING_CAS (1 << 24)
#define XHCI_U2_DISABLE_WAKE (1 << 27)
+#define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28)
unsigned int num_active_eps;
unsigned int limit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 419a5b3cb924..8fc6b8bdd1ba 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -164,12 +164,13 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
return tmp;
}
- if (in) {
+ if (in)
dev->in_pipe = usb_rcvbulkpipe(udev,
in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ if (out)
dev->out_pipe = usb_sndbulkpipe(udev,
out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- }
+
if (iso_in) {
dev->iso_in = &iso_in->desc;
dev->in_iso_pipe = usb_rcvisocpipe(udev,
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
index 17267b0a2e95..e1648e4230ac 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -600,8 +600,10 @@ static int usbhsc_resume(struct device *dev)
struct usbhs_priv *priv = dev_get_drvdata(dev);
struct platform_device *pdev = usbhs_priv_to_pdev(priv);
- if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
+ if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) {
usbhsc_power_ctrl(priv, 1);
+ usbhs_mod_autonomy_mode(priv);
+ }
usbhs_platform_call(priv, phy_reset, pdev);
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 6583c04cc35e..5732dd0fbd27 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -36,6 +36,7 @@ struct usbhsg_gpriv;
struct usbhsg_uep {
struct usb_ep ep;
struct usbhs_pipe *pipe;
+ spinlock_t lock; /* protect the pipe */
char ep_name[EP_NAME_SIZE];
@@ -126,7 +127,8 @@ static void usbhsg_queue_pop(struct usbhsg_uep *uep,
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
struct device *dev = usbhsg_gpriv_to_dev(gpriv);
- dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
+ if (pipe)
+ dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
ureq->req.status = status;
ureq->req.complete(&uep->ep, &ureq->req);
@@ -607,15 +609,26 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
static int usbhsg_ep_disable(struct usb_ep *ep)
{
struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
+ struct usbhs_pipe *pipe;
+ unsigned long flags;
+ int ret = 0;
- if (!uep->pipe)
- return -EINVAL;
+ spin_lock_irqsave(&uep->lock, flags);
+ pipe = usbhsg_uep_to_pipe(uep);
+ if (!pipe) {
+ ret = -EINVAL;
+ goto out;
+ }
usbhsg_pipe_disable(uep);
+ usbhs_pipe_free(pipe);
uep->pipe->mod_private = NULL;
uep->pipe = NULL;
+out:
+ spin_unlock_irqrestore(&uep->lock, flags);
+
return 0;
}
@@ -665,10 +678,20 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
{
struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
- struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
+ struct usbhs_pipe *pipe;
+ unsigned long flags;
- usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
+ spin_lock_irqsave(&uep->lock, flags);
+ pipe = usbhsg_uep_to_pipe(uep);
+ if (pipe)
+ usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
+
+ /*
+ * To dequeue a request, this driver should call the usbhsg_queue_pop()
+ * even if the pipe is NULL.
+ */
usbhsg_queue_pop(uep, ureq, -ECONNRESET);
+ spin_unlock_irqrestore(&uep->lock, flags);
return 0;
}
@@ -795,10 +818,10 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
{
struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
struct usbhs_mod *mod = usbhs_mod_get_current(priv);
- struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
+ struct usbhsg_uep *uep;
struct device *dev = usbhs_priv_to_dev(priv);
unsigned long flags;
- int ret = 0;
+ int ret = 0, i;
/******************** spin lock ********************/
usbhs_lock(priv, flags);
@@ -830,7 +853,9 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
usbhs_sys_set_test_mode(priv, 0);
usbhs_sys_function_ctrl(priv, 0);
- usbhsg_ep_disable(&dcp->ep);
+ /* disable all eps */
+ usbhsg_for_each_uep_with_dcp(uep, gpriv, i)
+ usbhsg_ep_disable(&uep->ep);
dev_dbg(dev, "stop gadget\n");
@@ -950,6 +975,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
ret = -ENOMEM;
goto usbhs_mod_gadget_probe_err_gpriv;
}
+ spin_lock_init(&uep->lock);
/*
* CAUTION
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 7926e1c700f1..aa611807661a 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -640,6 +640,11 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
return pipe;
}
+static void usbhsp_put_pipe(struct usbhs_pipe *pipe)
+{
+ usbhsp_flags_init(pipe);
+}
+
void usbhs_pipe_init(struct usbhs_priv *priv,
int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map))
{
@@ -726,6 +731,11 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
return pipe;
}
+void usbhs_pipe_free(struct usbhs_pipe *pipe)
+{
+ usbhsp_put_pipe(pipe);
+}
+
void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo)
{
if (pipe->fifo)
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
index 3e5349879838..406f36d050e4 100644
--- a/drivers/usb/renesas_usbhs/pipe.h
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -75,6 +75,7 @@ struct usbhs_pipe_info {
char *usbhs_pipe_name(struct usbhs_pipe *pipe);
struct usbhs_pipe
*usbhs_pipe_malloc(struct usbhs_priv *priv, int endpoint_type, int dir_in);
+void usbhs_pipe_free(struct usbhs_pipe *pipe);
int usbhs_pipe_probe(struct usbhs_priv *priv);
void usbhs_pipe_remove(struct usbhs_priv *priv);
int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 0786281108f6..8f8f4aed5fbb 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -135,6 +135,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
+ { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 475104bb3395..9cd199cbac2e 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -2036,6 +2036,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 599d8bff26c3..420e096ac09b 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1522,8 +1522,11 @@ static void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us)
/* Make sure driver was initialized */
- if (us->extra == NULL)
+ if (us->extra == NULL) {
usb_stor_dbg(us, "ERROR Driver not initialized\n");
+ srb->result = DID_ERROR << 16;
+ return;
+ }
scsi_set_resid(srb, 0);
/* scsi_bufflen might change in protocol translation to ata */
diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h
index f58caa9e6a27..a155cd02bce2 100644
--- a/drivers/usb/storage/uas-detect.h
+++ b/drivers/usb/storage/uas-detect.h
@@ -9,7 +9,8 @@ static int uas_is_interface(struct usb_host_interface *intf)
intf->desc.bInterfaceProtocol == USB_PR_UAS);
}
-static int uas_find_uas_alt_setting(struct usb_interface *intf)
+static struct usb_host_interface *uas_find_uas_alt_setting(
+ struct usb_interface *intf)
{
int i;
@@ -17,10 +18,10 @@ static int uas_find_uas_alt_setting(struct usb_interface *intf)
struct usb_host_interface *alt = &intf->altsetting[i];
if (uas_is_interface(alt))
- return alt->desc.bAlternateSetting;
+ return alt;
}
- return -ENODEV;
+ return NULL;
}
static int uas_find_endpoints(struct usb_host_interface *alt,
@@ -58,14 +59,14 @@ static int uas_use_uas_driver(struct usb_interface *intf,
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
unsigned long flags = id->driver_info;
- int r, alt;
-
+ struct usb_host_interface *alt;
+ int r;
alt = uas_find_uas_alt_setting(intf);
- if (alt < 0)
+ if (!alt)
return 0;
- r = uas_find_endpoints(&intf->altsetting[alt], eps);
+ r = uas_find_endpoints(alt, eps);
if (r < 0)
return 0;
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 88ccb9c6516e..87ecc65fe6e1 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -1034,14 +1034,14 @@ MODULE_DEVICE_TABLE(usb, uas_usb_ids);
static int uas_switch_interface(struct usb_device *udev,
struct usb_interface *intf)
{
- int alt;
+ struct usb_host_interface *alt;
alt = uas_find_uas_alt_setting(intf);
- if (alt < 0)
- return alt;
+ if (!alt)
+ return -ENODEV;
- return usb_set_interface(udev,
- intf->altsetting[0].desc.bInterfaceNumber, alt);
+ return usb_set_interface(udev, alt->desc.bInterfaceNumber,
+ alt->desc.bAlternateSetting);
}
static int uas_configure_endpoints(struct uas_dev_info *devinfo)
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
index d696eaf71cf9..8be79bef37af 100644
--- a/drivers/usb/storage/unusual_uas.h
+++ b/drivers/usb/storage/unusual_uas.h
@@ -113,9 +113,9 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999,
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@xxxxxxxxxx> */
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
"Initio Corporation",
- "",
+ "INIC-3069",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
- US_FL_NO_ATA_1X),
+ US_FL_NO_ATA_1X | US_FL_IGNORE_RESIDUE),
/* Reported-by: Tom Arild Naess <tanaess@xxxxxxxxx> */
UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999,
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 81ff9b68da3e..9ba9e285c4e5 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -2330,10 +2330,11 @@ config FB_MSM
config FB_MX3
tristate "MX3 Framebuffer support"
depends on FB && MX3_IPU
+ select BACKLIGHT_CLASS_DEVICE
+ select BACKLIGHT_LCD_SUPPORT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select BACKLIGHT_CLASS_DEVICE
default y
help
This is a framebuffer device for the i.MX31 LCD Controller. So
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 619e30f103d0..a30006636796 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -183,15 +183,21 @@ build_path_from_dentry(struct dentry *direntry)
}
/*
+ * Don't allow path components longer than the server max.
* Don't allow the separator character in a path component.
* The VFS will not allow "/", but "\" is allowed by posix.
*/
static int
-check_name(struct dentry *direntry)
+check_name(struct dentry *direntry, struct cifs_tcon *tcon)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
int i;
+ if (unlikely(tcon->fsAttrInfo.MaxPathNameComponentLength &&
+ direntry->d_name.len >
+ le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength)))
+ return -ENAMETOOLONG;
+
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
for (i = 0; i < direntry->d_name.len; i++) {
if (direntry->d_name.name[i] == '\\') {
@@ -489,10 +495,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
return finish_no_open(file, res);
}
- rc = check_name(direntry);
- if (rc)
- return rc;
-
xid = get_xid();
cifs_dbg(FYI, "parent inode = 0x%p name is: %s and dentry = 0x%p\n",
@@ -505,6 +507,11 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
}
tcon = tlink_tcon(tlink);
+
+ rc = check_name(direntry, tcon);
+ if (rc)
+ goto out;
+
server = tcon->ses->server;
if (server->ops->new_lease_key)
@@ -752,7 +759,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
}
pTcon = tlink_tcon(tlink);
- rc = check_name(direntry);
+ rc = check_name(direntry, pTcon);
if (rc)
goto lookup_out;
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index caa38395ec83..8add863a81fd 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -2486,8 +2486,8 @@ copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf,
kst->f_bsize = le32_to_cpu(pfs_inf->BytesPerSector) *
le32_to_cpu(pfs_inf->SectorsPerAllocationUnit);
kst->f_blocks = le64_to_cpu(pfs_inf->TotalAllocationUnits);
- kst->f_bfree = le64_to_cpu(pfs_inf->ActualAvailableAllocationUnits);
- kst->f_bavail = le64_to_cpu(pfs_inf->CallerAvailableAllocationUnits);
+ kst->f_bfree = kst->f_bavail =
+ le64_to_cpu(pfs_inf->CallerAvailableAllocationUnits);
return;
}
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 0de9d257fd92..2d5c6b4b840e 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -82,8 +82,8 @@
#define NUMBER_OF_SMB2_COMMANDS 0x0013
-/* BB FIXME - analyze following length BB */
-#define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */
+/* 4 len + 52 transform hdr + 64 hdr + 56 create rsp */
+#define MAX_SMB2_HDR_SIZE 0x00b0
#define SMB2_PROTO_NUMBER __constant_cpu_to_le32(0x424d53fe)
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 7bcfff900f05..feaa4cebeca8 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -518,8 +518,13 @@ static void ep_remove_wait_queue(struct eppoll_entry *pwq)
wait_queue_head_t *whead;
rcu_read_lock();
- /* If it is cleared by POLLFREE, it should be rcu-safe */
- whead = rcu_dereference(pwq->whead);
+ /*
+ * If it is cleared by POLLFREE, it should be rcu-safe.
+ * If we read NULL we need a barrier paired with
+ * smp_store_release() in ep_poll_callback(), otherwise
+ * we rely on whead->lock.
+ */
+ whead = smp_load_acquire(&pwq->whead);
if (whead)
remove_wait_queue(whead, &pwq->wait);
rcu_read_unlock();
@@ -1006,17 +1011,6 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
struct epitem *epi = ep_item_from_wait(wait);
struct eventpoll *ep = epi->ep;
- if ((unsigned long)key & POLLFREE) {
- ep_pwq_from_wait(wait)->whead = NULL;
- /*
- * whead = NULL above can race with ep_remove_wait_queue()
- * which can do another remove_wait_queue() after us, so we
- * can't use __remove_wait_queue(). whead->lock is held by
- * the caller.
- */
- list_del_init(&wait->task_list);
- }
-
spin_lock_irqsave(&ep->lock, flags);
/*
@@ -1081,6 +1075,22 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
if (pwake)
ep_poll_safewake(&ep->poll_wait);
+ if ((unsigned long)key & POLLFREE) {
+ /*
+ * If we race with ep_remove_wait_queue() it can miss
+ * ->whead = NULL and do another remove_wait_queue() after
+ * us, so we can't use __remove_wait_queue().
+ */
+ list_del_init(&wait->task_list);
+ /*
+ * ->whead != NULL protects us from the race with ep_free()
+ * or ep_remove(), ep_remove_wait_queue() takes whead->lock
+ * held by the caller. Once we nullify it, nothing protects
+ * ep/epi or even wait.
+ */
+ smp_store_release(&ep_pwq_from_wait(wait)->whead, NULL);
+ }
+
return 1;
}
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 9493a9fef2e1..c81044f51785 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -344,6 +344,8 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
lastoff = page_offset(page);
bh = head = page_buffers(page);
do {
+ if (lastoff + bh->b_size <= startoff)
+ goto next;
if (buffer_uptodate(bh) ||
buffer_unwritten(bh)) {
if (whence == SEEK_DATA)
@@ -358,6 +360,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode,
unlock_page(page);
goto out;
}
+next:
lastoff += bh->b_size;
bh = bh->b_this_page;
} while (bh != head);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index d534e589949b..74db6d94bc55 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1929,7 +1929,8 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
n_desc_blocks = o_desc_blocks +
le16_to_cpu(es->s_reserved_gdt_blocks);
n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
- n_blocks_count = n_group * EXT4_BLOCKS_PER_GROUP(sb);
+ n_blocks_count = (ext4_fsblk_t)n_group *
+ EXT4_BLOCKS_PER_GROUP(sb);
n_group--; /* set to last group number */
}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index d583c976fff2..ab9fad6fb6b1 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -54,7 +54,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
{
struct fuse_file *ff;
- ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+ ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL);
if (unlikely(!ff))
return NULL;
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 5d4261ff5d23..f3508f4583d5 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -749,12 +749,15 @@ static int get_leaf_nr(struct gfs2_inode *dip, u32 index,
u64 *leaf_out)
{
__be64 *hash;
+ int error;
hash = gfs2_dir_get_hash_table(dip);
- if (IS_ERR(hash))
- return PTR_ERR(hash);
- *leaf_out = be64_to_cpu(*(hash + index));
- return 0;
+ error = PTR_ERR_OR_ZERO(hash);
+
+ if (!error)
+ *leaf_out = be64_to_cpu(*(hash + index));
+
+ return error;
}
static int get_first_leaf(struct gfs2_inode *dip, u32 index,
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index a6bb3486841a..9f2d8afaa34b 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -931,6 +931,7 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
target->caps = source->caps;
target->options = source->options;
target->auth_info = source->auth_info;
+ target->port = source->port;
}
EXPORT_SYMBOL_GPL(nfs_server_copy_userdata);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index bc0b674c2a68..2a89aea2fb85 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -134,7 +134,7 @@ static void next_decode_page(struct nfsd4_compoundargs *argp)
argp->p = page_address(argp->pagelist[0]);
argp->pagelist++;
if (argp->pagelen < PAGE_SIZE) {
- argp->end = argp->p + (argp->pagelen>>2);
+ argp->end = argp->p + XDR_QUADLEN(argp->pagelen);
argp->pagelen = 0;
} else {
argp->end = argp->p + (PAGE_SIZE>>2);
@@ -1246,9 +1246,7 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
argp->pagelen -= pages * PAGE_SIZE;
len -= pages * PAGE_SIZE;
- argp->p = (__be32 *)page_address(argp->pagelist[0]);
- argp->pagelist++;
- argp->end = argp->p + XDR_QUADLEN(PAGE_SIZE);
+ next_decode_page(argp);
}
argp->p += XDR_QUADLEN(len);
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index 090d8ce25bd1..250db0862ca6 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -1797,7 +1797,7 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *btree,
__u64 key, __u64 ptr,
const __u64 *keys, const __u64 *ptrs, int n)
{
- struct buffer_head *bh;
+ struct buffer_head *bh = NULL;
union nilfs_bmap_ptr_req dreq, nreq, *di, *ni;
struct nilfs_bmap_stats stats;
int ret;
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index ff00a0b7acb9..9b4f205d1173 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -582,7 +582,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
struct nilfs_recovery_info *ri)
{
struct buffer_head *bh_sum = NULL;
- struct nilfs_segment_summary *sum;
+ struct nilfs_segment_summary *sum = NULL;
sector_t pseg_start;
sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */
unsigned long nsalvaged_blocks = 0;
@@ -814,7 +814,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs,
struct nilfs_recovery_info *ri)
{
struct buffer_head *bh_sum = NULL;
- struct nilfs_segment_summary *sum;
+ struct nilfs_segment_summary *sum = NULL;
sector_t pseg_start, pseg_end, sr_pseg_start = 0;
sector_t seg_start, seg_end; /* range of full segment (block number) */
sector_t b, end;
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 8c532b2ca3ab..f635ccfc3bdf 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -358,7 +358,7 @@ static int nilfs_move_2nd_super(struct super_block *sb, loff_t sb2off)
struct nilfs_super_block *nsbp;
sector_t blocknr, newblocknr;
unsigned long offset;
- int sb2i = -1; /* array index of the secondary superblock */
+ int sb2i; /* array index of the secondary superblock */
int ret = 0;
/* nilfs->ns_sem must be locked by the caller. */
@@ -369,6 +369,9 @@ static int nilfs_move_2nd_super(struct super_block *sb, loff_t sb2off)
} else if (nilfs->ns_sbh[0]->b_blocknr > nilfs->ns_first_data_block) {
sb2i = 0;
blocknr = nilfs->ns_sbh[0]->b_blocknr;
+ } else {
+ sb2i = -1;
+ blocknr = 0;
}
if (sb2i >= 0 && (u64)blocknr << nilfs->ns_blocksize_bits == sb2off)
goto out; /* super block location is unchanged */
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index 293ab80f3fe2..776aa6cfb6e2 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -240,19 +240,6 @@ int ocfs2_set_acl(handle_t *handle,
switch (type) {
case ACL_TYPE_ACCESS:
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
- if (acl) {
- umode_t mode;
- ret = posix_acl_update_mode(inode, &mode, &acl);
- if (ret)
- return ret;
- else {
- ret = ocfs2_acl_set_mode(inode, di_bh,
- handle, mode);
- if (ret)
- return ret;
-
- }
- }
break;
case ACL_TYPE_DEFAULT:
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT;
@@ -283,6 +270,20 @@ int ocfs2_set_acl(handle_t *handle,
int ocfs2_iop_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
+ int status;
+
+ if (type == ACL_TYPE_ACCESS && acl) {
+ umode_t mode;
+
+ status = posix_acl_update_mode(inode, &mode, &acl);
+ if (status)
+ return status;
+
+ status = ocfs2_acl_set_mode(inode, NULL, NULL, mode);
+ if (status)
+ return status;
+ }
+
return ocfs2_set_acl(NULL, inode, NULL, type, acl, NULL, NULL);
}
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 5960e5593fe0..d64a18db9bef 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -854,13 +854,13 @@ xfs_dialloc_ag_inobt(
/* free inodes to the left? */
if (useleft && trec.ir_freecount) {
- rec = trec;
xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
cur = tcur;
pag->pagl_leftrec = trec.ir_startino;
pag->pagl_rightrec = rec.ir_startino;
pag->pagl_pagino = pagino;
+ rec = trec;
goto alloc_inode;
}
diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h
index fc824e2828f3..5d2add1a6c96 100644
--- a/include/asm-generic/topology.h
+++ b/include/asm-generic/topology.h
@@ -48,7 +48,11 @@
#define parent_node(node) ((void)(node),0)
#endif
#ifndef cpumask_of_node
-#define cpumask_of_node(node) ((void)node, cpu_online_mask)
+ #ifdef CONFIG_NEED_MULTIPLE_NODES
+ #define cpumask_of_node(node) ((node) == 0 ? cpu_online_mask : cpu_none_mask)
+ #else
+ #define cpumask_of_node(node) ((void)node, cpu_online_mask)
+ #endif
#endif
#ifndef pcibus_to_node
#define pcibus_to_node(bus) ((void)(bus), -1)
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 0e0f3a4e8844..c1028e67c5dc 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -142,10 +142,8 @@ static inline unsigned int cpumask_any_but(const struct cpumask *mask,
return 1;
}
-static inline int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp)
+static inline unsigned int cpumask_local_spread(unsigned int i, int node)
{
- set_bit(0, cpumask_bits(dstp));
-
return 0;
}
@@ -199,7 +197,7 @@ static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp)
int cpumask_next_and(int n, const struct cpumask *, const struct cpumask *);
int cpumask_any_but(const struct cpumask *mask, unsigned int cpu);
-int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp);
+unsigned int cpumask_local_spread(unsigned int i, int node);
/**
* for_each_cpu - iterate over every cpu in a mask
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index c51706b7a36e..3d1c67b63d68 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -481,56 +481,32 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size);
*---------------------------------------------------------------*/
#define DM_NAME "device-mapper"
-#ifdef CONFIG_PRINTK
-extern struct ratelimit_state dm_ratelimit_state;
-
-#define dm_ratelimit() __ratelimit(&dm_ratelimit_state)
-#else
-#define dm_ratelimit() 0
-#endif
-
-#define DMCRIT(f, arg...) \
- printk(KERN_CRIT DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
-
-#define DMERR(f, arg...) \
- printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
-#define DMERR_LIMIT(f, arg...) \
- do { \
- if (dm_ratelimit()) \
- printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " \
- f "\n", ## arg); \
- } while (0)
-
-#define DMWARN(f, arg...) \
- printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
-#define DMWARN_LIMIT(f, arg...) \
- do { \
- if (dm_ratelimit()) \
- printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " \
- f "\n", ## arg); \
- } while (0)
-
-#define DMINFO(f, arg...) \
- printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
-#define DMINFO_LIMIT(f, arg...) \
- do { \
- if (dm_ratelimit()) \
- printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f \
- "\n", ## arg); \
- } while (0)
+#define DM_RATELIMIT(pr_func, fmt, ...) \
+do { \
+ static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, \
+ DEFAULT_RATELIMIT_BURST); \
+ \
+ if (__ratelimit(&rs)) \
+ pr_func(DM_FMT(fmt), ##__VA_ARGS__); \
+} while (0)
+
+#define DM_FMT(fmt) DM_NAME ": " DM_MSG_PREFIX ": " fmt "\n"
+
+#define DMCRIT(fmt, ...) pr_crit(DM_FMT(fmt), ##__VA_ARGS__)
+
+#define DMERR(fmt, ...) pr_err(DM_FMT(fmt), ##__VA_ARGS__)
+#define DMERR_LIMIT(fmt, ...) DM_RATELIMIT(pr_err, fmt, ##__VA_ARGS__)
+#define DMWARN(fmt, ...) pr_warn(DM_FMT(fmt), ##__VA_ARGS__)
+#define DMWARN_LIMIT(fmt, ...) DM_RATELIMIT(pr_warn, fmt, ##__VA_ARGS__)
+#define DMINFO(fmt, ...) pr_info(DM_FMT(fmt), ##__VA_ARGS__)
+#define DMINFO_LIMIT(fmt, ...) DM_RATELIMIT(pr_info, fmt, ##__VA_ARGS__)
#ifdef CONFIG_DM_DEBUG
-# define DMDEBUG(f, arg...) \
- printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg)
-# define DMDEBUG_LIMIT(f, arg...) \
- do { \
- if (dm_ratelimit()) \
- printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX ": " f \
- "\n", ## arg); \
- } while (0)
+#define DMDEBUG(fmt, ...) printk(KERN_DEBUG DM_FMT(fmt), ##__VA_ARGS__)
+#define DMDEBUG_LIMIT(fmt, ...) DM_RATELIMIT(pr_debug, fmt, ##__VA_ARGS__)
#else
-# define DMDEBUG(f, arg...) do {} while (0)
-# define DMDEBUG_LIMIT(f, arg...) do {} while (0)
+#define DMDEBUG(fmt, ...) no_printk(fmt, ##__VA_ARGS__)
+#define DMDEBUG_LIMIT(fmt, ...) no_printk(fmt, ##__VA_ARGS__)
#endif
#define DMEMIT(x...) sz += ((sz >= maxlen) ? \
diff --git a/include/linux/fs.h b/include/linux/fs.h
index da912e6cd2ea..d594f0fbc41a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -809,9 +809,9 @@ static inline struct file *get_file(struct file *f)
/* Page cache limit. The filesystems should put that into their s_maxbytes
limits, otherwise bad things can happen in VM. */
#if BITS_PER_LONG==32
-#define MAX_LFS_FILESIZE (((loff_t)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
+#define MAX_LFS_FILESIZE ((loff_t)ULONG_MAX << PAGE_SHIFT)
#elif BITS_PER_LONG==64
-#define MAX_LFS_FILESIZE ((loff_t)0x7fffffffffffffffLL)
+#define MAX_LFS_FILESIZE ((loff_t)LLONG_MAX)
#endif
#define FL_POSIX 1
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index cff3106ffe2c..c817d7938b4b 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -621,7 +621,7 @@ extern int ftrace_profile_set_filter(struct perf_event *event, int event_id,
char *filter_str);
extern void ftrace_profile_free_filter(struct perf_event *event);
extern void *perf_trace_buf_prepare(int size, unsigned short type,
- struct pt_regs *regs, int *rctxp);
+ struct pt_regs **regs, int *rctxp);
static inline void
perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr,
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 573e4f3243d0..ca3024554a2d 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -141,7 +141,7 @@ extern const char *gpiochip_is_requested(struct gpio_chip *chip,
/* add/remove chips */
extern int gpiochip_add(struct gpio_chip *chip);
-extern int __must_check gpiochip_remove(struct gpio_chip *chip);
+extern int gpiochip_remove(struct gpio_chip *chip);
extern struct gpio_chip *gpiochip_find(void *data,
int (*match)(struct gpio_chip *chip, void *data));
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 48ddabb261bc..61c043c449cb 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -467,6 +467,7 @@ struct mlx4_caps {
u16 hca_core_clock;
u64 phys_port_id[MLX4_MAX_PORTS + 1];
int tunnel_offload_mode;
+ bool wol_port[MLX4_MAX_PORTS + 1];
};
struct mlx4_buf_list {
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 96c5750e3110..761fc630f150 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -451,7 +451,7 @@ struct mm_struct {
* can move process memory needs to flush the TLB when moving a
* PROT_NONE or PROT_NUMA mapped page.
*/
- bool tlb_flush_pending;
+ atomic_t tlb_flush_pending;
#endif
struct uprobes_state uprobes_state;
};
@@ -479,33 +479,46 @@ static inline cpumask_t *mm_cpumask(struct mm_struct *mm)
static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
{
barrier();
- return mm->tlb_flush_pending;
+ return atomic_read(&mm->tlb_flush_pending) > 0;
}
-static inline void set_tlb_flush_pending(struct mm_struct *mm)
+
+static inline void init_tlb_flush_pending(struct mm_struct *mm)
{
- mm->tlb_flush_pending = true;
+ atomic_set(&mm->tlb_flush_pending, 0);
+}
+
+static inline void inc_tlb_flush_pending(struct mm_struct *mm)
+{
+ atomic_inc(&mm->tlb_flush_pending);
/*
- * Guarantee that the tlb_flush_pending store does not leak into the
+ * Guarantee that the tlb_flush_pending increase does not leak into the
* critical section updating the page tables
*/
smp_mb__before_spinlock();
}
+
/* Clearing is done after a TLB flush, which also provides a barrier. */
-static inline void clear_tlb_flush_pending(struct mm_struct *mm)
+static inline void dec_tlb_flush_pending(struct mm_struct *mm)
{
barrier();
- mm->tlb_flush_pending = false;
+ atomic_dec(&mm->tlb_flush_pending);
}
#else
static inline bool mm_tlb_flush_pending(struct mm_struct *mm)
{
return false;
}
-static inline void set_tlb_flush_pending(struct mm_struct *mm)
+
+static inline void init_tlb_flush_pending(struct mm_struct *mm)
{
}
-static inline void clear_tlb_flush_pending(struct mm_struct *mm)
+
+static inline void inc_tlb_flush_pending(struct mm_struct *mm)
+{
+}
+
+static inline void dec_tlb_flush_pending(struct mm_struct *mm)
{
}
#endif
diff --git a/include/linux/module.h b/include/linux/module.h
index f520a767c86c..ac1e65afc5a1 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -135,7 +135,7 @@ void trim_init_extable(struct module *m);
#ifdef MODULE
/* Creates an alias so file2alias.c can find device table. */
#define MODULE_DEVICE_TABLE(type, name) \
- extern const struct type##_device_id __mod_##type##__##name##_device_table \
+extern const typeof(name) __mod_##type##__##name##_device_table \
__attribute__ ((unused, alias(__stringify(name))))
#else /* !MODULE */
#define MODULE_DEVICE_TABLE(type, name)
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index b501e9cd7d3e..db1dba23aed2 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -317,7 +317,17 @@ static inline map_word map_word_or(struct map_info *map, map_word val1, map_word
return r;
}
-#define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b))
+static inline int map_word_andequal(struct map_info *map, map_word val1, map_word val2, map_word val3)
+{
+ int i;
+
+ for (i = 0; i < map_words(map); i++) {
+ if ((val1.x[i] & val2.x[i]) != val3.x[i])
+ return 0;
+ }
+
+ return 1;
+}
static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
{
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 7e8445e9dcbf..d86153fef0e0 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -642,6 +642,7 @@ static inline int is_software_event(struct perf_event *event)
extern struct static_key perf_swevent_enabled[PERF_COUNT_SW_MAX];
+extern void ___perf_sw_event(u32, u64, struct pt_regs *, u64);
extern void __perf_sw_event(u32, u64, struct pt_regs *, u64);
#ifndef perf_arch_fetch_caller_regs
@@ -666,14 +667,25 @@ static inline void perf_fetch_caller_regs(struct pt_regs *regs)
static __always_inline void
perf_sw_event(u32 event_id, u64 nr, struct pt_regs *regs, u64 addr)
{
- struct pt_regs hot_regs;
+ if (static_key_false(&perf_swevent_enabled[event_id]))
+ __perf_sw_event(event_id, nr, regs, addr);
+}
+
+DECLARE_PER_CPU(struct pt_regs, __perf_regs[4]);
+/*
+ * 'Special' version for the scheduler, it hard assumes no recursion,
+ * which is guaranteed by us not actually scheduling inside other swevents
+ * because those disable preemption.
+ */
+static __always_inline void
+perf_sw_event_sched(u32 event_id, u64 nr, u64 addr)
+{
if (static_key_false(&perf_swevent_enabled[event_id])) {
- if (!regs) {
- perf_fetch_caller_regs(&hot_regs);
- regs = &hot_regs;
- }
- __perf_sw_event(event_id, nr, regs, addr);
+ struct pt_regs *regs = this_cpu_ptr(&__perf_regs[0]);
+
+ perf_fetch_caller_regs(regs);
+ ___perf_sw_event(event_id, nr, regs, addr);
}
}
@@ -689,7 +701,7 @@ static inline void perf_event_task_sched_in(struct task_struct *prev,
static inline void perf_event_task_sched_out(struct task_struct *prev,
struct task_struct *next)
{
- perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, NULL, 0);
+ perf_sw_event_sched(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 0);
if (static_key_false(&perf_sched_events.key))
__perf_event_task_sched_out(prev, next);
@@ -800,6 +812,8 @@ static inline int perf_event_refresh(struct perf_event *event, int refresh)
static inline void
perf_sw_event(u32 event_id, u64 nr, struct pt_regs *regs, u64 addr) { }
static inline void
+perf_sw_event_sched(u32 event_id, u64 nr, u64 addr) { }
+static inline void
perf_bp_event(struct perf_event *event, void *data) { }
static inline int perf_register_guest_info_callbacks
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 9eb54f41623e..fa25f353f985 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -315,6 +315,7 @@ enum {
__WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */
__WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */
+ __WQ_ORDERED_EXPLICIT = 1 << 18, /* internal: alloc_ordered_workqueue() */
WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */
WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */
@@ -412,7 +413,8 @@ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active,
* Pointer to the allocated workqueue on success, %NULL on failure.
*/
#define alloc_ordered_workqueue(fmt, flags, args...) \
- alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), 1, ##args)
+ alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | \
+ __WQ_ORDERED_EXPLICIT | (flags), 1, ##args)
#define create_workqueue(name) \
alloc_workqueue("%s", WQ_MEM_RECLAIM, 1, (name))
diff --git a/include/net/dst.h b/include/net/dst.h
index 0fb99a26e973..673e69d1d7be 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -105,16 +105,25 @@ struct dst_entry {
};
};
+void *dst_alloc_metrics(gfp_t flags);
+void dst_free_metrics(void *metrics);
u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
-extern const u32 dst_default_metrics[];
#define DST_METRICS_READ_ONLY 0x1UL
#define DST_METRICS_FORCE_OVERWRITE 0x2UL
-#define DST_METRICS_FLAGS 0x3UL
+#define DST_METRICS_REFCOUNTED 0x4UL
+#define DST_METRICS_FLAGS 0x7UL
+#define DST_METRICS_ALIGNMENT 0x8UL
#define __DST_METRICS_PTR(Y) \
((u32 *)((Y) & ~DST_METRICS_FLAGS))
#define DST_METRICS_PTR(X) __DST_METRICS_PTR((X)->_metrics)
+struct dst_metrics {
+ u32 metrics[RTAX_MAX];
+ atomic_t refcnt;
+} __aligned(DST_METRICS_ALIGNMENT);
+extern const struct dst_metrics dst_default_metrics;
+
static inline bool dst_metrics_read_only(const struct dst_entry *dst)
{
return dst->_metrics & DST_METRICS_READ_ONLY;
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index cf485f9aa563..c09a71789868 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -66,6 +66,7 @@ struct fib6_node {
__u16 fn_flags;
__u32 fn_sernum;
struct rt6_info *rr_ptr;
+ struct rcu_head rcu;
};
#ifndef CONFIG_IPV6_SUBTREES
@@ -95,7 +96,7 @@ struct rt6_info {
* the same cache line.
*/
struct fib6_table *rt6i_table;
- struct fib6_node *rt6i_node;
+ struct fib6_node __rcu *rt6i_node;
struct in6_addr rt6i_gateway;
@@ -193,6 +194,38 @@ static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from)
rt->dst.from = new;
}
+/* Function to safely get fn->sernum for passed in rt
+ * and store result in passed in cookie.
+ * Return true if we can get cookie safely
+ * Return false if not
+ */
+static inline bool rt6_get_cookie_safe(const struct rt6_info *rt,
+ u32 *cookie)
+{
+ struct fib6_node *fn;
+ bool status = false;
+
+ rcu_read_lock();
+ fn = rcu_dereference(rt->rt6i_node);
+
+ if (fn) {
+ *cookie = fn->fn_sernum;
+ status = true;
+ }
+
+ rcu_read_unlock();
+ return status;
+}
+
+static inline u32 rt6_get_cookie(const struct rt6_info *rt)
+{
+ u32 cookie = 0;
+
+ rt6_get_cookie_safe(rt, &cookie);
+
+ return cookie;
+}
+
static inline void ip6_rt_put(struct rt6_info *rt)
{
/* dst_release() accepts a NULL parameter.
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 2e765849ccd6..cea379c35a06 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -146,7 +146,7 @@ static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst,
#ifdef CONFIG_IPV6_SUBTREES
np->saddr_cache = saddr;
#endif
- np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
+ np->dst_cookie = rt6_get_cookie(rt);
}
static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index fac652dc6852..fc7014fe8ee3 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -108,11 +108,11 @@ struct fib_info {
unsigned char fib_type;
__be32 fib_prefsrc;
u32 fib_priority;
- u32 *fib_metrics;
-#define fib_mtu fib_metrics[RTAX_MTU-1]
-#define fib_window fib_metrics[RTAX_WINDOW-1]
-#define fib_rtt fib_metrics[RTAX_RTT-1]
-#define fib_advmss fib_metrics[RTAX_ADVMSS-1]
+ struct dst_metrics *fib_metrics;
+#define fib_mtu fib_metrics->metrics[RTAX_MTU-1]
+#define fib_window fib_metrics->metrics[RTAX_WINDOW-1]
+#define fib_rtt fib_metrics->metrics[RTAX_RTT-1]
+#define fib_advmss fib_metrics->metrics[RTAX_ADVMSS-1]
int fib_nhs;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int fib_power;
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index ee2060f507b7..513aecb66565 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -618,8 +618,11 @@ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
old = *pold;
*pold = new;
if (old != NULL) {
- qdisc_tree_reduce_backlog(old, old->q.qlen, old->qstats.backlog);
+ unsigned int qlen = old->q.qlen;
+ unsigned int backlog = old->qstats.backlog;
+
qdisc_reset(old);
+ qdisc_tree_reduce_backlog(old, qlen, backlog);
}
sch_tree_unlock(sch);
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index a95d237579d6..6c9979b24eba 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -448,6 +448,8 @@ _sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member)
#define _sctp_walk_params(pos, chunk, end, member)\
for (pos.v = chunk->member;\
+ (pos.v + offsetof(struct sctp_paramhdr, length) + sizeof(pos.p->length) <=\
+ (void *)chunk + end) &&\
pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
pos.v += WORD_ROUND(ntohs(pos.p->length)))
@@ -458,6 +460,8 @@ _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
#define _sctp_walk_errors(err, chunk_hdr, end)\
for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
sizeof(sctp_chunkhdr_t));\
+ ((void *)err + offsetof(sctp_errhdr_t, length) + sizeof(err->length) <=\
+ (void *)chunk_hdr + end) &&\
(void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
ntohs(err->length) >= sizeof(sctp_errhdr_t); \
err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index ce55906b54a0..bc45acc195b1 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -184,10 +184,14 @@ static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr,
dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
if (dev) {
- ip4 = (struct in_device *)dev->ip_ptr;
+ ip4 = in_dev_get(dev);
if (ip4 && ip4->ifa_list && ip4->ifa_list->ifa_address)
ipv6_addr_set_v4mapped(ip4->ifa_list->ifa_address,
(struct in6_addr *)gid);
+
+ if (ip4)
+ in_dev_put(ip4);
+
dev_put(dev);
}
}
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 26b4f2e13275..bb1f5d82ad49 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -765,7 +765,7 @@ perf_trace_##call(void *__data, proto) \
struct ftrace_event_call *event_call = __data; \
struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
struct ftrace_raw_##call *entry; \
- struct pt_regs __regs; \
+ struct pt_regs *__regs; \
u64 __addr = 0, __count = 1; \
struct task_struct *__task = NULL; \
struct hlist_head *head; \
@@ -784,18 +784,19 @@ perf_trace_##call(void *__data, proto) \
sizeof(u64)); \
__entry_size -= sizeof(u32); \
\
- perf_fetch_caller_regs(&__regs); \
entry = perf_trace_buf_prepare(__entry_size, \
event_call->event.type, &__regs, &rctx); \
if (!entry) \
return; \
\
+ perf_fetch_caller_regs(__regs); \
+ \
tstruct \
\
{ assign; } \
\
perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \
- __count, &__regs, head, __task); \
+ __count, __regs, head, __task); \
}
/*
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
index a81f5473a801..21c1871c6d23 100644
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -724,6 +724,7 @@ struct usb_interface_assoc_descriptor {
__u8 iFunction;
} __attribute__ ((packed));
+#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
/*-------------------------------------------------------------------------*/
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index 70b4554d2fbe..4593b56339e4 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -455,13 +455,15 @@ void audit_remove_watch_rule(struct audit_krule *krule)
list_del(&krule->rlist);
if (list_empty(&watch->rules)) {
+ /*
+ * audit_remove_watch() drops our reference to 'parent' which
+ * can get freed. Grab our own reference to be safe.
+ */
+ audit_get_parent(parent);
audit_remove_watch(watch);
-
- if (list_empty(&parent->watches)) {
- audit_get_parent(parent);
+ if (list_empty(&parent->watches))
fsnotify_destroy_mark(&parent->mark, audit_watch_group);
- audit_put_parent(parent);
- }
+ audit_put_parent(parent);
}
}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index c1c6d24b5275..3598754bfab3 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3565,50 +3565,77 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running)
}
EXPORT_SYMBOL_GPL(perf_event_read_value);
-static int perf_event_read_group(struct perf_event *event,
- u64 read_format, char __user *buf)
+static void __perf_read_group_add(struct perf_event *leader,
+ u64 read_format, u64 *values)
{
- struct perf_event *leader = event->group_leader, *sub;
struct perf_event_context *ctx = leader->ctx;
- int n = 0, size = 0, ret;
+ struct perf_event *sub;
+ unsigned long flags;
+ int n = 1; /* skip @nr */
u64 count, enabled, running;
- u64 values[5];
-
- lockdep_assert_held(&ctx->mutex);
count = perf_event_read_value(leader, &enabled, &running);
- values[n++] = 1 + leader->nr_siblings;
+ /*
+ * Since we co-schedule groups, {enabled,running} times of siblings
+ * will be identical to those of the leader, so we only publish one
+ * set.
+ */
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
values[n++] = enabled;
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
values[n++] = running;
- values[n++] = count;
+
+ /*
+ * Write {count,id} tuples for every sibling.
+ */
+ values[n++] += count;
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(leader);
- size = n * sizeof(u64);
-
- if (copy_to_user(buf, values, size))
- return -EFAULT;
-
- ret = size;
+ raw_spin_lock_irqsave(&ctx->lock, flags);
list_for_each_entry(sub, &leader->sibling_list, group_entry) {
- n = 0;
-
values[n++] = perf_event_read_value(sub, &enabled, &running);
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(sub);
+ }
- size = n * sizeof(u64);
+ raw_spin_unlock_irqrestore(&ctx->lock, flags);
+}
- if (copy_to_user(buf + ret, values, size)) {
- return -EFAULT;
- }
+static int perf_event_read_group(struct perf_event *event,
+ u64 read_format, char __user *buf)
+{
+ struct perf_event *leader = event->group_leader, *child;
+ struct perf_event_context *ctx = leader->ctx;
+ int ret = event->read_size;
+ u64 *values;
- ret += size;
- }
+ lockdep_assert_held(&ctx->mutex);
+
+ values = kzalloc(event->read_size, GFP_KERNEL);
+ if (!values)
+ return -ENOMEM;
+
+ values[0] = 1 + leader->nr_siblings;
+
+ /*
+ * By locking the child_mutex of the leader we effectively
+ * lock the child list of all siblings.. XXX explain how.
+ */
+ mutex_lock(&leader->child_mutex);
+
+ __perf_read_group_add(leader, read_format, values);
+ list_for_each_entry(child, &leader->child_list, child_list)
+ __perf_read_group_add(child, read_format, values);
+
+ mutex_unlock(&leader->child_mutex);
+
+ if (copy_to_user(buf, values, event->read_size))
+ ret = -EFAULT;
+
+ kfree(values);
return ret;
}
@@ -5938,6 +5965,8 @@ static void do_perf_sw_event(enum perf_type_id type, u32 event_id,
rcu_read_unlock();
}
+DEFINE_PER_CPU(struct pt_regs, __perf_regs[4]);
+
int perf_swevent_get_recursion_context(void)
{
struct swevent_htable *swhash = &__get_cpu_var(swevent_htable);
@@ -5953,21 +5982,30 @@ inline void perf_swevent_put_recursion_context(int rctx)
put_recursion_context(swhash->recursion, rctx);
}
-void __perf_sw_event(u32 event_id, u64 nr, struct pt_regs *regs, u64 addr)
+void ___perf_sw_event(u32 event_id, u64 nr, struct pt_regs *regs, u64 addr)
{
struct perf_sample_data data;
- int rctx;
- preempt_disable_notrace();
- rctx = perf_swevent_get_recursion_context();
- if (rctx < 0)
+ if (WARN_ON_ONCE(!regs))
return;
perf_sample_data_init(&data, addr, 0);
-
do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, &data, regs);
+}
+
+void __perf_sw_event(u32 event_id, u64 nr, struct pt_regs *regs, u64 addr)
+{
+ int rctx;
+
+ preempt_disable_notrace();
+ rctx = perf_swevent_get_recursion_context();
+ if (unlikely(rctx < 0))
+ goto fail;
+
+ ___perf_sw_event(event_id, nr, regs, addr);
perf_swevent_put_recursion_context(rctx);
+fail:
preempt_enable_notrace();
}
@@ -7514,28 +7552,27 @@ SYSCALL_DEFINE5(perf_event_open,
if (group_leader->group_leader != group_leader)
goto err_context;
/*
- * Do not allow to attach to a group in a different
- * task or CPU context:
+ * Make sure we're both events for the same CPU;
+ * grouping events for different CPUs is broken; since
+ * you can never concurrently schedule them anyhow.
*/
- if (move_group) {
- /*
- * Make sure we're both on the same task, or both
- * per-cpu events.
- */
- if (group_leader->ctx->task != ctx->task)
- goto err_context;
+ if (group_leader->cpu != event->cpu)
+ goto err_context;
- /*
- * Make sure we're both events for the same CPU;
- * grouping events for different CPUs is broken; since
- * you can never concurrently schedule them anyhow.
- */
- if (group_leader->cpu != event->cpu)
- goto err_context;
- } else {
- if (group_leader->ctx != ctx)
- goto err_context;
- }
+ /*
+ * Make sure we're both on the same task, or both
+ * per-CPU events.
+ */
+ if (group_leader->ctx->task != ctx->task)
+ goto err_context;
+
+ /*
+ * Do not allow to attach to a group in a different task
+ * or CPU context. If we're moving SW events, we'll fix
+ * this up later, so allow that.
+ */
+ if (!move_group && group_leader->ctx != ctx)
+ goto err_context;
/*
* Only a group leader can be exclusive or pinned
diff --git a/kernel/fork.c b/kernel/fork.c
index 0e1f602b8f47..f6422f07d133 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -539,7 +539,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
spin_lock_init(&mm->page_table_lock);
mm_init_aio(mm);
mm_init_owner(mm, p);
- clear_tlb_flush_pending(mm);
+ init_tlb_flush_pending(mm);
if (current->mm) {
mm->flags = current->mm->flags & MMF_INIT_MASK;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d6d34bbf921a..0940ee9603ae 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1083,7 +1083,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
if (p->sched_class->migrate_task_rq)
p->sched_class->migrate_task_rq(p, new_cpu);
p->se.nr_migrations++;
- perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, NULL, 0);
+ perf_sw_event_sched(PERF_COUNT_SW_CPU_MIGRATIONS, 1, 0);
tmn.task = p;
tmn.from_cpu = task_cpu(p);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index b86ee4effa02..4df317cb0e9a 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -6373,6 +6373,7 @@ static int instance_delete(const char *name)
debugfs_remove_recursive(tr->dir);
free_trace_buffers(tr);
+ free_cpumask_var(tr->tracing_cpumask);
kfree(tr->name);
kfree(tr);
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
index 5d12bb407b44..a818e5601f89 100644
--- a/kernel/trace/trace_event_perf.c
+++ b/kernel/trace/trace_event_perf.c
@@ -249,7 +249,7 @@ void perf_trace_del(struct perf_event *p_event, int flags)
}
void *perf_trace_buf_prepare(int size, unsigned short type,
- struct pt_regs *regs, int *rctxp)
+ struct pt_regs **regs, int *rctxp)
{
struct trace_entry *entry;
unsigned long flags;
@@ -268,6 +268,8 @@ void *perf_trace_buf_prepare(int size, unsigned short type,
if (*rctxp < 0)
return NULL;
+ if (regs)
+ *regs = this_cpu_ptr(&__perf_regs[*rctxp]);
raw_data = this_cpu_ptr(perf_trace_buf[*rctxp]);
/* zero the dead bytes from align to not leak stack to user */
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 7b244d004d68..ebbb24147d51 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -1950,6 +1950,10 @@ static int create_filter(struct ftrace_event_call *call,
if (err && set_str)
append_filter_err(ps, filter);
}
+ if (err && !set_str) {
+ free_event_filter(filter);
+ filter = NULL;
+ }
create_filter_finish(ps);
*filterp = filter;
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 94b253911a2a..562cbf747622 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1155,7 +1155,7 @@ kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs)
size = ALIGN(__size + sizeof(u32), sizeof(u64));
size -= sizeof(u32);
- entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx);
+ entry = perf_trace_buf_prepare(size, call->event.type, NULL, &rctx);
if (!entry)
return;
@@ -1186,7 +1186,7 @@ kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
size = ALIGN(__size + sizeof(u32), sizeof(u64));
size -= sizeof(u32);
- entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx);
+ entry = perf_trace_buf_prepare(size, call->event.type, NULL, &rctx);
if (!entry)
return;
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 7e3cd7aaec83..ba78f0e3477d 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -586,7 +586,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
size -= sizeof(u32);
rec = (struct syscall_trace_enter *)perf_trace_buf_prepare(size,
- sys_data->enter_event->event.type, regs, &rctx);
+ sys_data->enter_event->event.type, NULL, &rctx);
if (!rec)
return;
@@ -659,7 +659,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
size -= sizeof(u32);
rec = (struct syscall_trace_exit *)perf_trace_buf_prepare(size,
- sys_data->exit_event->event.type, regs, &rctx);
+ sys_data->exit_event->event.type, NULL, &rctx);
if (!rec)
return;
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 3c9b97e6b1f4..5224e836acde 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -1116,7 +1116,7 @@ static void __uprobe_perf_func(struct trace_uprobe *tu,
if (hlist_empty(head))
goto out;
- entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx);
+ entry = perf_trace_buf_prepare(size, call->event.type, NULL, &rctx);
if (!entry)
goto out;
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 5e6cafeeb048..146fb7784900 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3324,7 +3324,7 @@ int workqueue_sysfs_register(struct workqueue_struct *wq)
* attributes breaks ordering guarantee. Disallow exposing ordered
* workqueues.
*/
- if (WARN_ON(wq->flags & __WQ_ORDERED))
+ if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))
return -EINVAL;
wq->wq_dev = wq_dev = kzalloc(sizeof(*wq_dev), GFP_KERNEL);
@@ -3907,8 +3907,12 @@ int apply_workqueue_attrs(struct workqueue_struct *wq,
return -EINVAL;
/* creating multiple pwqs breaks ordering guarantee */
- if (WARN_ON((wq->flags & __WQ_ORDERED) && !list_empty(&wq->pwqs)))
- return -EINVAL;
+ if (!list_empty(&wq->pwqs)) {
+ if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))
+ return -EINVAL;
+
+ wq->flags &= ~__WQ_ORDERED;
+ }
pwq_tbl = kzalloc(wq_numa_tbl_len * sizeof(pwq_tbl[0]), GFP_KERNEL);
new_attrs = alloc_workqueue_attrs(GFP_KERNEL);
@@ -4152,6 +4156,16 @@ struct workqueue_struct *__alloc_workqueue_key(const char *fmt,
struct workqueue_struct *wq;
struct pool_workqueue *pwq;
+ /*
+ * Unbound && max_active == 1 used to imply ordered, which is no
+ * longer the case on NUMA machines due to per-node pools. While
+ * alloc_ordered_workqueue() is the right way to create an ordered
+ * workqueue, keep the previous behavior to avoid subtle breakages
+ * on NUMA.
+ */
+ if ((flags & WQ_UNBOUND) && max_active == 1)
+ flags |= __WQ_ORDERED;
+
/* see the comment above the definition of WQ_POWER_EFFICIENT */
if ((flags & WQ_POWER_EFFICIENT) && wq_power_efficient)
flags |= WQ_UNBOUND;
@@ -4344,13 +4358,14 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)
struct pool_workqueue *pwq;
/* disallow meddling with max_active for ordered workqueues */
- if (WARN_ON(wq->flags & __WQ_ORDERED))
+ if (WARN_ON(wq->flags & __WQ_ORDERED_EXPLICIT))
return;
max_active = wq_clamp_max_active(max_active, wq->flags, wq->name);
mutex_lock(&wq->mutex);
+ wq->flags &= ~__WQ_ORDERED;
wq->saved_max_active = max_active;
for_each_pwq(pwq, wq)
diff --git a/lib/assoc_array.c b/lib/assoc_array.c
index 03a77f4740c1..0d122543bd63 100644
--- a/lib/assoc_array.c
+++ b/lib/assoc_array.c
@@ -597,21 +597,31 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit,
if ((edit->segment_cache[ASSOC_ARRAY_FAN_OUT] ^ base_seg) == 0)
goto all_leaves_cluster_together;
- /* Otherwise we can just insert a new node ahead of the old
- * one.
+ /* Otherwise all the old leaves cluster in the same slot, but
+ * the new leaf wants to go into a different slot - so we
+ * create a new node (n0) to hold the new leaf and a pointer to
+ * a new node (n1) holding all the old leaves.
+ *
+ * This can be done by falling through to the node splitting
+ * path.
*/
- goto present_leaves_cluster_but_not_new_leaf;
+ pr_devel("present leaves cluster but not new leaf\n");
}
split_node:
pr_devel("split node\n");
- /* We need to split the current node; we know that the node doesn't
- * simply contain a full set of leaves that cluster together (it
- * contains meta pointers and/or non-clustering leaves).
+ /* We need to split the current node. The node must contain anything
+ * from a single leaf (in the one leaf case, this leaf will cluster
+ * with the new leaf) and the rest meta-pointers, to all leaves, some
+ * of which may cluster.
+ *
+ * It won't contain the case in which all the current leaves plus the
+ * new leaves want to cluster in the same slot.
*
* We need to expel at least two leaves out of a set consisting of the
- * leaves in the node and the new leaf.
+ * leaves in the node and the new leaf. The current meta pointers can
+ * just be copied as they shouldn't cluster with any of the leaves.
*
* We need a new node (n0) to replace the current one and a new node to
* take the expelled nodes (n1).
@@ -716,33 +726,6 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit,
pr_devel("<--%s() = ok [split node]\n", __func__);
return true;
-present_leaves_cluster_but_not_new_leaf:
- /* All the old leaves cluster in the same slot, but the new leaf wants
- * to go into a different slot, so we create a new node to hold the new
- * leaf and a pointer to a new node holding all the old leaves.
- */
- pr_devel("present leaves cluster but not new leaf\n");
-
- new_n0->back_pointer = node->back_pointer;
- new_n0->parent_slot = node->parent_slot;
- new_n0->nr_leaves_on_branch = node->nr_leaves_on_branch;
- new_n1->back_pointer = assoc_array_node_to_ptr(new_n0);
- new_n1->parent_slot = edit->segment_cache[0];
- new_n1->nr_leaves_on_branch = node->nr_leaves_on_branch;
- edit->adjust_count_on = new_n0;
-
- for (i = 0; i < ASSOC_ARRAY_FAN_OUT; i++)
- new_n1->slots[i] = node->slots[i];
-
- new_n0->slots[edit->segment_cache[0]] = assoc_array_node_to_ptr(new_n0);
- edit->leaf_p = &new_n0->slots[edit->segment_cache[ASSOC_ARRAY_FAN_OUT]];
-
- edit->set[0].ptr = &assoc_array_ptr_to_node(node->back_pointer)->slots[node->parent_slot];
- edit->set[0].to = assoc_array_node_to_ptr(new_n0);
- edit->excised_meta[0] = assoc_array_node_to_ptr(node);
- pr_devel("<--%s() = ok [insert node before]\n", __func__);
- return true;
-
all_leaves_cluster_together:
/* All the leaves, new and old, want to cluster together in this node
* in the same slot, so we have to replace this node with a shortcut to
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 78c13985a0a3..317867e0a03f 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -198,64 +198,42 @@ void __init free_bootmem_cpumask_var(cpumask_var_t mask)
#endif
/**
- * cpumask_set_cpu_local_first - set i'th cpu with local numa cpu's first
- *
+ * cpumask_local_spread - select the i'th cpu with local numa cpu's first
* @i: index number
- * @numa_node: local numa_node
- * @dstp: cpumask with the relevant cpu bit set according to the policy
+ * @node: local numa_node
*
- * This function sets the cpumask according to a numa aware policy.
- * cpumask could be used as an affinity hint for the IRQ related to a
- * queue. When the policy is to spread queues across cores - local cores
- * first.
+ * This function selects an online CPU according to a numa aware policy;
+ * local cpus are returned first, followed by non-local ones, then it
+ * wraps around.
*
- * Returns 0 on success, -ENOMEM for no memory, and -EAGAIN when failed to set
- * the cpu bit and need to re-call the function.
+ * It's not very efficient, but useful for setup.
*/
-int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp)
+unsigned int cpumask_local_spread(unsigned int i, int node)
{
- cpumask_var_t mask;
int cpu;
- int ret = 0;
-
- if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
- return -ENOMEM;
+ /* Wrap: we always want a cpu. */
i %= num_online_cpus();
- if (numa_node == -1 || !cpumask_of_node(numa_node)) {
- /* Use all online cpu's for non numa aware system */
- cpumask_copy(mask, cpu_online_mask);
+ if (node == -1) {
+ for_each_cpu(cpu, cpu_online_mask)
+ if (i-- == 0)
+ return cpu;
} else {
- int n;
-
- cpumask_and(mask,
- cpumask_of_node(numa_node), cpu_online_mask);
-
- n = cpumask_weight(mask);
- if (i >= n) {
- i -= n;
-
- /* If index > number of local cpu's, mask out local
- * cpu's
- */
- cpumask_andnot(mask, cpu_online_mask, mask);
+ /* NUMA first. */
+ for_each_cpu_and(cpu, cpumask_of_node(node), cpu_online_mask)
+ if (i-- == 0)
+ return cpu;
+
+ for_each_cpu(cpu, cpu_online_mask) {
+ /* Skip NUMA nodes, done above. */
+ if (cpumask_test_cpu(cpu, cpumask_of_node(node)))
+ continue;
+
+ if (i-- == 0)
+ return cpu;
}
}
-
- for_each_cpu(cpu, mask) {
- if (--i < 0)
- goto out;
- }
-
- ret = -EAGAIN;
-
-out:
- free_cpumask_var(mask);
-
- if (!ret)
- cpumask_set_cpu(cpu, dstp);
-
- return ret;
+ BUG();
}
-EXPORT_SYMBOL(cpumask_set_cpu_local_first);
+EXPORT_SYMBOL(cpumask_local_spread);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 467d04b62948..c892a6b51e8e 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1105,14 +1105,20 @@ static int dissolve_free_huge_page(struct page *page)
int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
{
unsigned long pfn;
+ struct page *page;
int rc = 0;
if (!hugepages_supported())
return rc;
- for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order)
- if (rc = dissolve_free_huge_page(pfn_to_page(pfn)))
- break;
+ for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) {
+ page = pfn_to_page(pfn);
+ if (PageHuge(page) && !page_count(page)) {
+ rc = dissolve_free_huge_page(page);
+ if (rc)
+ break;
+ }
+ }
return rc;
}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index ca088a55b902..fffff2a6677a 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -957,11 +957,6 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask,
*policy |= (pol->flags & MPOL_MODE_FLAGS);
}
- if (vma) {
- up_read(¤t->mm->mmap_sem);
- vma = NULL;
- }
-
err = 0;
if (nmask) {
if (mpol_store_user_nodemask(pol)) {
diff --git a/mm/mprotect.c b/mm/mprotect.c
index c43d557941f8..24607a31259e 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -225,7 +225,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,
BUG_ON(addr >= end);
pgd = pgd_offset(mm, addr);
flush_cache_range(vma, addr, end);
- set_tlb_flush_pending(mm);
+ inc_tlb_flush_pending(mm);
do {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
@@ -237,7 +237,7 @@ static unsigned long change_protection_range(struct vm_area_struct *vma,
/* Only flush the TLB if we actually modified any entries: */
if (pages)
flush_tlb_range(vma, start, end);
- clear_tlb_flush_pending(mm);
+ dec_tlb_flush_pending(mm);
return pages;
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ab7938d2248e..2c1d0eec78ba 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -61,6 +61,7 @@
#include <linux/page-debug-flags.h>
#include <linux/hugetlb.h>
#include <linux/sched/rt.h>
+#include <linux/nmi.h>
#include <asm/sections.h>
#include <asm/tlbflush.h>
@@ -1354,9 +1355,14 @@ void drain_all_pages(void)
#ifdef CONFIG_HIBERNATION
+/*
+ * Touch the watchdog for every WD_PAGE_COUNT pages.
+ */
+#define WD_PAGE_COUNT (128*1024)
+
void mark_free_pages(struct zone *zone)
{
- unsigned long pfn, max_zone_pfn;
+ unsigned long pfn, max_zone_pfn, page_count = WD_PAGE_COUNT;
unsigned long flags;
unsigned int order, t;
struct list_head *curr;
@@ -1371,6 +1377,11 @@ void mark_free_pages(struct zone *zone)
if (pfn_valid(pfn)) {
struct page *page = pfn_to_page(pfn);
+ if (!--page_count) {
+ touch_nmi_watchdog();
+ page_count = WD_PAGE_COUNT;
+ }
+
if (!swsusp_page_is_forbidden(page))
swsusp_unset_page_free(page);
}
@@ -1380,8 +1391,13 @@ void mark_free_pages(struct zone *zone)
unsigned long i;
pfn = page_to_pfn(list_entry(curr, struct page, lru));
- for (i = 0; i < (1UL << order); i++)
+ for (i = 0; i < (1UL << order); i++) {
+ if (!--page_count) {
+ touch_nmi_watchdog();
+ page_count = WD_PAGE_COUNT;
+ }
swsusp_set_page_free(pfn_to_page(pfn + i));
+ }
}
}
spin_unlock_irqrestore(&zone->lock, flags);
@@ -5319,15 +5335,18 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
sizeof(arch_zone_lowest_possible_pfn));
memset(arch_zone_highest_possible_pfn, 0,
sizeof(arch_zone_highest_possible_pfn));
- arch_zone_lowest_possible_pfn[0] = find_min_pfn_with_active_regions();
- arch_zone_highest_possible_pfn[0] = max_zone_pfn[0];
- for (i = 1; i < MAX_NR_ZONES; i++) {
+
+ start_pfn = find_min_pfn_with_active_regions();
+
+ for (i = 0; i < MAX_NR_ZONES; i++) {
if (i == ZONE_MOVABLE)
continue;
- arch_zone_lowest_possible_pfn[i] =
- arch_zone_highest_possible_pfn[i-1];
- arch_zone_highest_possible_pfn[i] =
- max(max_zone_pfn[i], arch_zone_lowest_possible_pfn[i]);
+
+ end_pfn = max(max_zone_pfn[i], start_pfn);
+ arch_zone_lowest_possible_pfn[i] = start_pfn;
+ arch_zone_highest_possible_pfn[i] = end_pfn;
+
+ start_pfn = end_pfn;
}
arch_zone_lowest_possible_pfn[ZONE_MOVABLE] = 0;
arch_zone_highest_possible_pfn[ZONE_MOVABLE] = 0;
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index c93007d9c403..118eba81620e 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1233,9 +1233,41 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
return found;
}
+/**
+ * batadv_tt_global_sync_flags - update TT sync flags
+ * @tt_global: the TT global entry to update sync flags in
+ *
+ * Updates the sync flag bits in the tt_global flag attribute with a logical
+ * OR of all sync flags from any of its TT orig entries.
+ */
+static void
+batadv_tt_global_sync_flags(struct batadv_tt_global_entry *tt_global)
+{
+ struct batadv_tt_orig_list_entry *orig_entry;
+ const struct hlist_head *head;
+ u16 flags = BATADV_NO_FLAGS;
+
+ rcu_read_lock();
+ head = &tt_global->orig_list;
+ hlist_for_each_entry_rcu(orig_entry, head, list)
+ flags |= orig_entry->flags;
+ rcu_read_unlock();
+
+ flags |= tt_global->common.flags & (~BATADV_TT_SYNC_MASK);
+ tt_global->common.flags = flags;
+}
+
+/**
+ * batadv_tt_global_orig_entry_add - add or update a TT orig entry
+ * @tt_global: the TT global entry to add an orig entry in
+ * @orig_node: the originator to add an orig entry for
+ * @ttvn: translation table version number of this changeset
+ * @flags: TT sync flags
+ */
static void
batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
- struct batadv_orig_node *orig_node, int ttvn)
+ struct batadv_orig_node *orig_node, int ttvn,
+ u8 flags)
{
struct batadv_tt_orig_list_entry *orig_entry;
@@ -1245,7 +1277,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
* was added during a "temporary client detection"
*/
orig_entry->ttvn = ttvn;
- goto out;
+ orig_entry->flags = flags;
+ goto sync_flags;
}
orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
@@ -1257,6 +1290,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
orig_entry->orig_node = orig_node;
orig_entry->ttvn = ttvn;
+ orig_entry->flags = flags;
atomic_set(&orig_entry->refcount, 2);
spin_lock_bh(&tt_global->list_lock);
@@ -1265,6 +1299,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
spin_unlock_bh(&tt_global->list_lock);
atomic_inc(&tt_global->orig_list_count);
+sync_flags:
+ batadv_tt_global_sync_flags(tt_global);
out:
if (orig_entry)
batadv_tt_orig_list_entry_free_ref(orig_entry);
@@ -1379,10 +1415,10 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
common->flags &= ~BATADV_TT_CLIENT_TEMP;
/* the change can carry possible "attribute" flags like the
- * TT_CLIENT_WIFI, therefore they have to be copied in the
+ * TT_CLIENT_TEMP, therefore they have to be copied in the
* client entry
*/
- tt_global_entry->common.flags |= flags;
+ tt_global_entry->common.flags |= flags & (~BATADV_TT_SYNC_MASK);
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
* one originator left in the list and we previously received a
@@ -1399,7 +1435,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
}
add_orig_entry:
/* add the new orig_entry (if needed) or update it */
- batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
+ batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn,
+ flags & BATADV_TT_SYNC_MASK);
batadv_dbg(BATADV_DBG_TT, bat_priv,
"Creating new global tt entry: %pM (vid: %d, via %pM)\n",
@@ -2045,6 +2082,7 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
unsigned short vid)
{
struct batadv_hashtable *hash = bat_priv->tt.global_hash;
+ struct batadv_tt_orig_list_entry *tt_orig;
struct batadv_tt_common_entry *tt_common;
struct batadv_tt_global_entry *tt_global;
struct hlist_head *head;
@@ -2083,8 +2121,9 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
/* find out if this global entry is announced by this
* originator
*/
- if (!batadv_tt_global_entry_has_orig(tt_global,
- orig_node))
+ tt_orig = batadv_tt_global_orig_entry_find(tt_global,
+ orig_node);
+ if (!tt_orig)
continue;
/* use network order to read the VID: this ensures that
@@ -2096,10 +2135,12 @@ static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
/* compute the CRC on flags that have to be kept in sync
* among nodes
*/
- flags = tt_common->flags & BATADV_TT_SYNC_MASK;
+ flags = tt_orig->flags;
crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
+
+ batadv_tt_orig_list_entry_free_ref(tt_orig);
}
rcu_read_unlock();
}
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 61f34f889555..9161e3e62a55 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -968,6 +968,7 @@ struct batadv_tt_global_entry {
* struct batadv_tt_orig_list_entry - orig node announcing a non-mesh client
* @orig_node: pointer to orig node announcing this non-mesh client
* @ttvn: translation table version number which added the non-mesh client
+ * @flags: per orig entry TT sync flags
* @list: list node for batadv_tt_global_entry::orig_list
* @refcount: number of contexts the object is used
* @rcu: struct used for freeing in an RCU-safe manner
@@ -975,6 +976,7 @@ struct batadv_tt_global_entry {
struct batadv_tt_orig_list_entry {
struct batadv_orig_node *orig_node;
uint8_t ttvn;
+ u8 flags;
struct hlist_node list;
atomic_t refcount;
struct rcu_head rcu;
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index f3526464bded..f6c9fb8e7449 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -31,10 +31,10 @@ static struct lock_class_key bridge_netdev_addr_lock_key;
netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
- const unsigned char *dest = skb->data;
struct net_bridge_fdb_entry *dst;
struct net_bridge_mdb_entry *mdst;
struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats);
+ const unsigned char *dest;
u16 vid = 0;
rcu_read_lock();
@@ -59,6 +59,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
if (!br_allowed_ingress(br, br_get_vlan_info(br), skb, &vid))
goto out;
+ dest = eth_hdr(skb)->h_dest;
if (is_broadcast_ether_addr(dest))
br_flood_deliver(br, skb, false);
else if (is_multicast_ether_addr(dest)) {
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 366c43649079..c0123c31f787 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -60,11 +60,11 @@ static int br_pass_frame_up(struct sk_buff *skb)
/* note: already called with rcu_read_lock */
int br_handle_frame_finish(struct sk_buff *skb)
{
- const unsigned char *dest = eth_hdr(skb)->h_dest;
struct net_bridge_port *p = br_port_get_rcu(skb->dev);
struct net_bridge *br;
struct net_bridge_fdb_entry *dst;
struct net_bridge_mdb_entry *mdst;
+ const unsigned char *dest;
struct sk_buff *skb2;
bool unicast = true;
u16 vid = 0;
@@ -80,6 +80,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
if (p->flags & BR_LEARNING)
br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, false);
+ dest = eth_hdr(skb)->h_dest;
if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) &&
br_multicast_rcv(br, p, skb, vid))
goto drop;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index a615264cf01a..2cf4e30ac41a 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -155,7 +155,7 @@ static struct dst_ops fake_dst_ops = {
* ipt_REJECT needs it. Future netfilter modules might
* require us to fill additional fields.
*/
-static const u32 br_dst_default_metrics[RTAX_MAX] = {
+static const u32 br_dst_default_metrics[RTAX_MAX] __aligned(DST_METRICS_ALIGNMENT) = {
[RTAX_MTU - 1] = 1500,
};
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c
index 1be0b521ac49..5add8e75759d 100644
--- a/net/caif/cfpkt_skbuff.c
+++ b/net/caif/cfpkt_skbuff.c
@@ -286,7 +286,7 @@ int cfpkt_setlen(struct cfpkt *pkt, u16 len)
else
skb_trim(skb, len);
- return cfpkt_getlen(pkt);
+ return cfpkt_getlen(pkt);
}
/* Need to expand SKB */
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 8e0ed8de3216..6a2236aee1ce 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -3075,8 +3075,10 @@ static struct ceph_msg_data *ceph_msg_data_create(enum ceph_msg_data_type type)
return NULL;
data = kmem_cache_zalloc(ceph_msg_data_cache, GFP_NOFS);
- if (data)
- data->type = type;
+ if (!data)
+ return NULL;
+
+ data->type = type;
INIT_LIST_HEAD(&data->links);
return data;
diff --git a/net/core/dev.c b/net/core/dev.c
index 869a04d5558d..ee2177c0b186 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2413,9 +2413,10 @@ EXPORT_SYMBOL(skb_mac_gso_segment);
static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
{
if (tx_path)
- return skb->ip_summed != CHECKSUM_PARTIAL;
- else
- return skb->ip_summed == CHECKSUM_NONE;
+ return skb->ip_summed != CHECKSUM_PARTIAL &&
+ skb->ip_summed != CHECKSUM_UNNECESSARY;
+
+ return skb->ip_summed == CHECKSUM_NONE;
}
/**
@@ -2432,13 +2433,14 @@ static inline bool skb_needs_check(struct sk_buff *skb, bool tx_path)
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
netdev_features_t features, bool tx_path)
{
+ struct sk_buff *segs;
+
if (unlikely(skb_needs_check(skb, tx_path))) {
int err;
- skb_warn_bad_offload(skb);
-
- if (skb_header_cloned(skb) &&
- (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
+ /* We're going to init ->check field in TCP or UDP header */
+ err = skb_cow_head(skb, 0);
+ if (err < 0)
return ERR_PTR(err);
}
@@ -2448,7 +2450,12 @@ struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
skb_reset_mac_header(skb);
skb_reset_mac_len(skb);
- return skb_mac_gso_segment(skb, features);
+ segs = skb_mac_gso_segment(skb, features);
+
+ if (unlikely(skb_needs_check(skb, tx_path)))
+ skb_warn_bad_offload(skb);
+
+ return segs;
}
EXPORT_SYMBOL(__skb_gso_segment);
diff --git a/net/core/dst.c b/net/core/dst.c
index 57746a18c957..52e900047f89 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -149,13 +149,13 @@ int dst_discard_sk(struct sock *sk, struct sk_buff *skb)
}
EXPORT_SYMBOL(dst_discard_sk);
-const u32 dst_default_metrics[RTAX_MAX + 1] = {
+const struct dst_metrics dst_default_metrics = {
/* This initializer is needed to force linker to place this variable
* into const section. Otherwise it might end into bss section.
* We really want to avoid false sharing on this variable, and catch
* any writes on it.
*/
- [RTAX_MAX] = 0xdeadbeef,
+ .refcnt = ATOMIC_INIT(1),
};
@@ -176,7 +176,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
if (dev)
dev_hold(dev);
dst->ops = ops;
- dst_init_metrics(dst, dst_default_metrics, true);
+ dst_init_metrics(dst, dst_default_metrics.metrics, true);
dst->expires = 0UL;
dst->path = dst;
dst->from = NULL;
@@ -292,27 +292,46 @@ void dst_release(struct dst_entry *dst)
}
EXPORT_SYMBOL(dst_release);
+static struct kmem_cache *metrics_cache;
+
+void *dst_alloc_metrics(gfp_t flags)
+{
+ return kmem_cache_alloc(metrics_cache, flags);
+}
+EXPORT_SYMBOL(dst_alloc_metrics);
+
+void dst_free_metrics(void *metrics)
+{
+ kmem_cache_free(metrics_cache, metrics);
+}
+EXPORT_SYMBOL(dst_free_metrics);
+
u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old)
{
- u32 *p = kmalloc(sizeof(u32) * RTAX_MAX, GFP_ATOMIC);
+ struct dst_metrics *p = dst_alloc_metrics(GFP_ATOMIC);
if (p) {
- u32 *old_p = __DST_METRICS_PTR(old);
+ struct dst_metrics *old_p = (struct dst_metrics *)__DST_METRICS_PTR(old);
unsigned long prev, new;
- memcpy(p, old_p, sizeof(u32) * RTAX_MAX);
+ atomic_set(&p->refcnt, 1);
+ memcpy(p->metrics, old_p->metrics, sizeof(p->metrics));
new = (unsigned long) p;
prev = cmpxchg(&dst->_metrics, old, new);
if (prev != old) {
- kfree(p);
- p = __DST_METRICS_PTR(prev);
+ dst_free_metrics(p);
+ p = (struct dst_metrics *)__DST_METRICS_PTR(prev);
if (prev & DST_METRICS_READ_ONLY)
p = NULL;
+ } else if (prev & DST_METRICS_REFCOUNTED) {
+ if (atomic_dec_and_test(&old_p->refcnt))
+ dst_free_metrics(old_p);
}
}
- return p;
+ BUILD_BUG_ON(offsetof(struct dst_metrics, metrics) != 0);
+ return (u32 *)p;
}
EXPORT_SYMBOL(dst_cow_metrics_generic);
@@ -321,10 +340,10 @@ void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old)
{
unsigned long prev, new;
- new = ((unsigned long) dst_default_metrics) | DST_METRICS_READ_ONLY;
+ new = ((unsigned long) &dst_default_metrics) | DST_METRICS_READ_ONLY;
prev = cmpxchg(&dst->_metrics, old, new);
if (prev == old)
- kfree(__DST_METRICS_PTR(old));
+ dst_free_metrics(__DST_METRICS_PTR(old));
}
EXPORT_SYMBOL(__dst_destroy_metrics_generic);
@@ -419,4 +438,8 @@ static struct notifier_block dst_dev_notifier = {
void __init dst_init(void)
{
register_netdevice_notifier(&dst_dev_notifier);
+ metrics_cache = kmem_cache_create("dst_metrics",
+ sizeof(struct dst_metrics),
+ DST_METRICS_ALIGNMENT,
+ SLAB_PANIC, NULL);
}
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 0234ae038a62..d585bc9109b4 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2502,7 +2502,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
#ifdef CONFIG_XFRM
-static u32 pktgen_dst_metrics[RTAX_MAX + 1] = {
+static u32 pktgen_dst_metrics[RTAX_MAX + 1] __aligned(DST_METRICS_ALIGNMENT) = {
[RTAX_HOPLIMIT] = 0x5, /* Set a static hoplimit */
};
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index c232ededeaa2..d04e56fb7be2 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1175,13 +1175,14 @@ static struct pernet_operations fib_net_ops = {
void __init ip_fib_init(void)
{
- rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL);
- rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
- rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
+ fib_trie_init();
register_pernet_subsys(&fib_net_ops);
+
register_netdevice_notifier(&fib_netdev_notifier);
register_inetaddr_notifier(&fib_inetaddr_notifier);
- fib_trie_init();
+ rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL);
+ rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
+ rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
}
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index b77a181cd450..df875ec5c243 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -201,6 +201,7 @@ static void rt_fibinfo_free_cpus(struct rtable __rcu * __percpu *rtp)
static void free_fib_info_rcu(struct rcu_head *head)
{
struct fib_info *fi = container_of(head, struct fib_info, rcu);
+ struct dst_metrics *m;
change_nexthops(fi) {
if (nexthop_nh->nh_dev)
@@ -212,8 +213,9 @@ static void free_fib_info_rcu(struct rcu_head *head)
} endfor_nexthops(fi);
release_net(fi->fib_net);
- if (fi->fib_metrics != (u32 *) dst_default_metrics)
- kfree(fi->fib_metrics);
+ m = fi->fib_metrics;
+ if (m != &dst_default_metrics && atomic_dec_and_test(&m->refcnt))
+ dst_free_metrics(m);
kfree(fi);
}
@@ -821,14 +823,17 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
if (fi == NULL)
goto failure;
- fib_info_cnt++;
if (cfg->fc_mx) {
- fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL);
- if (!fi->fib_metrics)
- goto failure;
- } else
- fi->fib_metrics = (u32 *) dst_default_metrics;
-
+ fi->fib_metrics = dst_alloc_metrics(GFP_KERNEL | __GFP_ZERO);
+ if (unlikely(!fi->fib_metrics)) {
+ kfree(fi);
+ return ERR_PTR(err);
+ }
+ atomic_set(&fi->fib_metrics->refcnt, 1);
+ } else {
+ fi->fib_metrics = (struct dst_metrics *)&dst_default_metrics;
+ }
+ fib_info_cnt++;
fi->fib_net = hold_net(net);
fi->fib_protocol = cfg->fc_protocol;
fi->fib_scope = cfg->fc_scope;
@@ -864,7 +869,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
val = 65535 - 15;
if (type == RTAX_HOPLIMIT && val > 255)
val = 255;
- fi->fib_metrics[type - 1] = val;
+ fi->fib_metrics->metrics[type - 1] = val;
}
}
}
@@ -1029,7 +1034,7 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
if (fi->fib_priority &&
nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority))
goto nla_put_failure;
- if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
+ if (rtnetlink_put_metrics(skb, fi->fib_metrics->metrics) < 0)
goto nla_put_failure;
if (fi->fib_prefsrc &&
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 2510c02c2d21..0b6a54b9bdeb 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -115,7 +115,8 @@ clusterip_config_entry_put(struct clusterip_config *c)
* functions are also incrementing the refcount on their own,
* so it's safe to remove the entry even if it's in use. */
#ifdef CONFIG_PROC_FS
- proc_remove(c->pde);
+ if (cn->procdir)
+ proc_remove(c->pde);
#endif
return;
}
@@ -735,6 +736,7 @@ static void clusterip_net_exit(struct net *net)
#ifdef CONFIG_PROC_FS
struct clusterip_net *cn = net_generic(net, clusterip_net_id);
proc_remove(cn->procdir);
+ cn->procdir = NULL;
#endif
}
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c
index e79718a382f2..292783018da5 100644
--- a/net/ipv4/netfilter/nft_reject_ipv4.c
+++ b/net/ipv4/netfilter/nft_reject_ipv4.c
@@ -33,6 +33,8 @@ void nft_reject_ipv4_eval(const struct nft_expr *expr,
case NFT_REJECT_TCP_RST:
nf_send_reset(pkt->skb, pkt->ops->hooknum);
break;
+ default:
+ break;
}
data[NFT_REG_VERDICT].verdict = NF_DROP;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index b8dc5d8cdedf..75b122645188 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1344,8 +1344,12 @@ static void rt_add_uncached_list(struct rtable *rt)
static void ipv4_dst_destroy(struct dst_entry *dst)
{
+ struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
struct rtable *rt = (struct rtable *) dst;
+ if (p != &dst_default_metrics && atomic_dec_and_test(&p->refcnt))
+ dst_free_metrics(p);
+
if (!list_empty(&rt->rt_uncached)) {
spin_lock_bh(&rt_uncached_lock);
list_del(&rt->rt_uncached);
@@ -1392,7 +1396,11 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
rt->rt_gateway = nh->nh_gw;
rt->rt_uses_gateway = 1;
}
- dst_init_metrics(&rt->dst, fi->fib_metrics, true);
+ dst_init_metrics(&rt->dst, fi->fib_metrics->metrics, true);
+ if (fi->fib_metrics != &dst_default_metrics) {
+ rt->dst._metrics |= DST_METRICS_REFCOUNTED;
+ atomic_inc(&fi->fib_metrics->refcnt);
+ }
#ifdef CONFIG_IP_ROUTE_CLASSID
rt->dst.tclassid = nh->nh_tclassid;
#endif
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index ca41bcbea39c..15659166c8f2 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -93,7 +93,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
csum = skb_checksum(skb, offset, skb->len - offset, 0);
offset += skb->csum_offset;
*(__sum16 *)(skb->data + offset) = csum_fold(csum);
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
/* Fragment the skb. IP headers of the fragments are updated in
* inet_gso_segment()
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 9f48905cac9c..22773519912b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4737,7 +4737,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
* our DAD process, so we don't need
* to do it again
*/
- if (!(ifp->rt->rt6i_node))
+ if (!rcu_access_pointer(ifp->rt->rt6i_node))
ip6_ins_rt(ifp->rt);
if (ifp->idev->cnf.forwarding)
addrconf_join_anycast(ifp);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 36aadaeb7f44..9f6024f0821d 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -151,11 +151,23 @@ static __inline__ struct fib6_node *node_alloc(void)
return fn;
}
-static __inline__ void node_free(struct fib6_node *fn)
+static void node_free_immediate(struct fib6_node *fn)
{
kmem_cache_free(fib6_node_kmem, fn);
}
+static void node_free_rcu(struct rcu_head *head)
+{
+ struct fib6_node *fn = container_of(head, struct fib6_node, rcu);
+
+ kmem_cache_free(fib6_node_kmem, fn);
+}
+
+static void node_free(struct fib6_node *fn)
+{
+ call_rcu(&fn->rcu, node_free_rcu);
+}
+
static __inline__ void rt6_release(struct rt6_info *rt)
{
if (atomic_dec_and_test(&rt->rt6i_ref))
@@ -551,9 +563,9 @@ static struct fib6_node *fib6_add_1(struct fib6_node *root,
if (!in || !ln) {
if (in)
- node_free(in);
+ node_free_immediate(in);
if (ln)
- node_free(ln);
+ node_free_immediate(ln);
return ERR_PTR(-ENOMEM);
}
@@ -643,7 +655,7 @@ static int fib6_commit_metrics(struct dst_entry *dst,
if (dst->flags & DST_HOST) {
mp = dst_metrics_write_ptr(dst);
} else {
- mp = kzalloc(sizeof(u32) * RTAX_MAX, GFP_ATOMIC);
+ mp = dst_alloc_metrics(GFP_ATOMIC | __GFP_ZERO);
if (!mp)
return -ENOMEM;
dst_init_metrics(dst, mp, 0);
@@ -824,7 +836,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
}
rt->dst.rt6_next = iter;
*ins = rt;
- rt->rt6i_node = fn;
+ rcu_assign_pointer(rt->rt6i_node, fn);
atomic_inc(&rt->rt6i_ref);
inet6_rt_notify(RTM_NEWROUTE, rt, info);
info->nl_net->ipv6.rt6_stats->fib_rt_entries++;
@@ -849,7 +861,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
return err;
}
*ins = rt;
- rt->rt6i_node = fn;
+ rcu_assign_pointer(rt->rt6i_node, fn);
rt->dst.rt6_next = iter->dst.rt6_next;
atomic_inc(&rt->rt6i_ref);
inet6_rt_notify(RTM_NEWROUTE, rt, info);
@@ -859,6 +871,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
}
nsiblings = iter->rt6i_nsiblings;
fib6_purge_rt(iter, fn, info->nl_net);
+ if (fn->rr_ptr == iter)
+ fn->rr_ptr = NULL;
rt6_release(iter);
if (nsiblings) {
@@ -871,6 +885,8 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
if (rt6_qualify_for_ecmp(iter)) {
*ins = iter->dst.rt6_next;
fib6_purge_rt(iter, fn, info->nl_net);
+ if (fn->rr_ptr == iter)
+ fn->rr_ptr = NULL;
rt6_release(iter);
nsiblings--;
} else {
@@ -973,7 +989,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info,
root, and then (in st_failure) stale node
in main tree.
*/
- node_free(sfn);
+ node_free_immediate(sfn);
err = PTR_ERR(sn);
goto st_failure;
}
@@ -1397,8 +1413,9 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
int fib6_del(struct rt6_info *rt, struct nl_info *info)
{
+ struct fib6_node *fn = rcu_dereference_protected(rt->rt6i_node,
+ lockdep_is_held(&rt->rt6i_table->tb6_lock));
struct net *net = info->nl_net;
- struct fib6_node *fn = rt->rt6i_node;
struct rt6_info **rtp;
#if RT6_DEBUG >= 2
@@ -1577,7 +1594,9 @@ static int fib6_clean_node(struct fib6_walker_t *w)
if (res) {
#if RT6_DEBUG >= 2
pr_debug("%s: del failed: rt=%p@%p err=%d\n",
- __func__, rt, rt->rt6i_node, res);
+ __func__, rt,
+ rcu_access_pointer(rt->rt6i_node),
+ res);
#endif
continue;
}
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index c36764006d94..88a2d0ce326e 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -157,7 +157,7 @@ EXPORT_SYMBOL_GPL(ip6_tnl_dst_reset);
void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *) dst;
- t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
+ t->dst_cookie = rt6_get_cookie(rt);
dst_release(t->dst_cache);
t->dst_cache = dst;
}
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c
index 0bc19fa87821..367bd4841a0c 100644
--- a/net/ipv6/netfilter/nft_reject_ipv6.c
+++ b/net/ipv6/netfilter/nft_reject_ipv6.c
@@ -34,6 +34,8 @@ void nft_reject_ipv6_eval(const struct nft_expr *expr,
case NFT_REJECT_TCP_RST:
nf_send_reset6(net, pkt->skb, pkt->ops->hooknum);
break;
+ default:
+ break;
}
data[NFT_REG_VERDICT].verdict = NF_DROP;
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index 19f9a4a339b5..e32c1ff35f78 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -52,7 +52,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
while (offset <= packet_len) {
struct ipv6_opt_hdr *exthdr;
- unsigned int len;
switch (**nexthdr) {
@@ -78,10 +77,9 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
offset);
- len = ipv6_optlen(exthdr);
- if (len + offset >= IPV6_MAXPLEN)
+ offset += ipv6_optlen(exthdr);
+ if (offset > IPV6_MAXPLEN)
return -EINVAL;
- offset += len;
*nexthdr = &exthdr->nexthdr;
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index af2bc34cb81f..d791d769d858 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -247,7 +247,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
.neigh_lookup = ip6_neigh_lookup,
};
-static const u32 ip6_template_metrics[RTAX_MAX] = {
+static const u32 ip6_template_metrics[RTAX_MAX] __aligned(DST_METRICS_ALIGNMENT) = {
[RTAX_HOPLIMIT - 1] = 0,
};
@@ -1090,6 +1090,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
{
struct rt6_info *rt;
+ u32 rt_cookie = 0;
rt = (struct rt6_info *) dst;
@@ -1097,7 +1098,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
* DST_OBSOLETE_FORCE_CHK which forces validation calls down
* into this function always.
*/
- if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
+ if (!rt6_get_cookie_safe(rt, &rt_cookie) || rt_cookie != cookie)
return NULL;
if (rt6_check_expired(rt))
@@ -1136,8 +1137,14 @@ static void ip6_link_failure(struct sk_buff *skb)
dst_hold(&rt->dst);
if (ip6_del_rt(rt))
dst_free(&rt->dst);
- } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) {
- rt->rt6i_node->fn_sernum = -1;
+ } else {
+ struct fib6_node *fn;
+
+ rcu_read_lock();
+ fn = rcu_dereference(rt->rt6i_node);
+ if (fn && (rt->rt6i_flags & RTF_DEFAULT))
+ fn->fn_sernum = -1;
+ rcu_read_unlock();
}
}
}
@@ -1843,6 +1850,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
if (on_link)
nrt->rt6i_flags &= ~RTF_GATEWAY;
+ nrt->rt6i_protocol = RTPROT_REDIRECT;
nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key;
if (ip6_ins_rt(nrt))
@@ -1950,6 +1958,7 @@ static struct rt6_info *rt6_add_route_info(struct net *net,
.fc_dst_len = prefixlen,
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
RTF_UP | RTF_PREF(pref),
+ .fc_protocol = RTPROT_RA,
.fc_nlinfo.portid = 0,
.fc_nlinfo.nlh = NULL,
.fc_nlinfo.nl_net = net,
@@ -2000,6 +2009,7 @@ struct rt6_info *rt6_add_dflt_router(const struct in6_addr *gwaddr,
.fc_ifindex = dev->ifindex,
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
+ .fc_protocol = RTPROT_RA,
.fc_nlinfo.portid = 0,
.fc_nlinfo.nlh = NULL,
.fc_nlinfo.nl_net = dev_net(dev),
@@ -2591,14 +2601,6 @@ static int rt6_fill_node(struct net *net,
rtm->rtm_flags = 0;
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
rtm->rtm_protocol = rt->rt6i_protocol;
- if (rt->rt6i_flags & RTF_DYNAMIC)
- rtm->rtm_protocol = RTPROT_REDIRECT;
- else if (rt->rt6i_flags & RTF_ADDRCONF) {
- if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ROUTEINFO))
- rtm->rtm_protocol = RTPROT_RA;
- else
- rtm->rtm_protocol = RTPROT_KERNEL;
- }
if (rt->rt6i_flags & RTF_CACHE)
rtm->rtm_flags |= RTM_F_CLONED;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4098243f6589..7d901c77a80e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -98,8 +98,7 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
dst_hold(dst);
sk->sk_rx_dst = dst;
inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
- if (rt->rt6i_node)
- inet6_sk(sk)->rx_dst_cookie = rt->rt6i_node->fn_sernum;
+ inet6_sk(sk)->rx_dst_cookie = rt6_get_cookie(rt);
}
static void tcp_v6_hash(struct sock *sk)
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index 3dd9891cfa77..fa9ea1a72f99 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -90,7 +90,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
csum = skb_checksum(skb, offset, skb->len - offset, 0);
offset += skb->csum_offset;
*(__sum16 *)(skb->data + offset) = csum_fold(csum);
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
/* Check if there is enough headroom to insert fragment header. */
tnl_hlen = skb_tnl_header_len(skb);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 28af4e66d87a..b7a06749fa11 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -85,8 +85,7 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
{
if (dst->ops->family == AF_INET6) {
struct rt6_info *rt = (struct rt6_info*)dst;
- if (rt->rt6i_node)
- path->path_cookie = rt->rt6i_node->fn_sernum;
+ path->path_cookie = rt6_get_cookie(rt);
}
path->u.rt6.rt6i_nfheader_len = nfheader_len;
@@ -116,8 +115,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
RTF_LOCAL);
xdst->u.rt6.rt6i_metric = rt->rt6i_metric;
xdst->u.rt6.rt6i_node = rt->rt6i_node;
- if (rt->rt6i_node)
- xdst->route_cookie = rt->rt6i_node->fn_sernum;
+ xdst->route_cookie = rt6_get_cookie(rt);
xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway;
xdst->u.rt6.rt6i_dst = rt->rt6i_dst;
xdst->u.rt6.rt6i_src = rt->rt6i_src;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index eac22fe84c4a..e33e850b5b3f 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -224,7 +224,7 @@ static int pfkey_broadcast_one(struct sk_buff *skb, struct sk_buff **skb2,
#define BROADCAST_ONE 1
#define BROADCAST_REGISTERED 2
#define BROADCAST_PROMISC_ONLY 4
-static int pfkey_broadcast(struct sk_buff *skb,
+static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
int broadcast_flags, struct sock *one_sk,
struct net *net)
{
@@ -274,7 +274,7 @@ static int pfkey_broadcast(struct sk_buff *skb,
rcu_read_unlock();
if (one_sk != NULL)
- err = pfkey_broadcast_one(skb, &skb2, GFP_KERNEL, one_sk);
+ err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk);
kfree_skb(skb2);
kfree_skb(skb);
@@ -307,7 +307,7 @@ static int pfkey_do_dump(struct pfkey_sock *pfk)
hdr = (struct sadb_msg *) pfk->dump.skb->data;
hdr->sadb_msg_seq = 0;
hdr->sadb_msg_errno = rc;
- pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE,
+ pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
&pfk->sk, sock_net(&pfk->sk));
pfk->dump.skb = NULL;
}
@@ -351,7 +351,7 @@ static int pfkey_error(const struct sadb_msg *orig, int err, struct sock *sk)
hdr->sadb_msg_len = (sizeof(struct sadb_msg) /
sizeof(uint64_t));
- pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk));
+ pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk, sock_net(sk));
return 0;
}
@@ -1394,7 +1394,7 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, const struct sadb_
xfrm_state_put(x);
- pfkey_broadcast(resp_skb, BROADCAST_ONE, sk, net);
+ pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk, net);
return 0;
}
@@ -1481,7 +1481,7 @@ static int key_notify_sa(struct xfrm_state *x, const struct km_event *c)
hdr->sadb_msg_seq = c->seq;
hdr->sadb_msg_pid = c->portid;
- pfkey_broadcast(skb, BROADCAST_ALL, NULL, xs_net(x));
+ pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x));
return 0;
}
@@ -1594,7 +1594,7 @@ static int pfkey_get(struct sock *sk, struct sk_buff *skb, const struct sadb_msg
out_hdr->sadb_msg_reserved = 0;
out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
- pfkey_broadcast(out_skb, BROADCAST_ONE, sk, sock_net(sk));
+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk));
return 0;
}
@@ -1699,8 +1699,8 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, const struct sad
return -ENOBUFS;
}
- pfkey_broadcast(supp_skb, BROADCAST_REGISTERED, sk, sock_net(sk));
-
+ pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk,
+ sock_net(sk));
return 0;
}
@@ -1718,7 +1718,8 @@ static int unicast_flush_resp(struct sock *sk, const struct sadb_msg *ihdr)
hdr->sadb_msg_errno = (uint8_t) 0;
hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
- return pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk));
+ return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ONE, sk,
+ sock_net(sk));
}
static int key_notify_sa_flush(const struct km_event *c)
@@ -1739,7 +1740,7 @@ static int key_notify_sa_flush(const struct km_event *c)
hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
hdr->sadb_msg_reserved = 0;
- pfkey_broadcast(skb, BROADCAST_ALL, NULL, c->net);
+ pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net);
return 0;
}
@@ -1796,7 +1797,7 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr)
out_hdr->sadb_msg_pid = pfk->dump.msg_portid;
if (pfk->dump.skb)
- pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE,
+ pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
&pfk->sk, sock_net(&pfk->sk));
pfk->dump.skb = out_skb;
@@ -1884,7 +1885,7 @@ static int pfkey_promisc(struct sock *sk, struct sk_buff *skb, const struct sadb
new_hdr->sadb_msg_errno = 0;
}
- pfkey_broadcast(skb, BROADCAST_ALL, NULL, sock_net(sk));
+ pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ALL, NULL, sock_net(sk));
return 0;
}
@@ -2218,7 +2219,7 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, const struct km_ev
out_hdr->sadb_msg_errno = 0;
out_hdr->sadb_msg_seq = c->seq;
out_hdr->sadb_msg_pid = c->portid;
- pfkey_broadcast(out_skb, BROADCAST_ALL, NULL, xp_net(xp));
+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp));
return 0;
}
@@ -2438,7 +2439,7 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, const struc
out_hdr->sadb_msg_errno = 0;
out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
- pfkey_broadcast(out_skb, BROADCAST_ONE, sk, xp_net(xp));
+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, xp_net(xp));
err = 0;
out:
@@ -2692,7 +2693,7 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
out_hdr->sadb_msg_pid = pfk->dump.msg_portid;
if (pfk->dump.skb)
- pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE,
+ pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
&pfk->sk, sock_net(&pfk->sk));
pfk->dump.skb = out_skb;
@@ -2749,7 +2750,7 @@ static int key_notify_policy_flush(const struct km_event *c)
hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
hdr->sadb_msg_reserved = 0;
- pfkey_broadcast(skb_out, BROADCAST_ALL, NULL, c->net);
+ pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net);
return 0;
}
@@ -2811,7 +2812,7 @@ static int pfkey_process(struct sock *sk, struct sk_buff *skb, const struct sadb
void *ext_hdrs[SADB_EXT_MAX];
int err;
- pfkey_broadcast(skb_clone(skb, GFP_KERNEL),
+ pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL,
BROADCAST_PROMISC_ONLY, NULL, sock_net(sk));
memset(ext_hdrs, 0, sizeof(ext_hdrs));
@@ -3033,7 +3034,8 @@ static int key_notify_sa_expire(struct xfrm_state *x, const struct km_event *c)
out_hdr->sadb_msg_seq = 0;
out_hdr->sadb_msg_pid = 0;
- pfkey_broadcast(out_skb, BROADCAST_REGISTERED, NULL, xs_net(x));
+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL,
+ xs_net(x));
return 0;
}
@@ -3223,7 +3225,8 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
xfrm_ctx->ctx_len);
}
- return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x));
+ return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL,
+ xs_net(x));
}
static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
@@ -3421,7 +3424,8 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
n_port->sadb_x_nat_t_port_port = sport;
n_port->sadb_x_nat_t_port_reserved = 0;
- return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x));
+ return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL,
+ xs_net(x));
}
#ifdef CONFIG_NET_KEY_MIGRATE
@@ -3613,7 +3617,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
}
/* broadcast migrate message to sockets */
- pfkey_broadcast(skb, BROADCAST_ALL, NULL, &init_net);
+ pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net);
return 0;
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 384d92ecd26a..45374242d19a 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -112,53 +112,19 @@ struct l2tp_net {
spinlock_t l2tp_session_hlist_lock;
};
-static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
static inline struct l2tp_tunnel *l2tp_tunnel(struct sock *sk)
{
return sk->sk_user_data;
}
-static inline struct l2tp_net *l2tp_pernet(struct net *net)
+static inline struct l2tp_net *l2tp_pernet(const struct net *net)
{
BUG_ON(!net);
return net_generic(net, l2tp_net_id);
}
-/* Tunnel reference counts. Incremented per session that is added to
- * the tunnel.
- */
-static inline void l2tp_tunnel_inc_refcount_1(struct l2tp_tunnel *tunnel)
-{
- atomic_inc(&tunnel->ref_count);
-}
-
-static inline void l2tp_tunnel_dec_refcount_1(struct l2tp_tunnel *tunnel)
-{
- if (atomic_dec_and_test(&tunnel->ref_count))
- l2tp_tunnel_free(tunnel);
-}
-#ifdef L2TP_REFCNT_DEBUG
-#define l2tp_tunnel_inc_refcount(_t) \
-do { \
- pr_debug("l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", \
- __func__, __LINE__, (_t)->name, \
- atomic_read(&_t->ref_count)); \
- l2tp_tunnel_inc_refcount_1(_t); \
-} while (0)
-#define l2tp_tunnel_dec_refcount(_t)
-do { \
- pr_debug("l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", \
- __func__, __LINE__, (_t)->name, \
- atomic_read(&_t->ref_count)); \
- l2tp_tunnel_dec_refcount_1(_t); \
-} while (0)
-#else
-#define l2tp_tunnel_inc_refcount(t) l2tp_tunnel_inc_refcount_1(t)
-#define l2tp_tunnel_dec_refcount(t) l2tp_tunnel_dec_refcount_1(t)
-#endif
-
/* Session hash global list for L2TPv3.
* The session_id SHOULD be random according to RFC3931, but several
* L2TP implementations use incrementing session_ids. So we do a real
@@ -277,10 +243,31 @@ struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunn
}
EXPORT_SYMBOL_GPL(l2tp_session_find);
+/* Lookup a tunnel. A new reference is held on the returned tunnel. */
+struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id)
+{
+ const struct l2tp_net *pn = l2tp_pernet(net);
+ struct l2tp_tunnel *tunnel;
+
+ rcu_read_lock_bh();
+ list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
+ if (tunnel->tunnel_id == tunnel_id) {
+ l2tp_tunnel_inc_refcount(tunnel);
+ rcu_read_unlock_bh();
+
+ return tunnel;
+ }
+ }
+ rcu_read_unlock_bh();
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(l2tp_tunnel_get);
+
/* Like l2tp_session_find() but takes a reference on the returned session.
* Optionally calls session->ref() too if do_ref is true.
*/
-struct l2tp_session *l2tp_session_get(struct net *net,
+struct l2tp_session *l2tp_session_get(const struct net *net,
struct l2tp_tunnel *tunnel,
u32 session_id, bool do_ref)
{
@@ -355,7 +342,8 @@ EXPORT_SYMBOL_GPL(l2tp_session_get_nth);
/* Lookup a session by interface name.
* This is very inefficient but is only used by management interfaces.
*/
-struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname,
+struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
+ const char *ifname,
bool do_ref)
{
struct l2tp_net *pn = l2tp_pernet(net);
@@ -1395,17 +1383,6 @@ static void l2tp_udp_encap_destroy(struct sock *sk)
}
}
-/* Really kill the tunnel.
- * Come here only when all sessions have been cleared from the tunnel.
- */
-static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
-{
- BUG_ON(atomic_read(&tunnel->ref_count) != 0);
- BUG_ON(tunnel->sock != NULL);
- l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: free...\n", tunnel->name);
- kfree_rcu(tunnel, rcu);
-}
-
/* Workqueue tunnel deletion function */
static void l2tp_tunnel_del_work(struct work_struct *work)
{
@@ -1929,6 +1906,8 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
l2tp_session_set_header_len(session, tunnel->version);
+ l2tp_session_inc_refcount(session);
+
err = l2tp_session_add_to_tunnel(tunnel, session);
if (err) {
kfree(session);
@@ -1936,10 +1915,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
return ERR_PTR(err);
}
- /* Bump the reference count. The session context is deleted
- * only when this drops to zero.
- */
- l2tp_session_inc_refcount(session);
l2tp_tunnel_inc_refcount(tunnel);
/* Ensure tunnel socket isn't deleted */
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 12b08016a312..2219f9d8d961 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -240,7 +240,9 @@ static inline struct l2tp_tunnel *l2tp_sock_to_tunnel(struct sock *sk)
return tunnel;
}
-struct l2tp_session *l2tp_session_get(struct net *net,
+struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id);
+
+struct l2tp_session *l2tp_session_get(const struct net *net,
struct l2tp_tunnel *tunnel,
u32 session_id, bool do_ref);
struct l2tp_session *l2tp_session_find(struct net *net,
@@ -248,7 +250,8 @@ struct l2tp_session *l2tp_session_find(struct net *net,
u32 session_id);
struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth,
bool do_ref);
-struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname,
+struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
+ const char *ifname,
bool do_ref);
struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id);
struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth);
@@ -280,6 +283,17 @@ int l2tp_nl_register_ops(enum l2tp_pwtype pw_type,
void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type);
int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg);
+static inline void l2tp_tunnel_inc_refcount(struct l2tp_tunnel *tunnel)
+{
+ atomic_inc(&tunnel->ref_count);
+}
+
+static inline void l2tp_tunnel_dec_refcount(struct l2tp_tunnel *tunnel)
+{
+ if (atomic_dec_and_test(&tunnel->ref_count))
+ kfree_rcu(tunnel, rcu);
+}
+
/* Session reference counts. Incremented when code obtains a reference
* to a session.
*/
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index a492a781ce9e..6727f16afd44 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -60,10 +60,12 @@ static struct l2tp_session *l2tp_nl_session_get(struct genl_info *info,
(info->attrs[L2TP_ATTR_CONN_ID])) {
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
- if (tunnel)
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
+ if (tunnel) {
session = l2tp_session_get(net, tunnel, session_id,
do_ref);
+ l2tp_tunnel_dec_refcount(tunnel);
+ }
}
return session;
@@ -207,14 +209,16 @@ static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info
}
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
- if (tunnel == NULL) {
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
+ if (!tunnel) {
ret = -ENODEV;
goto out;
}
(void) l2tp_tunnel_delete(tunnel);
+ l2tp_tunnel_dec_refcount(tunnel);
+
out:
return ret;
}
@@ -232,8 +236,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info
}
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
- if (tunnel == NULL) {
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
+ if (!tunnel) {
ret = -ENODEV;
goto out;
}
@@ -241,6 +245,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info
if (info->attrs[L2TP_ATTR_DEBUG])
tunnel->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
+ l2tp_tunnel_dec_refcount(tunnel);
+
out:
return ret;
}
@@ -343,34 +349,37 @@ static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[L2TP_ATTR_CONN_ID]) {
ret = -EINVAL;
- goto out;
+ goto err;
}
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
- if (tunnel == NULL) {
- ret = -ENODEV;
- goto out;
- }
-
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg) {
ret = -ENOMEM;
- goto out;
+ goto err;
+ }
+
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
+ if (!tunnel) {
+ ret = -ENODEV;
+ goto err_nlmsg;
}
ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq,
NLM_F_ACK, tunnel);
if (ret < 0)
- goto err_out;
+ goto err_nlmsg_tunnel;
+
+ l2tp_tunnel_dec_refcount(tunnel);
return genlmsg_unicast(net, msg, info->snd_portid);
-err_out:
+err_nlmsg_tunnel:
+ l2tp_tunnel_dec_refcount(tunnel);
+err_nlmsg:
nlmsg_free(msg);
-
-out:
+err:
return ret;
}
@@ -406,7 +415,6 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
u32 peer_session_id;
int ret = 0;
struct l2tp_tunnel *tunnel;
- struct l2tp_session *session;
struct l2tp_session_cfg cfg = { 0, };
struct net *net = genl_info_net(info);
@@ -414,8 +422,9 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
ret = -EINVAL;
goto out;
}
+
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
if (!tunnel) {
ret = -ENODEV;
goto out;
@@ -423,29 +432,24 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
if (!info->attrs[L2TP_ATTR_SESSION_ID]) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
- session = l2tp_session_find(net, tunnel, session_id);
- if (session) {
- ret = -EEXIST;
- goto out;
- }
if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]);
if (!info->attrs[L2TP_ATTR_PW_TYPE]) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]);
if (cfg.pw_type >= __L2TP_PWTYPE_MAX) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
if (tunnel->version > 2) {
@@ -467,7 +471,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
if (len > 8) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
cfg.cookie_len = len;
memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len);
@@ -476,7 +480,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]);
if (len > 8) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
cfg.peer_cookie_len = len;
memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len);
@@ -512,7 +516,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) ||
(l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) {
ret = -EPROTONOSUPPORT;
- goto out;
+ goto out_tunnel;
}
/* Check that pseudowire-specific params are present */
@@ -522,7 +526,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
case L2TP_PWTYPE_ETH_VLAN:
if (!info->attrs[L2TP_ATTR_VLAN_ID]) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
break;
case L2TP_PWTYPE_ETH:
@@ -541,6 +545,8 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id,
session_id, peer_session_id, &cfg);
+out_tunnel:
+ l2tp_tunnel_dec_refcount(tunnel);
out:
return ret;
}
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 947daa9d3346..398cc91aff65 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -3,6 +3,7 @@
* Copyright 2005-2006, Devicescape Software, Inc.
* Copyright 2006-2007 Jiri Benc <jbenc@xxxxxxx>
* Copyright 2007-2008 Johannes Berg <johannes@xxxxxxxxxxxxxxxx>
+ * Copyright 2017 Intel Deutschland GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -487,9 +488,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
idx = key->conf.keyidx;
- key->local = sdata->local;
- key->sdata = sdata;
- key->sta = sta;
mutex_lock(&sdata->local->key_mtx);
@@ -500,6 +498,21 @@ int ieee80211_key_link(struct ieee80211_key *key,
else
old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
+ /*
+ * Silently accept key re-installation without really installing the
+ * new version of the key to avoid nonce reuse or replay issues.
+ */
+ if (old_key && key->conf.keylen == old_key->conf.keylen &&
+ !memcmp(key->conf.key, old_key->conf.key, key->conf.keylen)) {
+ ieee80211_key_free_unused(key);
+ ret = 0;
+ goto out;
+ }
+
+ key->local = sdata->local;
+ key->sdata = sdata;
+ key->sta = sta;
+
increment_tailroom_need_count(sdata);
ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
@@ -515,6 +528,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
ret = 0;
}
+ out:
mutex_unlock(&sdata->local->key_mtx);
return ret;
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 180f7624bcd4..7abd786d9d89 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -373,7 +373,7 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
goto err_unreach;
}
rt = (struct rt6_info *) dst;
- cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
+ cookie = rt6_get_cookie(rt);
__ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie);
spin_unlock_bh(&dest->dst_lock);
IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n",
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 62097fda49dc..55be1e0a4a7f 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -295,11 +295,11 @@ static void nft_match_eval(const struct nft_expr *expr,
return;
}
- switch(ret) {
- case true:
+ switch (ret ? 1 : 0) {
+ case 1:
data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
break;
- case false:
+ case 0:
data[NFT_REG_VERDICT].verdict = NFT_BREAK;
break;
}
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index cc5603016242..18d520e0ca0a 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -56,6 +56,8 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
state = NF_CT_STATE_BIT(ctinfo);
dest->data[0] = state;
return;
+ default:
+ break;
}
if (ct == NULL)
@@ -117,6 +119,8 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
return;
}
#endif
+ default:
+ break;
}
tuple = &ct->tuplehash[priv->dir].tuple;
@@ -141,6 +145,8 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
case NFT_CT_PROTO_DST:
dest->data[0] = (__force __u16)tuple->dst.u.all;
return;
+ default:
+ break;
}
return;
err:
@@ -172,6 +178,8 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
}
break;
#endif
+ default:
+ break;
}
}
diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c
index f3448c296446..5d5d1df34f77 100644
--- a/net/netfilter/nft_reject.c
+++ b/net/netfilter/nft_reject.c
@@ -61,6 +61,8 @@ int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr)
if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code))
goto nla_put_failure;
break;
+ default:
+ break;
}
return 0;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index d798c2fcd114..f5bf29c033bd 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -214,6 +214,7 @@ static void prb_clear_rxhash(struct tpacket_kbdq_core *,
static void prb_fill_vlan_info(struct tpacket_kbdq_core *,
struct tpacket3_hdr *);
static void packet_flush_mclist(struct sock *sk);
+static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb);
struct packet_skb_cb {
unsigned int origlen;
@@ -266,6 +267,7 @@ static int packet_direct_xmit(struct sk_buff *skb)
goto drop;
}
+ packet_pick_tx_queue(dev, skb);
queue_map = skb_get_queue_mapping(skb);
txq = netdev_get_tx_queue(dev, queue_map);
@@ -1457,10 +1459,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
mutex_lock(&fanout_mutex);
- err = -EINVAL;
- if (!po->running)
- goto out;
-
err = -EALREADY;
if (po->fanout)
goto out;
@@ -1497,7 +1495,10 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
list_add(&match->list, &fanout_list);
}
err = -EINVAL;
- if (match->type == type &&
+
+ spin_lock(&po->bind_lock);
+ if (po->running &&
+ match->type == type &&
match->prot_hook.type == po->prot_hook.type &&
match->prot_hook.dev == po->prot_hook.dev) {
err = -ENOSPC;
@@ -1509,6 +1510,13 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
err = 0;
}
}
+ spin_unlock(&po->bind_lock);
+
+ if (err && !atomic_read(&match->sk_ref)) {
+ list_del(&match->list);
+ kfree(match);
+ }
+
out:
mutex_unlock(&fanout_mutex);
return err;
@@ -2343,8 +2351,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
}
}
- packet_pick_tx_queue(dev, skb);
-
skb->destructor = tpacket_destruct_skb;
__packet_set_status(po, ph, TP_STATUS_SENDING);
packet_inc_pending(&po->tx_ring);
@@ -2551,8 +2557,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
- packet_pick_tx_queue(dev, skb);
-
if (po->has_vnet_hdr) {
if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
if (!skb_partial_csum_set(skb, vnet_hdr.csum_start,
@@ -2692,13 +2696,15 @@ static int packet_do_bind(struct sock *sk, const char *name, int ifindex,
int ret = 0;
bool unlisted = false;
- if (po->fanout)
- return -EINVAL;
-
lock_sock(sk);
spin_lock(&po->bind_lock);
rcu_read_lock();
+ if (po->fanout) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
if (name) {
dev = dev_get_by_name_rcu(sock_net(sk), name);
if (!dev) {
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 8b7e7e25bd72..2403a7b126f6 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -978,6 +978,8 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
return sch;
}
+ /* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */
+ ops->destroy(sch);
err_out3:
dev_put(dev);
kfree((char *) sch - sch->padded);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index fc0ea5c63521..56d1262d8593 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1364,6 +1364,13 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
struct tc_ratespec *r;
int err;
+ qdisc_watchdog_init(&q->watchdog, sch);
+ hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
+ q->delay_timer.function = cbq_undelay;
+
+ if (!opt)
+ return -EINVAL;
+
err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy);
if (err < 0)
return err;
@@ -1402,9 +1409,6 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
q->link.avpkt = q->link.allot/2;
q->link.minidle = -0x7FFFFFFF;
- qdisc_watchdog_init(&q->watchdog, sch);
- hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
- q->delay_timer.function = cbq_undelay;
q->toplevel = TC_CBQ_MAXLEVEL;
q->now = psched_get_time();
q->now_rt = q->now;
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index 633be4b72e20..3de2fd89e7fe 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -411,10 +411,8 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt)
if (!q->flows)
return -ENOMEM;
q->backlogs = fq_codel_zalloc(q->flows_cnt * sizeof(u32));
- if (!q->backlogs) {
- fq_codel_free(q->flows);
+ if (!q->backlogs)
return -ENOMEM;
- }
for (i = 0; i < q->flows_cnt; i++) {
struct fq_codel_flow *flow = q->flows + i;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 90bc6e56f112..4cbcf532e55b 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1432,6 +1432,8 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
struct tc_hfsc_qopt *qopt;
int err;
+ qdisc_watchdog_init(&q->watchdog, sch);
+
if (opt == NULL || nla_len(opt) < sizeof(*qopt))
return -EINVAL;
qopt = nla_data(opt);
@@ -1457,8 +1459,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
qdisc_class_hash_insert(&q->clhash, &q->root.cl_common);
qdisc_class_hash_grow(sch, &q->clhash);
- qdisc_watchdog_init(&q->watchdog, sch);
-
return 0;
}
diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
index cdc1836810c2..33cf9e5ae352 100644
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -509,6 +509,9 @@ static void hhf_destroy(struct Qdisc *sch)
hhf_free(q->hhf_valid_bits[i]);
}
+ if (!q->hh_flows)
+ return;
+
for (i = 0; i < HH_FLOWS_CNT; i++) {
struct hh_flow_state *flow, *next;
struct list_head *head = &q->hh_flows[i];
@@ -644,7 +647,9 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt)
q->hhf_arrays[i] = hhf_zalloc(HHF_ARRAYS_LEN *
sizeof(u32));
if (!q->hhf_arrays[i]) {
- hhf_destroy(sch);
+ /* Note: hhf_destroy() will be called
+ * by our caller.
+ */
return -ENOMEM;
}
}
@@ -655,7 +660,9 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt)
q->hhf_valid_bits[i] = hhf_zalloc(HHF_ARRAYS_LEN /
BITS_PER_BYTE);
if (!q->hhf_valid_bits[i]) {
- hhf_destroy(sch);
+ /* Note: hhf_destroy() will be called
+ * by our caller.
+ */
return -ENOMEM;
}
}
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index b169a8a05a5d..ac0e30dd1ed9 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1025,6 +1025,9 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
int err;
int i;
+ qdisc_watchdog_init(&q->watchdog, sch);
+ INIT_WORK(&q->work, htb_work_func);
+
if (!opt)
return -EINVAL;
@@ -1045,8 +1048,6 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
for (i = 0; i < TC_HTB_NUMPRIO; i++)
INIT_LIST_HEAD(q->drops + i);
- qdisc_watchdog_init(&q->watchdog, sch);
- INIT_WORK(&q->work, htb_work_func);
skb_queue_head_init(&q->direct_queue);
if (tb[TCA_HTB_DIRECT_QLEN])
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index a8b2864a696b..0c6db36b6a82 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -52,7 +52,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt)
/* pre-allocate qdiscs, attachment can't fail */
priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]),
GFP_KERNEL);
- if (priv->qdiscs == NULL)
+ if (!priv->qdiscs)
return -ENOMEM;
for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
@@ -60,18 +60,14 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt)
qdisc = qdisc_create_dflt(dev_queue, default_qdisc_ops,
TC_H_MAKE(TC_H_MAJ(sch->handle),
TC_H_MIN(ntx + 1)));
- if (qdisc == NULL)
- goto err;
+ if (!qdisc)
+ return -ENOMEM;
priv->qdiscs[ntx] = qdisc;
qdisc->flags |= TCQ_F_ONETXQUEUE;
}
sch->flags |= TCQ_F_MQROOT;
return 0;
-
-err:
- mq_destroy(sch);
- return -ENOMEM;
}
static void mq_attach(struct Qdisc *sch)
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 6749e2f540d0..626170d568ce 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -117,20 +117,17 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
/* pre-allocate qdisc, attachment can't fail */
priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]),
GFP_KERNEL);
- if (priv->qdiscs == NULL) {
- err = -ENOMEM;
- goto err;
- }
+ if (!priv->qdiscs)
+ return -ENOMEM;
for (i = 0; i < dev->num_tx_queues; i++) {
dev_queue = netdev_get_tx_queue(dev, i);
qdisc = qdisc_create_dflt(dev_queue, default_qdisc_ops,
TC_H_MAKE(TC_H_MAJ(sch->handle),
TC_H_MIN(i + 1)));
- if (qdisc == NULL) {
- err = -ENOMEM;
- goto err;
- }
+ if (!qdisc)
+ return -ENOMEM;
+
priv->qdiscs[i] = qdisc;
qdisc->flags |= TCQ_F_ONETXQUEUE;
}
@@ -143,7 +140,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
priv->hw_owned = 1;
err = dev->netdev_ops->ndo_setup_tc(dev, qopt->num_tc);
if (err)
- goto err;
+ return err;
} else {
netdev_set_num_tc(dev, qopt->num_tc);
for (i = 0; i < qopt->num_tc; i++)
@@ -157,10 +154,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
sch->flags |= TCQ_F_MQROOT;
return 0;
-
-err:
- mqprio_destroy(sch);
- return err;
}
static void mqprio_attach(struct Qdisc *sch)
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 946392276385..e70f51863e01 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -253,7 +253,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
static int multiq_init(struct Qdisc *sch, struct nlattr *opt)
{
struct multiq_sched_data *q = qdisc_priv(sch);
- int i, err;
+ int i;
q->queues = NULL;
@@ -268,12 +268,7 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt)
for (i = 0; i < q->max_bands; i++)
q->queues[i] = &noop_qdisc;
- err = multiq_tune(sch, opt);
-
- if (err)
- kfree(q->queues);
-
- return err;
+ return multiq_tune(sch, opt);
}
static int multiq_dump(struct Qdisc *sch, struct sk_buff *skb)
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index aa9e07816feb..cbf402451c20 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -956,11 +956,11 @@ static int netem_init(struct Qdisc *sch, struct nlattr *opt)
struct netem_sched_data *q = qdisc_priv(sch);
int ret;
+ qdisc_watchdog_init(&q->watchdog, sch);
+
if (!opt)
return -EINVAL;
- qdisc_watchdog_init(&q->watchdog, sch);
-
q->loss_model = CLG_RANDOM;
ret = netem_change(sch, opt);
if (ret)
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 78a5d7d43634..baebaaa995c1 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -460,6 +460,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
qdisc_drop(head, sch);
slot_queue_add(slot, skb);
+ qdisc_tree_reduce_backlog(sch, 0, delta);
return NET_XMIT_CN;
}
@@ -491,8 +492,10 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
/* Return Congestion Notification only if we dropped a packet
* from this flow.
*/
- if (qlen != slot->qlen)
+ if (qlen != slot->qlen) {
+ qdisc_tree_reduce_backlog(sch, 0, dropped - qdisc_pkt_len(skb));
return NET_XMIT_CN;
+ }
/* As we dropped a packet, better let upper stack know this */
qdisc_tree_reduce_backlog(sch, 1, dropped);
@@ -767,9 +770,10 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
q->ht = sfq_alloc(sizeof(q->ht[0]) * q->divisor);
q->slots = sfq_alloc(sizeof(q->slots[0]) * q->maxflows);
if (!q->ht || !q->slots) {
- sfq_destroy(sch);
+ /* Note: sfq_destroy() will be called by our caller */
return -ENOMEM;
}
+
for (i = 0; i < q->divisor; i++)
q->ht[i] = SFQ_EMPTY_SLOT;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 7c9545f1a391..8e7b508914c5 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -431,12 +431,13 @@ static int tbf_init(struct Qdisc *sch, struct nlattr *opt)
{
struct tbf_sched_data *q = qdisc_priv(sch);
+ qdisc_watchdog_init(&q->watchdog, sch);
+ q->qdisc = &noop_qdisc;
+
if (opt == NULL)
return -EINVAL;
q->t_c = ktime_to_ns(ktime_get());
- qdisc_watchdog_init(&q->watchdog, sch);
- q->qdisc = &noop_qdisc;
return tbf_change(sch, opt);
}
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 8ad13ba731b9..7f47fbdeb414 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -331,7 +331,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
rt = (struct rt6_info *)dst;
t->dst = dst;
- t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
+ t->dst_cookie = rt6_get_cookie(rt);
pr_debug("rt6_dst:%pI6 rt6_src:%pI6\n", &rt->rt6i_dst.addr,
&fl6->saddr);
} else {
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index a6d54a9a1133..c28716452211 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1752,6 +1752,7 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct
return -EMSGSIZE;
id = nlmsg_data(nlh);
+ memset(&id->sa_id, 0, sizeof(id->sa_id));
memcpy(&id->sa_id.daddr, &x->id.daddr, sizeof(x->id.daddr));
id->sa_id.spi = x->id.spi;
id->sa_id.family = x->props.family;
@@ -2552,6 +2553,7 @@ static int xfrm_notify_sa(struct xfrm_state *x, const struct km_event *c)
struct nlattr *attr;
id = nlmsg_data(nlh);
+ memset(id, 0, sizeof(*id));
memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr));
id->spi = x->id.spi;
id->family = x->props.family;
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 9d9c5b905b35..2241d036b63a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -798,6 +798,7 @@ static int number_prefix(const char *sym)
* where the '1' can be any number including several digits.
* The $ syntax is for sections where ld append a dot number
* to make section name unique.
+ * "*foo*" will match a string that contains "foo"
*/
static int match(const char *sym, const char * const pat[])
{
@@ -806,8 +807,17 @@ static int match(const char *sym, const char * const pat[])
p = *pat++;
const char *endp = p + strlen(p) - 1;
+ /* "*foo*" */
+ if (*p == '*' && *endp == '*') {
+ char *here, *bare = strndup(p + 1, strlen(p) - 2);
+
+ here = strstr(sym, bare);
+ free(bare);
+ if (here != NULL)
+ return 1;
+ }
/* "*foo" */
- if (*p == '*') {
+ else if (*p == '*') {
if (strrcmp(sym, p + 1) == 0)
return 1;
}
@@ -920,6 +930,10 @@ static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL };
static const char *init_exit_sections[] =
{ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
+/* all text sections */
+static const char *const text_sections[] = { ALL_INIT_TEXT_SECTIONS,
+ ALL_EXIT_TEXT_SECTIONS, TEXT_SECTIONS, NULL };
+
/* data section */
static const char *data_sections[] = { DATA_SECTIONS, NULL };
@@ -938,6 +952,7 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL };
static const char *head_sections[] = { ".head.text*", NULL };
static const char *linker_symbols[] =
{ "__init_begin", "_sinittext", "_einittext", NULL };
+static const char *const optim_symbols[] = { "*.constprop.*", NULL };
enum mismatch {
TEXT_TO_ANY_INIT,
@@ -1095,6 +1110,17 @@ static const struct sectioncheck *section_mismatch(
* This pattern is identified by
* refsymname = __init_begin, _sinittext, _einittext
*
+ * Pattern 5:
+ * GCC may optimize static inlines when fed constant arg(s) resulting
+ * in functions like cpumask_empty() -- generating an associated symbol
+ * cpumask_empty.constprop.3 that appears in the audit. If the const that
+ * is passed in comes from __init, like say nmi_ipi_mask, we get a
+ * meaningless section warning. May need to add isra symbols too...
+ * This pattern is identified by
+ * tosec = init section
+ * fromsec = text section
+ * refsymname = *.constprop.*
+ *
**/
static int secref_whitelist(const struct sectioncheck *mismatch,
const char *fromsec, const char *fromsym,
@@ -1127,6 +1153,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch,
if (match(tosym, linker_symbols))
return 0;
+ /* Check for pattern 5 */
+ if (match(fromsec, text_sections) &&
+ match(tosec, init_sections) &&
+ match(fromsym, optim_symbols))
+ return 0;
+
return 1;
}
diff --git a/security/keys/key.c b/security/keys/key.c
index 07cd1fe2a496..58ebea254519 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -901,6 +901,16 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
*/
__key_link_end(keyring, &index_key, edit);
+ key = key_ref_to_ptr(key_ref);
+ if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) {
+ ret = wait_for_key_construction(key, true);
+ if (ret < 0) {
+ key_ref_put(key_ref);
+ key_ref = ERR_PTR(ret);
+ goto error_free_prep;
+ }
+ }
+
key_ref = __key_update(key_ref, &prep);
goto error_free_prep;
}
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index edc3f3c32324..4598617c66de 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -735,6 +735,11 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
key = key_ref_to_ptr(key_ref);
+ if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
+ ret = -ENOKEY;
+ goto error2;
+ }
+
/* see if we can read it directly */
ret = key_permission(key_ref, KEY_NEED_READ);
if (ret == 0)
diff --git a/sound/core/control.c b/sound/core/control.c
index 665020b7c82e..fdffe37d40b8 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1087,7 +1087,7 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
mutex_lock(&ue->card->user_ctl_lock);
change = ue->tlv_data_size != size;
if (!change)
- change = memcmp(ue->tlv_data, new_data, size);
+ change = memcmp(ue->tlv_data, new_data, size) != 0;
kfree(ue->tlv_data);
ue->tlv_data = new_data;
ue->tlv_data_size = size;
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 7825e7e69ab4..a3988a4bcfd6 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1260,6 +1260,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client,
struct snd_seq_client_port *port;
struct snd_seq_port_info info;
struct snd_seq_port_callback *callback;
+ int port_idx;
if (copy_from_user(&info, arg, sizeof(info)))
return -EFAULT;
@@ -1273,7 +1274,9 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client,
return -ENOMEM;
if (client->type == USER_CLIENT && info.kernel) {
- snd_seq_delete_port(client, port->addr.port);
+ port_idx = port->addr.port;
+ snd_seq_port_unlock(port);
+ snd_seq_delete_port(client, port_idx);
return -EINVAL;
}
if (client->type == KERNEL_CLIENT) {
@@ -1295,6 +1298,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client,
snd_seq_set_port_info(port, &info);
snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port);
+ snd_seq_port_unlock(port);
if (copy_to_user(arg, &info, sizeof(info)))
return -EFAULT;
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index 12ba83367b1b..ba5752ee9af3 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -23,8 +23,6 @@
#include <sound/core.h>
#include "seq_lock.h"
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
/* wait until all locks are released */
void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
{
@@ -42,5 +40,3 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
}
EXPORT_SYMBOL(snd_use_lock_sync_helper);
-
-#endif
diff --git a/sound/core/seq/seq_lock.h b/sound/core/seq/seq_lock.h
index 54044bc2c9ef..ac38031c370e 100644
--- a/sound/core/seq/seq_lock.h
+++ b/sound/core/seq/seq_lock.h
@@ -3,8 +3,6 @@
#include <linux/sched.h>
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
typedef atomic_t snd_use_lock_t;
/* initialize lock */
@@ -20,14 +18,4 @@ typedef atomic_t snd_use_lock_t;
void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line);
#define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__)
-#else /* SMP || CONFIG_SND_DEBUG */
-
-typedef spinlock_t snd_use_lock_t; /* dummy */
-#define snd_use_lock_init(lockp) /**/
-#define snd_use_lock_use(lockp) /**/
-#define snd_use_lock_free(lockp) /**/
-#define snd_use_lock_sync(lockp) /**/
-
-#endif /* SMP || CONFIG_SND_DEBUG */
-
#endif /* __SND_SEQ_LOCK_H */
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 9c1c8d50f593..1ddae911255c 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -122,7 +122,9 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp)
}
-/* create a port, port number is returned (-1 on failure) */
+/* create a port, port number is returned (-1 on failure);
+ * the caller needs to unref the port via snd_seq_port_unlock() appropriately
+ */
struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
int port)
{
@@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
snd_use_lock_init(&new_port->use_lock);
port_subs_info_init(&new_port->c_src);
port_subs_info_init(&new_port->c_dest);
+ snd_use_lock_use(&new_port->use_lock);
num = port >= 0 ? port : 0;
mutex_lock(&client->ports_mutex);
@@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
list_add_tail(&new_port->list, &p->list);
client->num_ports++;
new_port->addr.port = num; /* store the port number in the port */
+ sprintf(new_port->name, "port-%d", num);
write_unlock_irqrestore(&client->ports_lock, flags);
mutex_unlock(&client->ports_mutex);
- sprintf(new_port->name, "port-%d", num);
return new_port;
}
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index ced54249c171..2086353ec6af 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3438,6 +3438,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI),
SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1b8fa72a6302..5c2b5c949c78 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2285,6 +2285,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
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, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c
index fd55da7cb9d4..70ab35744aba 100644
--- a/sound/soc/codecs/adau1977.c
+++ b/sound/soc/codecs/adau1977.c
@@ -968,7 +968,7 @@ int adau1977_probe(struct device *dev, struct regmap *regmap,
if (adau1977->dvdd_reg)
power_off_mask = ~0;
else
- power_off_mask = ~ADAU1977_BLOCK_POWER_SAI_LDO_EN;
+ power_off_mask = (unsigned int)~ADAU1977_BLOCK_POWER_SAI_LDO_EN;
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
power_off_mask, 0x00);
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index c5a0e8af8226..60465646fed8 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -333,8 +333,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
* The transmitter bit clock and frame sync are to be
* used by both the transmitter and receiver.
*/
- regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
- ~FSL_SAI_CR2_SYNC);
+ regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 0);
regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
FSL_SAI_CR2_SYNC);
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 9bfef55d77d1..3043d576856b 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -590,8 +590,8 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
else
clkrate = clk_round_rate(ssi_private->baudclk, tmprate);
- do_div(clkrate, factor);
- afreq = (u32)clkrate / (i + 1);
+ clkrate /= factor;
+ afreq = clkrate / (i + 1);
if (freq == afreq)
sub = 0;
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 267717aa96c1..46f9beb6b273 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -67,7 +67,7 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
{
ssize_t ret;
char *buf;
- int port = (int)file->private_data;
+ uintptr_t port = (uintptr_t)file->private_data;
u32 pdcr, ptcr;
if (audmux_clk) {
@@ -147,7 +147,7 @@ static const struct file_operations audmux_debugfs_fops = {
static void audmux_debugfs_init(void)
{
- int i;
+ uintptr_t i;
char buf[20];
audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
@@ -157,10 +157,10 @@ static void audmux_debugfs_init(void)
}
for (i = 0; i < MX31_AUDMUX_PORT7_SSI_PINS_7 + 1; i++) {
- snprintf(buf, sizeof(buf), "ssi%d", i);
+ snprintf(buf, sizeof(buf), "ssi%lu", i);
if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
(void *)i, &audmux_debugfs_fops))
- pr_warning("Failed to create AUDMUX port %d debugfs file\n",
+ pr_warning("Failed to create AUDMUX port %lu debugfs file\n",
i);
}
}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 9fa664de8580..0b44e605c1d2 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -150,6 +150,10 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n",
be->dai_link->name, event, dir);
+ if ((event == SND_SOC_DAPM_STREAM_STOP) &&
+ (be->dpcm[dir].users >= 1))
+ continue;
+
snd_soc_dapm_stream_event(be, dir, event);
}
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 8887f4e19956..32ed66722c54 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -219,6 +219,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
struct usb_interface_descriptor *altsd;
void *control_header;
int i, protocol;
+ int rest_bytes;
/* find audiocontrol interface */
host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
@@ -233,6 +234,15 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
return -EINVAL;
}
+ rest_bytes = (void *)(host_iface->extra + host_iface->extralen) -
+ control_header;
+
+ /* just to be sure -- this shouldn't hit at all */
+ if (rest_bytes <= 0) {
+ dev_err(&dev->dev, "invalid control header\n");
+ return -EINVAL;
+ }
+
switch (protocol) {
default:
dev_warn(&dev->dev,
@@ -243,11 +253,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
case UAC_VERSION_1: {
struct uac1_ac_header_descriptor *h1 = control_header;
+ if (rest_bytes < sizeof(*h1)) {
+ dev_err(&dev->dev, "too short v1 buffer descriptor\n");
+ return -EINVAL;
+ }
+
if (!h1->bInCollection) {
dev_info(&dev->dev, "skipping empty audio interface (v1)\n");
return -EINVAL;
}
+ if (rest_bytes < h1->bLength) {
+ dev_err(&dev->dev, "invalid buffer length (v1)\n");
+ return -EINVAL;
+ }
+
if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
dev_err(&dev->dev, "invalid UAC_HEADER (v1)\n");
return -EINVAL;
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 5d249caf3349..6d7605db36d0 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -533,6 +533,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
if (size < sizeof(scale))
return -ENOMEM;
+ if (cval->min_mute)
+ scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE;
scale[2] = cval->dBmin;
scale[3] = cval->dBmax;
if (copy_to_user(_tlv, scale, sizeof(scale)))
@@ -2156,6 +2158,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
{
+ /* kill pending URBs */
+ snd_usb_mixer_disconnect(&mixer->list);
+
kfree(mixer->id_elems);
if (mixer->urb) {
kfree(mixer->urb->transfer_buffer);
@@ -2492,8 +2497,13 @@ void snd_usb_mixer_disconnect(struct list_head *p)
struct usb_mixer_interface *mixer;
mixer = list_entry(p, struct usb_mixer_interface, list);
- usb_kill_urb(mixer->urb);
- usb_kill_urb(mixer->rc_urb);
+ if (mixer->disconnected)
+ return;
+ if (mixer->urb)
+ usb_kill_urb(mixer->urb);
+ if (mixer->rc_urb)
+ usb_kill_urb(mixer->rc_urb);
+ mixer->disconnected = true;
}
#ifdef CONFIG_PM
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 73b1f649447b..483cbe89430a 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -23,6 +23,8 @@ struct usb_mixer_interface {
u8 audigy2nx_leds[3];
u8 xonar_u1_status;
+
+ bool disconnected;
};
#define MAX_CHANNELS 16 /* max logical channels */
@@ -53,6 +55,7 @@ struct usb_mixer_elem_info {
int cached;
int cache_val[MAX_CHANNELS];
u8 initialized;
+ u8 min_mute;
};
int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 10ef6ce8f8bb..89d32f066561 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -1759,6 +1759,12 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
if (unitid == 7 && cval->control == UAC_FU_VOLUME)
snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
break;
+ /* lowest playback value is muted on C-Media devices */
+ case USB_ID(0x0d8c, 0x000c):
+ case USB_ID(0x0d8c, 0x0014):
+ if (strstr(kctl->id.name, "Playback"))
+ cval->min_mute = 1;
+ break;
}
}
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 3ccf6e14f89b..8c8ac8c255a9 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -670,7 +670,7 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser,
ui_browser__gotorc(browser, row, column + 1);
SLsmg_draw_hline(2);
- if (row++ == 0)
+ if (++row == 0)
goto out;
} else
row = 0;
Attachment:
signature.asc
Description: Digital signature