Merge tag 'drm-for-v4.17' of git://people.freedesktop.org/~airlied/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 2 Apr 2018 14:59:23 +0000 (07:59 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 2 Apr 2018 14:59:23 +0000 (07:59 -0700)
Pull drm updates from Dave Airlie:
 "Cannonlake and Vega12 support are probably the two major things. This
  pull lacks nouveau, Ben had some unforseen leave and a few other
  blockers so we'll see how things look or maybe leave it for this merge
  window.

  core:
   - Device links to handle sound/gpu pm dependency
   - Color encoding/range properties
   - Plane clipping into plane check helper
   - Backlight helpers
   - DP TP4 + HBR3 helper support

  amdgpu:
   - Vega12 support
   - Enable DC by default on all supported GPUs
   - Powerplay restructuring and cleanup
   - DC bandwidth calc updates
   - DC backlight on pre-DCE11
   - TTM backing store dropping support
   - SR-IOV fixes
   - Adding "wattman" like functionality
   - DC crc support
   - Improved DC dual-link handling

  amdkfd:
   - GPUVM support for dGPU
   - KFD events for dGPU
   - Enable PCIe atomics for dGPUs
   - HSA process eviction support
   - Live-lock fixes for process eviction
   - VM page table allocation fix for large-bar systems

  panel:
   - Raydium RM68200
   - AUO G104SN02 V2
   - KEO TX31D200VM0BAA
   - ARM Versatile panels

  i915:
   - Cannonlake support enabled
   - AUX-F port support added
   - Icelake base enabling until internal milestone of forcewake support
   - Query uAPI interface (used for GPU topology information currently)
   - Compressed framebuffer support for sprites
   - kmem cache shrinking when GPU is idle
   - Avoid boosting GPU when waited item is being processed already
   - Avoid retraining LSPCON link unnecessarily
   - Decrease request signaling latency
   - Deprecation of I915_SET_COLORKEY_NONE
   - Kerneldoc and compiler warning cleanup for upcoming CI enforcements
   - Full range ycbcr toggling
   - HDCP support

  i915/gvt:
   - Big refactor for shadow ppgtt
   - KBL context save/restore via LRI cmd (Weinan)
   - Properly unmap dma for guest page (Changbin)

  vmwgfx:
   - Lots of various improvements

  etnaviv:
   - Use the drm gpu scheduler
   - prep work for GC7000L support

  vc4:
   - fix alpha blending
   - Expose perf counters to userspace

  pl111:
   - Bandwidth checking/limiting
   - Versatile panel support

  sun4i:
   - A83T HDMI support
   - A80 support
   - YUV plane support
   - H3/H5 HDMI support

  omapdrm:
   - HPD support for DVI connector
   - remove lots of static variables

  msm:
   - DSI updates from 10nm / SDM845
   - fix for race condition with a3xx/a4xx fence completion irq
   - some refactoring/prep work for eventual a6xx support (ie. when we
     have a userspace)
   - a5xx debugfs enhancements
   - some mdp5 fixes/cleanups to prepare for eventually merging
     writeback
   - support (ie. when we have a userspace)

  tegra:
   - mmap() fixes for fbdev devices
   - Overlay plane for hw cursor fix
   - dma-buf cache maintenance support

  mali-dp:
   - YUV->RGB conversion support

  rockchip:
   - rk3399/chromebook fixes and improvements

  rcar-du:
   - LVDS support move to drm bridge
   - DT bindings for R8A77995
   - Driver/DT support for R8A77970

  tilcdc:
   - DRM panel support"

* tag 'drm-for-v4.17' of git://people.freedesktop.org/~airlied/linux: (1646 commits)
  drm/i915: Fix hibernation with ACPI S0 target state
  drm/i915/execlists: Use a locked clear_bit() for synchronisation with interrupt
  drm/i915: Specify which engines to reset following semaphore/event lockups
  drm/i915/dp: Write to SET_POWER dpcd to enable MST hub.
  drm/amdkfd: Use ordered workqueue to restore processes
  drm/amdgpu: Fix acquiring VM on large-BAR systems
  drm/amd/pp: clean header file hwmgr.h
  drm/amd/pp: use mlck_table.count for array loop index limit
  drm: Fix uabi regression by allowing garbage mode->type from userspace
  drm/amdgpu: Add an ATPX quirk for hybrid laptop
  drm/amdgpu: fix spelling mistake: "asssert" -> "assert"
  drm/amd/pp: Add new asic support in pp_psm.c
  drm/amd/pp: Clean up powerplay code on Vega12
  drm/amd/pp: Add smu irq handlers for legacy asics
  drm/amd/pp: Fix set wrong temperature range on smu7
  drm/amdgpu: Don't change preferred domian when fallback GTT v5
  drm/vmwgfx: Bump version patchlevel and date
  drm/vmwgfx: use monotonic event timestamps
  drm/vmwgfx: Unpin the screen object backup buffer when not used
  drm/vmwgfx: Stricter count of legacy surface device resources
  ...

163 files changed:
.mailmap
Documentation/isdn/INTERFACE.CAPI
Documentation/isdn/README
Documentation/isdn/README.FAQ
Documentation/isdn/README.gigaset
MAINTAINERS
Makefile
arch/arm/Kconfig.debug
arch/arm/boot/deflate_xip_data.sh
arch/arm/boot/dts/aspeed-g4.dtsi
arch/arm/boot/dts/aspeed-g5.dtsi
arch/arm/boot/dts/imx7d-sdb.dts
arch/arm/boot/dts/rk3288.dtsi
arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
arch/arm/include/asm/vdso.h
arch/arm/kernel/vdso.c
arch/arm/mach-davinci/board-omapl138-hawk.c
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/include/plat/sram.h
arch/arm/plat-omap/sram.c
arch/arm/vfp/vfpmodule.c
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/powerpc/include/asm/book3s/64/mmu.h
arch/powerpc/include/asm/book3s/64/tlbflush-radix.h
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/mmu_context.h
arch/powerpc/kernel/dt_cpu_ftrs.c
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/irq.c
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/kvm/book3s_hv_rm_mmu.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/mm/hash_native_64.c
arch/powerpc/mm/mmu_context_book3s64.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/tlb-radix.c
arch/x86/events/intel/ds.c
arch/x86/include/asm/alternative.h
arch/x86/include/asm/hw_irq.h
arch/x86/include/asm/uv/uv_mmrs.h
arch/x86/kernel/idt.c
arch/x86/kernel/kvm.c
arch/x86/kvm/vmx.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/purgatory/Makefile
drivers/atm/iphase.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
drivers/gpu/drm/tegra/dc.c
drivers/i2c/busses/i2c-stm32f7.c
drivers/infiniband/core/addr.c
drivers/infiniband/core/device.c
drivers/infiniband/core/ucma.c
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mr.c
drivers/infiniband/hw/qedr/main.c
drivers/infiniband/hw/qedr/verbs.c
drivers/md/dm-mpath.c
drivers/md/dm.c
drivers/mtd/chips/jedec_probe.c
drivers/mtd/nand/atmel/pmecc.c
drivers/net/bonding/bond_main.c
drivers/net/dsa/mt7530.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
drivers/net/ethernet/mellanox/mlx4/en_main.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/mellanox/mlx5/core/Kconfig
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/netronome/nfp/bpf/jit.c
drivers/net/ethernet/qlogic/qede/qede_fp.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/hyperv/rndis_filter.c
drivers/net/team/team.c
drivers/net/usb/lan78xx.c
drivers/net/usb/qmi_wwan.c
drivers/net/vrf.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
drivers/net/wireless/intel/iwlwifi/cfg/9000.c
drivers/net/wireless/intel/iwlwifi/fw/file.h
drivers/net/wireless/intel/iwlwifi/iwl-config.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
drivers/scsi/hosts.c
drivers/scsi/hpsa.c
drivers/scsi/hpsa.h
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/megaraid/megaraid_sas_fusion.c
drivers/scsi/sd.c
drivers/scsi/virtio_scsi.c
drivers/vhost/net.c
drivers/vhost/vhost.c
fs/ceph/file.c
include/linux/if_vlan.h
include/linux/net_dim.h
include/net/llc_conn.h
include/net/netfilter/nf_tables.h
include/net/sch_generic.h
include/rdma/ib_addr.h
include/scsi/scsi_host.h
ipc/shm.c
kernel/events/hw_breakpoint.c
mm/kmemleak.c
mm/memcontrol.c
mm/page_owner.c
mm/slab.c
mm/vmstat.c
net/batman-adv/gateway_client.c
net/batman-adv/multicast.c
net/core/dev.c
net/core/skbuff.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_vti.c
net/ipv4/netfilter/Makefile
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/netfilter/nf_socket_ipv4.c
net/ipv4/syncookies.c
net/ipv4/tcp_input.c
net/ipv6/ip6_output.c
net/ipv6/ip6_vti.c
net/ipv6/netfilter/nf_socket_ipv6.c
net/ipv6/route.c
net/ipv6/seg6_iptunnel.c
net/ipv6/syncookies.c
net/llc/llc_c_ac.c
net/llc/llc_conn.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_set_hash.c
net/netlink/af_netlink.c
net/sched/act_api.c
net/sched/sch_generic.c
net/smc/smc_clc.c
net/strparser/strparser.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_output.c
scripts/adjust_autoksyms.sh
scripts/package/builddeb
scripts/package/mkspec
sound/core/oss/pcm_oss.c
sound/core/pcm_native.c
sound/usb/quirks.c
tools/bpf/bpftool/map.c
tools/objtool/check.c

index e18cab73e209a7b3057cfd672356dab6d9846483..a2ce89a456c225610d38ca38499dbbe5dfd1a703 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -62,6 +62,7 @@ Frank Zago <fzago@systemfabricworks.com>
 Greg Kroah-Hartman <greg@echidna.(none)>
 Greg Kroah-Hartman <gregkh@suse.de>
 Greg Kroah-Hartman <greg@kroah.com>
+Gregory CLEMENT <gregory.clement@bootlin.com> <gregory.clement@free-electrons.com>
 Henk Vergonet <Henk.Vergonet@gmail.com>
 Henrik Kretzschmar <henne@nachtwindheim.de>
 Henrik Rydberg <rydberg@bitmath.org>
index 1688b5a1fd77ac1de87ae4822713d02a9164b0bf..021aa9cf139d9155b25d96f8de709c2cbf5a2824 100644 (file)
@@ -18,7 +18,7 @@ corresponding hardware driver. Kernel CAPI then forwards CAPI messages in both
 directions between the application and the hardware driver.
 
 Format and semantics of CAPI messages are specified in the CAPI 2.0 standard.
-This standard is freely available from http://www.capi.org.
+This standard is freely available from https://www.capi.org.
 
 
 2. Driver and Device Registration
index 32d4e80c2c03fd09bac20abe054e0a06a8751082..74bd2bdb455b94e91398c3922c69cbaafd961bc1 100644 (file)
@@ -33,10 +33,10 @@ README for the ISDN-subsystem
      de.alt.comm.isdn4linux
 
   There is also a well maintained FAQ in English available at
-     http://www.mhessler.de/i4lfaq/
+     https://www.mhessler.de/i4lfaq/
   It can be viewed online, or downloaded in sgml/text/html format.
   The FAQ can also be viewed online at
-     http://www.isdn4linux.de/faq/
+     https://www.isdn4linux.de/faq/i4lfaq.html
   or downloaded from
      ftp://ftp.isdn4linux.de/pub/isdn4linux/FAQ/
 
index 356f7944641d50d71fd0d737a725a6a3d715a0dc..e5dd1addacdd2a05f0ec37d466b8a6caac98ebd6 100644 (file)
@@ -8,9 +8,9 @@ You find it in:
 
 In case you just want to see the FAQ online, or download the newest version,
 you can have a look at my website:
-http://www.mhessler.de/i4lfaq/ (view + download)
+https://www.mhessler.de/i4lfaq/ (view + download)
 or:
-http://www.isdn4linux.de/faq/ (view)
+https://www.isdn4linux.de/faq/4lfaq.html (view)
 
 As the extension tells, the FAQ is in SGML format, and you can convert it
 into text/html/... format by using the sgml2txt/sgml2html/... tools.
index 7534c6039adc824e63d6992455187945d61cf115..9b1ce277ca3d58a04a3f30c25f2a3a09f9e80745 100644 (file)
@@ -29,8 +29,9 @@ GigaSet 307x Device Driver
         T-Com Sinus 721 data
         Chicago 390 USB (KPN)
 
-     See also http://www.erbze.info/sinus_gigaset.htm and
-              http://gigaset307x.sourceforge.net/
+     See also http://www.erbze.info/sinus_gigaset.htm
+       (archived at https://web.archive.org/web/20100717020421/http://www.erbze.info:80/sinus_gigaset.htm ) and
+       http://gigaset307x.sourceforge.net/
 
      We had also reports from users of Gigaset M105 who could use the drivers
      with SX 100 and CX 100 ISDN bases (only in unimodem mode, see section 2.5.)
@@ -52,7 +53,7 @@ GigaSet 307x Device Driver
      to use CAPI 2.0 or ISDN4Linux for ISDN connections (voice or data).
 
      There are some user space tools available at
-     http://sourceforge.net/projects/gigaset307x/
+     https://sourceforge.net/projects/gigaset307x/
      which provide access to additional device specific functions like SMS,
      phonebook or call journal.
 
@@ -202,7 +203,7 @@ GigaSet 307x Device Driver
      You can use some configuration tool of your distribution to configure this
      "modem" or configure pppd/wvdial manually. There are some example ppp
      configuration files and chat scripts in the gigaset-VERSION/ppp directory
-     in the driver packages from http://sourceforge.net/projects/gigaset307x/.
+     in the driver packages from https://sourceforge.net/projects/gigaset307x/.
      Please note that the USB drivers are not able to change the state of the
      control lines. This means you must use "Stupid Mode" if you are using
      wvdial or you should use the nocrtscts option of pppd.
@@ -361,7 +362,7 @@ GigaSet 307x Device Driver
      ---------------------------
      If you can't solve problems with the driver on your own, feel free to
      use one of the forums, bug trackers, or mailing lists on
-         http://sourceforge.net/projects/gigaset307x
+         https://sourceforge.net/projects/gigaset307x
      or write an electronic mail to the maintainers.
 
      Try to provide as much information as possible, such as
@@ -391,11 +392,12 @@ GigaSet 307x Device Driver
 4.   Links, other software
      ---------------------
      - Sourceforge project developing this driver and associated tools
-         http://sourceforge.net/projects/gigaset307x
+         https://sourceforge.net/projects/gigaset307x
      - Yahoo! Group on the Siemens Gigaset family of devices
-         http://de.groups.yahoo.com/group/Siemens-Gigaset
+         https://de.groups.yahoo.com/group/Siemens-Gigaset
      - Siemens Gigaset/T-Sinus compatibility table
          http://www.erbze.info/sinus_gigaset.htm
+           (archived at https://web.archive.org/web/20100717020421/http://www.erbze.info:80/sinus_gigaset.htm )
 
 
 5.   Credits
index 004d2c14ee4b4413108f5ac1b241ce04f61d3c93..06b33d2b74a12455e7cd4eeb7f639712d44635a7 100644 (file)
@@ -1062,41 +1062,42 @@ ARM PORT
 M:     Russell King <linux@armlinux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.armlinux.org.uk/
-S:     Maintained
+S:     Odd Fixes
 T:     git git://git.armlinux.org.uk/~rmk/linux-arm.git
 F:     arch/arm/
+X:     arch/arm/boot/dts/
 
 ARM PRIMECELL AACI PL041 DRIVER
 M:     Russell King <linux@armlinux.org.uk>
-S:     Maintained
+S:     Odd Fixes
 F:     sound/arm/aaci.*
 
 ARM PRIMECELL BUS SUPPORT
 M:     Russell King <linux@armlinux.org.uk>
-S:     Maintained
+S:     Odd Fixes
 F:     drivers/amba/
 F:     include/linux/amba/bus.h
 
 ARM PRIMECELL CLCD PL110 DRIVER
 M:     Russell King <linux@armlinux.org.uk>
-S:     Maintained
+S:     Odd Fixes
 F:     drivers/video/fbdev/amba-clcd.*
 
 ARM PRIMECELL KMI PL050 DRIVER
 M:     Russell King <linux@armlinux.org.uk>
-S:     Maintained
+S:     Odd Fixes
 F:     drivers/input/serio/ambakmi.*
 F:     include/linux/amba/kmi.h
 
 ARM PRIMECELL MMCI PL180/1 DRIVER
 M:     Russell King <linux@armlinux.org.uk>
-S:     Maintained
+S:     Odd Fixes
 F:     drivers/mmc/host/mmci.*
 F:     include/linux/amba/mmci.h
 
 ARM PRIMECELL UART PL010 AND PL011 DRIVERS
 M:     Russell King <linux@armlinux.org.uk>
-S:     Maintained
+S:     Odd Fixes
 F:     drivers/tty/serial/amba-pl01*.c
 F:     include/linux/amba/serial.h
 
@@ -1154,7 +1155,7 @@ S:        Maintained
 F:     drivers/clk/sunxi/
 
 ARM/Allwinner sunXi SoC support
-M:     Maxime Ripard <maxime.ripard@free-electrons.com>
+M:     Maxime Ripard <maxime.ripard@bootlin.com>
 M:     Chen-Yu Tsai <wens@csie.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -4635,7 +4636,7 @@ F:        include/uapi/drm/drm*
 F:     include/linux/vga*
 
 DRM DRIVERS FOR ALLWINNER A10
-M:     Maxime Ripard  <maxime.ripard@free-electrons.com>
+M:     Maxime Ripard  <maxime.ripard@bootlin.com>
 L:     dri-devel@lists.freedesktop.org
 S:     Supported
 F:     drivers/gpu/drm/sun4i/
@@ -8444,7 +8445,7 @@ S:        Orphan
 F:     drivers/net/wireless/marvell/libertas/
 
 MARVELL MACCHIATOBIN SUPPORT
-M:     Russell King <rmk@armlinux.org.uk>
+M:     Russell King <linux@armlinux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org
 S:     Maintained
 F:     arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts
@@ -8457,7 +8458,7 @@ F:        drivers/net/ethernet/marvell/mv643xx_eth.*
 F:     include/linux/mv643xx.h
 
 MARVELL MV88X3310 PHY DRIVER
-M:     Russell King <rmk@armlinux.org.uk>
+M:     Russell King <linux@armlinux.org.uk>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/phy/marvell10g.c
@@ -12885,6 +12886,19 @@ S:     Maintained
 F:     drivers/net/ethernet/socionext/netsec.c
 F:     Documentation/devicetree/bindings/net/socionext-netsec.txt
 
+SOLIDRUN CLEARFOG SUPPORT
+M:     Russell King <linux@armlinux.org.uk>
+S:     Maintained
+F:     arch/arm/boot/dts/armada-388-clearfog*
+F:     arch/arm/boot/dts/armada-38x-solidrun-*
+
+SOLIDRUN CUBOX-I/HUMMINGBOARD SUPPORT
+M:     Russell King <linux@armlinux.org.uk>
+S:     Maintained
+F:     arch/arm/boot/dts/imx6*-cubox-i*
+F:     arch/arm/boot/dts/imx6*-hummingboard*
+F:     arch/arm/boot/dts/imx6*-sr-*
+
 SONIC NETWORK DRIVER
 M:     Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 L:     netdev@vger.kernel.org
@@ -13654,7 +13668,8 @@ S:      Supported
 F:     drivers/i2c/busses/i2c-tegra.c
 
 TEGRA IOMMU DRIVERS
-M:     Hiroshi Doyu <hdoyu@nvidia.com>
+M:     Thierry Reding <thierry.reding@gmail.com>
+L:     linux-tegra@vger.kernel.org
 S:     Supported
 F:     drivers/iommu/tegra*
 
index 7ba478ab8c82c0a4c0800fcc57921e541b15c8b9..363dd096e46e59ee60f3e446fdd9d59083f3a262 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 16
 SUBLEVEL = 0
-EXTRAVERSION = -rc7
+EXTRAVERSION =
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
@@ -487,6 +487,8 @@ CLANG_GCC_TC        := --gcc-toolchain=$(GCC_TOOLCHAIN)
 endif
 KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
 KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC)
+KBUILD_CFLAGS += $(call cc-option, -no-integrated-as)
+KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
 endif
 
 RETPOLINE_CFLAGS_GCC := -mindirect-branch=thunk-extern -mindirect-branch-register
@@ -743,8 +745,6 @@ KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare)
 # See modpost pattern 2
 KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
 KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
-KBUILD_CFLAGS += $(call cc-option, -no-integrated-as)
-KBUILD_AFLAGS += $(call cc-option, -no-integrated-as)
 else
 
 # These warnings generated too much noise in a regular build.
index 78a647080ebccca0ebeaa7117b9e703724a2eea7..199ebc1c4538e66700c8e8e2f49d0f5fbfb4c44b 100644 (file)
@@ -22,6 +22,7 @@ config ARM_PTDUMP_DEBUGFS
 
 config DEBUG_WX
        bool "Warn on W+X mappings at boot"
+       depends on MMU
        select ARM_PTDUMP_CORE
        ---help---
                Generate a warning if any W+X mappings are found at boot.
index 1189598a25ebb01dc13fbb03a510f0750d709398..5e7d758ebdd62722e7f453f92ff219f41c6b9b50 100755 (executable)
@@ -30,7 +30,7 @@ esac
 
 sym_val() {
        # extract hex value for symbol in $1
-       local val=$($NM "$VMLINUX" | sed -n "/ $1$/{s/ .*$//p;q}")
+       local val=$($NM "$VMLINUX" 2>/dev/null | sed -n "/ $1\$/{s/ .*$//p;q}")
        [ "$val" ] || { echo "can't find $1 in $VMLINUX" 1>&2; exit 1; }
        # convert from hex to decimal
        echo $((0x$val))
@@ -48,12 +48,12 @@ data_end=$(($_edata_loc - $base_offset))
 file_end=$(stat -c "%s" "$XIPIMAGE")
 if [ "$file_end" != "$data_end" ]; then
        printf "end of xipImage doesn't match with _edata_loc (%#x vs %#x)\n" \
-              $(($file_end + $base_offset)) $_edata_loc 2>&1
+              $(($file_end + $base_offset)) $_edata_loc 1>&2
        exit 1;
 fi
 
 # be ready to clean up
-trap 'rm -f "$XIPIMAGE.tmp"' 0 1 2 3
+trap 'rm -f "$XIPIMAGE.tmp"; exit 1' 1 2 3
 
 # substitute the data section by a compressed version
 $DD if="$XIPIMAGE" count=$data_start iflag=count_bytes of="$XIPIMAGE.tmp"
index b0d8431a3700378f2bd4f5b9daf97b6a952a8271..ae2b8c952e80d7102f9aa262c7422d676c390adf 100644 (file)
                };
        };
 
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x40000000 0>;
+       };
+
        ahb {
                compatible = "simple-bus";
                #address-cells = <1>;
index 40de3b66c33f56ad4d8f8981c2a88f8a6d73544b..2477ebc11d9db4dfdd62fe09fcdf6a00c9f80161 100644 (file)
                };
        };
 
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0>;
+       };
+
        ahb {
                compatible = "simple-bus";
                #address-cells = <1>;
index a7a5dc7b270083ffc6172a5d4cd499f74a7c67d6..e7d2db839d70790fe0ace3e62c6fcd3e9def6e59 100644 (file)
@@ -82,7 +82,7 @@
                enable-active-high;
        };
 
-       reg_usb_otg2_vbus: regulator-usb-otg1-vbus {
+       reg_usb_otg2_vbus: regulator-usb-otg2-vbus {
                compatible = "regulator-fixed";
                regulator-name = "usb_otg2_vbus";
                regulator-min-microvolt = <5000000>;
index 6102e4e7f35c15bcb809152453ef3ed82dd579d7..354aff45c1afca2dcec62e420602c01237c5b04e 100644 (file)
        i2s: i2s@ff890000 {
                compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s";
                reg = <0x0 0xff890000 0x0 0x10000>;
+               #sound-dai-cells = <0>;
                interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "rockchip,rk3288-dw-hdmi";
                reg = <0x0 0xff980000 0x0 0x20000>;
                reg-io-width = <4>;
+               #sound-dai-cells = <0>;
                rockchip,grf = <&grf>;
                interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru  PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>;
index 51e6f1d21c32b745957fe82dfc6eeeafb9b67bb7..b2758dd8ce438abdfd53a0a347f496b6d8ddbe7d 100644 (file)
@@ -42,7 +42,6 @@
 
 /dts-v1/;
 #include "sun6i-a31s.dtsi"
-#include "sunxi-common-regulators.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 
 / {
@@ -99,6 +98,7 @@
        pinctrl-0 = <&gmac_pins_rgmii_a>, <&gmac_phy_reset_pin_bpi_m2>;
        phy = <&phy1>;
        phy-mode = "rgmii";
+       phy-supply = <&reg_dldo1>;
        snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>; /* PA21 */
        snps,reset-active-low;
        snps,reset-delays-us = <0 10000 30000>;
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_bpi_m2>;
-       vmmc-supply = <&reg_vcc3v0>;
+       vmmc-supply = <&reg_dcdc1>;
        bus-width = <4>;
        cd-gpios = <&pio 0 4 GPIO_ACTIVE_HIGH>; /* PA4 */
        cd-inverted;
 &mmc2 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc2_pins_a>;
-       vmmc-supply = <&reg_vcc3v0>;
+       vmmc-supply = <&reg_aldo1>;
        mmc-pwrseq = <&mmc2_pwrseq>;
        bus-width = <4>;
        non-removable;
                reg = <0x68>;
                interrupt-parent = <&nmi_intc>;
                interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+               eldoin-supply = <&reg_dcdc1>;
+               x-powers,drive-vbus-en;
        };
 };
 
 
 #include "axp22x.dtsi"
 
+&reg_aldo1 {
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-wifi";
+};
+
+&reg_aldo2 {
+       regulator-always-on;
+       regulator-min-microvolt = <2500000>;
+       regulator-max-microvolt = <2500000>;
+       regulator-name = "vcc-gmac";
+};
+
+&reg_aldo3 {
+       regulator-always-on;
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-name = "avcc";
+};
+
 &reg_dc5ldo {
+       regulator-always-on;
        regulator-min-microvolt = <700000>;
        regulator-max-microvolt = <1320000>;
        regulator-name = "vdd-cpus";
        regulator-name = "vcc-dram";
 };
 
+&reg_dldo1 {
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-name = "vcc-mac";
+};
+
+&reg_dldo2 {
+       regulator-min-microvolt = <2800000>;
+       regulator-max-microvolt = <2800000>;
+       regulator-name = "avdd-csi";
+};
+
+&reg_dldo3 {
+       regulator-always-on;
+       regulator-min-microvolt = <3300000>;
+       regulator-max-microvolt = <3300000>;
+       regulator-name = "vcc-pb";
+};
+
+&reg_eldo1 {
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-name = "vdd-csi";
+       status = "okay";
+};
+
+&reg_ldo_io1 {
+       regulator-always-on;
+       regulator-min-microvolt = <1800000>;
+       regulator-max-microvolt = <1800000>;
+       regulator-name = "vcc-pm-cpus";
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins_a>;
index 9c99e817535ecd4cfa6013e8dffba974e94a2bae..5b85889f82eeb422400c039e8b5e8a2a6d4553b3 100644 (file)
@@ -12,8 +12,6 @@ struct mm_struct;
 
 void arm_install_vdso(struct mm_struct *mm, unsigned long addr);
 
-extern char vdso_start, vdso_end;
-
 extern unsigned int vdso_total_pages;
 
 #else /* CONFIG_VDSO */
index a4d6dc0f24273e15d18b53b23dbf1481f6b7cfc7..f4dd7f9663c10a704d3858de6beb538e5023cf78 100644 (file)
@@ -39,6 +39,8 @@
 
 static struct page **vdso_text_pagelist;
 
+extern char vdso_start[], vdso_end[];
+
 /* Total number of pages needed for the data and text portions of the VDSO. */
 unsigned int vdso_total_pages __ro_after_init;
 
@@ -197,13 +199,13 @@ static int __init vdso_init(void)
        unsigned int text_pages;
        int i;
 
-       if (memcmp(&vdso_start, "\177ELF", 4)) {
+       if (memcmp(vdso_start, "\177ELF", 4)) {
                pr_err("VDSO is not a valid ELF object!\n");
                return -ENOEXEC;
        }
 
-       text_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
-       pr_debug("vdso: %i text pages at base %p\n", text_pages, &vdso_start);
+       text_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
+       pr_debug("vdso: %i text pages at base %p\n", text_pages, vdso_start);
 
        /* Allocate the VDSO text pagelist */
        vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *),
@@ -218,7 +220,7 @@ static int __init vdso_init(void)
        for (i = 0; i < text_pages; i++) {
                struct page *page;
 
-               page = virt_to_page(&vdso_start + i * PAGE_SIZE);
+               page = virt_to_page(vdso_start + i * PAGE_SIZE);
                vdso_text_pagelist[i] = page;
        }
 
@@ -229,7 +231,7 @@ static int __init vdso_init(void)
 
        cntvct_ok = cntvct_functional();
 
-       patch_vdso(&vdso_start);
+       patch_vdso(vdso_start);
 
        return 0;
 }
index a3e78074be701a3a6abec03ff7e5586f79acfcbe..62eb7d6688900f244f546bd88da951e4ef934ac0 100644 (file)
@@ -127,8 +127,8 @@ static struct gpiod_lookup_table mmc_gpios_table = {
        .dev_id = "da830-mmc.0",
        .table = {
                /* CD: gpio3_12: gpio60: chip 1 contains gpio range 32-63*/
-               GPIO_LOOKUP("davinci_gpio.1", 28, "cd", GPIO_ACTIVE_LOW),
-               GPIO_LOOKUP("davinci_gpio.1", 29, "wp", GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP("davinci_gpio.0", 28, "cd", GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP("davinci_gpio.0", 29, "wp", GPIO_ACTIVE_LOW),
        },
 };
 
index 7e5d7a083707074b639dc35ba18c40a14312a38c..36cd23c8be9b0f147c87e952c101ef14b0b8db93 100644 (file)
@@ -133,6 +133,9 @@ static void __init u8500_init_machine(void)
        if (of_machine_is_compatible("st-ericsson,u8540"))
                of_platform_populate(NULL, u8500_local_bus_nodes,
                                     u8540_auxdata_lookup, NULL);
+       else
+               of_platform_populate(NULL, u8500_local_bus_nodes,
+                                    NULL, NULL);
 }
 
 static const char * stericsson_dt_platform_compat[] = {
index d443e481c3e94aeddcc82ec199a4be82e6bb06ca..8805a59bae538e1835860b08db17628c9b20b30a 100644 (file)
@@ -888,11 +888,8 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
        timer->irq = irq->start;
        timer->pdev = pdev;
 
-       /* Skip pm_runtime_enable for OMAP1 */
-       if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
-               pm_runtime_enable(dev);
-               pm_runtime_irq_safe(dev);
-       }
+       pm_runtime_enable(dev);
+       pm_runtime_irq_safe(dev);
 
        if (!timer->reserved) {
                ret = pm_runtime_get_sync(dev);
index fb061cf0d736d3203cf670d366cab227776e8264..30a07730807a86b2f5440702d17094b2f6a4bb26 100644 (file)
@@ -5,13 +5,4 @@ void omap_map_sram(unsigned long start, unsigned long size,
                        unsigned long skip, int cached);
 void omap_sram_reset(void);
 
-extern void *omap_sram_push_address(unsigned long size);
-
-/* Macro to push a function to the internal SRAM, using the fncpy API */
-#define omap_sram_push(funcp, size) ({                         \
-       typeof(&(funcp)) _res = NULL;                           \
-       void *_sram_address = omap_sram_push_address(size);     \
-       if (_sram_address)                                      \
-               _res = fncpy(_sram_address, &(funcp), size);    \
-       _res;                                                   \
-})
+extern void *omap_sram_push(void *funcp, unsigned long size);
index a5bc92d7e4765b81315379c41618fff7f84cbec2..921840acf65c83a5ac785ac5e514591a404a8a46 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/fncpy.h>
 #include <asm/tlb.h>
 #include <asm/cacheflush.h>
+#include <asm/set_memory.h>
 
 #include <asm/mach/map.h>
 
@@ -42,7 +43,7 @@ static void __iomem *omap_sram_ceil;
  * Note that fncpy requires the returned address to be aligned
  * to an 8-byte boundary.
  */
-void *omap_sram_push_address(unsigned long size)
+static void *omap_sram_push_address(unsigned long size)
 {
        unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
 
@@ -60,6 +61,30 @@ void *omap_sram_push_address(unsigned long size)
        return (void *)omap_sram_ceil;
 }
 
+void *omap_sram_push(void *funcp, unsigned long size)
+{
+       void *sram;
+       unsigned long base;
+       int pages;
+       void *dst = NULL;
+
+       sram = omap_sram_push_address(size);
+       if (!sram)
+               return NULL;
+
+       base = (unsigned long)sram & PAGE_MASK;
+       pages = PAGE_ALIGN(size) / PAGE_SIZE;
+
+       set_memory_rw(base, pages);
+
+       dst = fncpy(sram, funcp, size);
+
+       set_memory_ro(base, pages);
+       set_memory_x(base, pages);
+
+       return dst;
+}
+
 /*
  * The SRAM context is lost during off-idle and stack
  * needs to be reset.
@@ -75,6 +100,9 @@ void omap_sram_reset(void)
 void __init omap_map_sram(unsigned long start, unsigned long size,
                                 unsigned long skip, int cached)
 {
+       unsigned long base;
+       int pages;
+
        if (size == 0)
                return;
 
@@ -95,4 +123,10 @@ void __init omap_map_sram(unsigned long start, unsigned long size,
         */
        memset_io(omap_sram_base + omap_sram_skip, 0,
                  omap_sram_size - omap_sram_skip);
+
+       base = (unsigned long)omap_sram_base;
+       pages = PAGE_ALIGN(omap_sram_size) / PAGE_SIZE;
+
+       set_memory_ro(base, pages);
+       set_memory_x(base, pages);
 }
index 03c6a3c72f9ce6f71db5404b5469c8e5ab1c57be..4c375e11ae9531bec8b5a05bd14ab8424ccd6653 100644 (file)
@@ -648,7 +648,7 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
  */
 static int vfp_dying_cpu(unsigned int cpu)
 {
-       vfp_force_reload(cpu, current_thread_info());
+       vfp_current_hw_state[cpu] = NULL;
        return 0;
 }
 
index 03f195025390d6b8e32c4fb5cccf7045e1cf5069..204bdb9857b9cbd3517c0ff2307aa9af30ae2f8c 100644 (file)
        wlan_pd_n: wlan-pd-n {
                compatible = "regulator-fixed";
                regulator-name = "wlan_pd_n";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wlan_module_reset_l>;
 
-               /* Note the wlan_module_reset_l pinctrl */
                enable-active-high;
                gpio = <&gpio1 11 GPIO_ACTIVE_HIGH>;
 
@@ -983,12 +984,6 @@ ap_i2c_audio: &i2c8 {
        pinctrl-0 = <
                &ap_pwroff      /* AP will auto-assert this when in S3 */
                &clk_32k        /* This pin is always 32k on gru boards */
-
-               /*
-                * We want this driven low ASAP; firmware should help us, but
-                * we can help ourselves too.
-                */
-               &wlan_module_reset_l
        >;
 
        pcfg_output_low: pcfg-output-low {
@@ -1168,12 +1163,7 @@ ap_i2c_audio: &i2c8 {
                };
 
                wlan_module_reset_l: wlan-module-reset-l {
-                       /*
-                        * We want this driven low ASAP (As {Soon,Strongly} As
-                        * Possible), to avoid leakage through the powered-down
-                        * WiFi.
-                        */
-                       rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_output_low>;
+                       rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_pull_none>;
                };
 
                bt_host_wake_l: bt-host-wake-l {
index 2605118d4b4ce74755ced75843d91ca22ad38ce8..0b81ca1d07e7e900705d71f8e9cdacd5ce9b1217 100644 (file)
                        reg = <0x0 0xfe800000 0x0 0x100000>;
                        interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH 0>;
                        dr_mode = "otg";
-                       phys = <&u2phy0_otg>, <&tcphy0_usb3>;
-                       phy-names = "usb2-phy", "usb3-phy";
+                       phys = <&u2phy0_otg>;
+                       phy-names = "usb2-phy";
                        phy_type = "utmi_wide";
                        snps,dis_enblslpm_quirk;
                        snps,dis-u2-freeclk-exists-quirk;
                        reg = <0x0 0xfe900000 0x0 0x100000>;
                        interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>;
                        dr_mode = "otg";
-                       phys = <&u2phy1_otg>, <&tcphy1_usb3>;
-                       phy-names = "usb2-phy", "usb3-phy";
+                       phys = <&u2phy1_otg>;
+                       phy-names = "usb2-phy";
                        phy_type = "utmi_wide";
                        snps,dis_enblslpm_quirk;
                        snps,dis-u2-freeclk-exists-quirk;
index 0abeb0e2d616d5376646361836f63db0c8a32819..37671feb2bf60f761140c8765c65cce29600cccd 100644 (file)
@@ -87,6 +87,9 @@ typedef struct {
        /* Number of bits in the mm_cpumask */
        atomic_t active_cpus;
 
+       /* Number of users of the external (Nest) MMU */
+       atomic_t copros;
+
        /* NPU NMMU context */
        struct npu_context *npu_context;
 
index 8eea90f80e45a5ab00d189801d97b4f0e74eeb80..19b45ba6caf91536291becea14f4d1f73c937d8d 100644 (file)
@@ -47,9 +47,6 @@ extern void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmad
 #endif
 extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr);
 extern void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr);
-extern void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa,
-                                    unsigned long page_size);
-extern void radix__flush_tlb_lpid(unsigned long lpid);
 extern void radix__flush_tlb_all(void);
 extern void radix__flush_tlb_pte_p9_dd1(unsigned long old_pte, struct mm_struct *mm,
                                        unsigned long address);
index a2c5c95882cf08d3fda4b4c87cc13d73ba66a652..2e2bacbdf6ed486f1aad88f3a7f3c73c2fd898df 100644 (file)
@@ -203,6 +203,7 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTR_DAWR                   LONG_ASM_CONST(0x0400000000000000)
 #define CPU_FTR_DABRX                  LONG_ASM_CONST(0x0800000000000000)
 #define CPU_FTR_PMAO_BUG               LONG_ASM_CONST(0x1000000000000000)
+#define CPU_FTR_P9_TLBIE_BUG           LONG_ASM_CONST(0x2000000000000000)
 #define CPU_FTR_POWER9_DD1             LONG_ASM_CONST(0x4000000000000000)
 #define CPU_FTR_POWER9_DD2_1           LONG_ASM_CONST(0x8000000000000000)
 
@@ -465,7 +466,7 @@ static inline void cpu_feature_keys_init(void) { }
            CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
            CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
            CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | \
-           CPU_FTR_PKEY)
+           CPU_FTR_PKEY | CPU_FTR_P9_TLBIE_BUG)
 #define CPU_FTRS_POWER9_DD1 ((CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1) & \
                             (~CPU_FTR_SAO))
 #define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
index 051b3d63afe34b89b5da18bb000541a0870b0b38..3a15b6db950175a5d717249aa1355439f3065da0 100644 (file)
@@ -92,15 +92,23 @@ static inline void dec_mm_active_cpus(struct mm_struct *mm)
 static inline void mm_context_add_copro(struct mm_struct *mm)
 {
        /*
-        * On hash, should only be called once over the lifetime of
-        * the context, as we can't decrement the active cpus count
-        * and flush properly for the time being.
+        * If any copro is in use, increment the active CPU count
+        * in order to force TLB invalidations to be global as to
+        * propagate to the Nest MMU.
         */
-       inc_mm_active_cpus(mm);
+       if (atomic_inc_return(&mm->context.copros) == 1)
+               inc_mm_active_cpus(mm);
 }
 
 static inline void mm_context_remove_copro(struct mm_struct *mm)
 {
+       int c;
+
+       c = atomic_dec_if_positive(&mm->context.copros);
+
+       /* Detect imbalance between add and remove */
+       WARN_ON(c < 0);
+
        /*
         * Need to broadcast a global flush of the full mm before
         * decrementing active_cpus count, as the next TLBI may be
@@ -111,7 +119,7 @@ static inline void mm_context_remove_copro(struct mm_struct *mm)
         * for the time being. Invalidations will remain global if
         * used on hash.
         */
-       if (radix_enabled()) {
+       if (c == 0 && radix_enabled()) {
                flush_all_mm(mm);
                dec_mm_active_cpus(mm);
        }
index 945e2c29ad2daa55211ab747a1638f591cf5c19e..8ca5d5b74618371904ec7af9c436050ea35cdf0e 100644 (file)
@@ -709,6 +709,9 @@ static __init void cpufeatures_cpu_quirks(void)
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD1;
        else if ((version & 0xffffefff) == 0x004e0201)
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
+
+       if ((version & 0xffff0000) == 0x004e0000)
+               cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_BUG;
 }
 
 static void __init cpufeatures_setup_finished(void)
@@ -720,6 +723,9 @@ static void __init cpufeatures_setup_finished(void)
                cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE;
        }
 
+       /* Make sure powerpc_base_platform is non-NULL */
+       powerpc_base_platform = cur_cpu_spec->platform;
+
        system_registers.lpcr = mfspr(SPRN_LPCR);
        system_registers.hfscr = mfspr(SPRN_HFSCR);
        system_registers.fscr = mfspr(SPRN_FSCR);
index 3ac87e53b3da0fdc0c41bd967ac731f5d98d6efb..1ecfd8ffb0986aea0a3904eb2f2c348412021180 100644 (file)
@@ -706,7 +706,7 @@ EXC_COMMON_BEGIN(bad_addr_slb)
        ld      r3, PACA_EXSLB+EX_DAR(r13)
        std     r3, _DAR(r1)
        beq     cr6, 2f
-       li      r10, 0x480              /* fix trap number for I-SLB miss */
+       li      r10, 0x481              /* fix trap number for I-SLB miss */
        std     r10, _TRAP(r1)
 2:     bl      save_nvgprs
        addi    r3, r1, STACK_FRAME_OVERHEAD
index f880388477908d60bf314318cc090e12157729c8..061aa0f47bb100364fdb8e584f4d32a961440a49 100644 (file)
@@ -476,6 +476,14 @@ void force_external_irq_replay(void)
         */
        WARN_ON(!arch_irqs_disabled());
 
+       /*
+        * Interrupts must always be hard disabled before irq_happened is
+        * modified (to prevent lost update in case of interrupt between
+        * load and store).
+        */
+       __hard_irq_disable();
+       local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
+
        /* Indicate in the PACA that we have an interrupt to replay */
        local_paca->irq_happened |= PACA_IRQ_EE;
 }
index 5cb4e4687107e1204667e3314bee2ce49de32de7..5d9bafe9a37165bdfef6f5c0367b82904b6b1bd5 100644 (file)
@@ -157,6 +157,9 @@ static void kvmppc_radix_tlbie_page(struct kvm *kvm, unsigned long addr,
        asm volatile("ptesync": : :"memory");
        asm volatile(PPC_TLBIE_5(%0, %1, 0, 0, 1)
                     : : "r" (addr), "r" (kvm->arch.lpid) : "memory");
+       if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG))
+               asm volatile(PPC_TLBIE_5(%0, %1, 0, 0, 1)
+                            : : "r" (addr), "r" (kvm->arch.lpid) : "memory");
        asm volatile("ptesync": : :"memory");
 }
 
index 8888e625a9991c4ab3dea1e05f1a6aa8508b30e1..e1c083fbe43480d0b0990ce25f9cd6f52dce2bac 100644 (file)
@@ -473,6 +473,17 @@ static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues,
                        trace_tlbie(kvm->arch.lpid, 0, rbvalues[i],
                                kvm->arch.lpid, 0, 0, 0);
                }
+
+               if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+                       /*
+                        * Need the extra ptesync to make sure we don't
+                        * re-order the tlbie
+                        */
+                       asm volatile("ptesync": : :"memory");
+                       asm volatile(PPC_TLBIE_5(%0,%1,0,0,0) : :
+                                    "r" (rbvalues[0]), "r" (kvm->arch.lpid));
+               }
+
                asm volatile("eieio; tlbsync; ptesync" : : : "memory");
                kvm->arch.tlbie_lock = 0;
        } else {
index d33264697a31a13c2e84f2faaa02f055007a4948..f86a20270e508ef7108acc4fe02e556d40ff2378 100644 (file)
@@ -1557,6 +1557,24 @@ mc_cont:
        ptesync
 3:     stw     r5,VCPU_SLB_MAX(r9)
 
+       /* load host SLB entries */
+BEGIN_MMU_FTR_SECTION
+       b       0f
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
+       ld      r8,PACA_SLBSHADOWPTR(r13)
+
+       .rept   SLB_NUM_BOLTED
+       li      r3, SLBSHADOW_SAVEAREA
+       LDX_BE  r5, r8, r3
+       addi    r3, r3, 8
+       LDX_BE  r6, r8, r3
+       andis.  r7,r5,SLB_ESID_V@h
+       beq     1f
+       slbmte  r6,r5
+1:     addi    r8,r8,16
+       .endr
+0:
+
 guest_bypass:
        stw     r12, STACK_SLOT_TRAP(r1)
        mr      r3, r12
@@ -2018,23 +2036,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        mtspr   SPRN_LPCR,r8
        isync
 48:
-       /* load host SLB entries */
-BEGIN_MMU_FTR_SECTION
-       b       0f
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
-       ld      r8,PACA_SLBSHADOWPTR(r13)
-
-       .rept   SLB_NUM_BOLTED
-       li      r3, SLBSHADOW_SAVEAREA
-       LDX_BE  r5, r8, r3
-       addi    r3, r3, 8
-       LDX_BE  r6, r8, r3
-       andis.  r7,r5,SLB_ESID_V@h
-       beq     1f
-       slbmte  r6,r5
-1:     addi    r8,r8,16
-       .endr
-0:
 #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING
        /* Finish timing, if we have a vcpu */
        ld      r4, HSTATE_KVM_VCPU(r13)
index a0675e91ad7d11318d8f630a378509e5703dfe70..656933c859256bff1c9f1848830c0616033218aa 100644 (file)
@@ -201,6 +201,15 @@ static inline unsigned long  ___tlbie(unsigned long vpn, int psize,
        return va;
 }
 
+static inline void fixup_tlbie(unsigned long vpn, int psize, int apsize, int ssize)
+{
+       if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+               /* Need the extra ptesync to ensure we don't reorder tlbie*/
+               asm volatile("ptesync": : :"memory");
+               ___tlbie(vpn, psize, apsize, ssize);
+       }
+}
+
 static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
 {
        unsigned long rb;
@@ -278,6 +287,7 @@ static inline void tlbie(unsigned long vpn, int psize, int apsize,
                asm volatile("ptesync": : :"memory");
        } else {
                __tlbie(vpn, psize, apsize, ssize);
+               fixup_tlbie(vpn, psize, apsize, ssize);
                asm volatile("eieio; tlbsync; ptesync": : :"memory");
        }
        if (lock_tlbie && !use_local)
@@ -771,7 +781,7 @@ static void native_hpte_clear(void)
  */
 static void native_flush_hash_range(unsigned long number, int local)
 {
-       unsigned long vpn;
+       unsigned long vpn = 0;
        unsigned long hash, index, hidx, shift, slot;
        struct hash_pte *hptep;
        unsigned long hpte_v;
@@ -843,6 +853,10 @@ static void native_flush_hash_range(unsigned long number, int local)
                                __tlbie(vpn, psize, psize, ssize);
                        } pte_iterate_hashed_end();
                }
+               /*
+                * Just do one more with the last used values.
+                */
+               fixup_tlbie(vpn, psize, psize, ssize);
                asm volatile("eieio; tlbsync; ptesync":::"memory");
 
                if (lock_tlbie)
index 929d9ef7083f1ac85155f349788713eafbd1ea09..3f980baade4c19c27d1f6f42d4d0ee6a1893a4a7 100644 (file)
@@ -173,6 +173,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
        mm_iommu_init(mm);
 #endif
        atomic_set(&mm->context.active_cpus, 0);
+       atomic_set(&mm->context.copros, 0);
 
        return 0;
 }
index 28c980eb4422284d788716e245934c679925ad86..adf469f312f2044b9b4035a201b63b3da393e6ce 100644 (file)
@@ -481,6 +481,7 @@ void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
                             "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
                trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
        }
+       /* do we need fixup here ?*/
        asm volatile("eieio; tlbsync; ptesync" : : : "memory");
 }
 EXPORT_SYMBOL_GPL(mmu_partition_table_set_entry);
index 71d1b19ad1c0da190ecaf5cd394e918a771b01f9..a07f5372a4bf36ce726408891defc380dd9fea59 100644 (file)
@@ -119,6 +119,49 @@ static inline void __tlbie_pid(unsigned long pid, unsigned long ric)
        trace_tlbie(0, 0, rb, rs, ric, prs, r);
 }
 
+static inline void __tlbiel_va(unsigned long va, unsigned long pid,
+                              unsigned long ap, unsigned long ric)
+{
+       unsigned long rb,rs,prs,r;
+
+       rb = va & ~(PPC_BITMASK(52, 63));
+       rb |= ap << PPC_BITLSHIFT(58);
+       rs = pid << PPC_BITLSHIFT(31);
+       prs = 1; /* process scoped */
+       r = 1;   /* raidx format */
+
+       asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1)
+                    : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
+       trace_tlbie(0, 1, rb, rs, ric, prs, r);
+}
+
+static inline void __tlbie_va(unsigned long va, unsigned long pid,
+                             unsigned long ap, unsigned long ric)
+{
+       unsigned long rb,rs,prs,r;
+
+       rb = va & ~(PPC_BITMASK(52, 63));
+       rb |= ap << PPC_BITLSHIFT(58);
+       rs = pid << PPC_BITLSHIFT(31);
+       prs = 1; /* process scoped */
+       r = 1;   /* raidx format */
+
+       asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
+                    : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
+       trace_tlbie(0, 0, rb, rs, ric, prs, r);
+}
+
+static inline void fixup_tlbie(void)
+{
+       unsigned long pid = 0;
+       unsigned long va = ((1UL << 52) - 1);
+
+       if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG)) {
+               asm volatile("ptesync": : :"memory");
+               __tlbie_va(va, pid, mmu_get_ap(MMU_PAGE_64K), RIC_FLUSH_TLB);
+       }
+}
+
 /*
  * We use 128 set in radix mode and 256 set in hpt mode.
  */
@@ -151,24 +194,25 @@ static inline void _tlbiel_pid(unsigned long pid, unsigned long ric)
 static inline void _tlbie_pid(unsigned long pid, unsigned long ric)
 {
        asm volatile("ptesync": : :"memory");
-       __tlbie_pid(pid, ric);
-       asm volatile("eieio; tlbsync; ptesync": : :"memory");
-}
 
-static inline void __tlbiel_va(unsigned long va, unsigned long pid,
-                              unsigned long ap, unsigned long ric)
-{
-       unsigned long rb,rs,prs,r;
-
-       rb = va & ~(PPC_BITMASK(52, 63));
-       rb |= ap << PPC_BITLSHIFT(58);
-       rs = pid << PPC_BITLSHIFT(31);
-       prs = 1; /* process scoped */
-       r = 1;   /* raidx format */
-
-       asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1)
-                    : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
-       trace_tlbie(0, 1, rb, rs, ric, prs, r);
+       /*
+        * Workaround the fact that the "ric" argument to __tlbie_pid
+        * must be a compile-time contraint to match the "i" constraint
+        * in the asm statement.
+        */
+       switch (ric) {
+       case RIC_FLUSH_TLB:
+               __tlbie_pid(pid, RIC_FLUSH_TLB);
+               break;
+       case RIC_FLUSH_PWC:
+               __tlbie_pid(pid, RIC_FLUSH_PWC);
+               break;
+       case RIC_FLUSH_ALL:
+       default:
+               __tlbie_pid(pid, RIC_FLUSH_ALL);
+       }
+       fixup_tlbie();
+       asm volatile("eieio; tlbsync; ptesync": : :"memory");
 }
 
 static inline void __tlbiel_va_range(unsigned long start, unsigned long end,
@@ -203,22 +247,6 @@ static inline void _tlbiel_va_range(unsigned long start, unsigned long end,
        asm volatile("ptesync": : :"memory");
 }
 
-static inline void __tlbie_va(unsigned long va, unsigned long pid,
-                            unsigned long ap, unsigned long ric)
-{
-       unsigned long rb,rs,prs,r;
-
-       rb = va & ~(PPC_BITMASK(52, 63));
-       rb |= ap << PPC_BITLSHIFT(58);
-       rs = pid << PPC_BITLSHIFT(31);
-       prs = 1; /* process scoped */
-       r = 1;   /* raidx format */
-
-       asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
-                    : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
-       trace_tlbie(0, 0, rb, rs, ric, prs, r);
-}
-
 static inline void __tlbie_va_range(unsigned long start, unsigned long end,
                                    unsigned long pid, unsigned long page_size,
                                    unsigned long psize)
@@ -237,6 +265,7 @@ static inline void _tlbie_va(unsigned long va, unsigned long pid,
 
        asm volatile("ptesync": : :"memory");
        __tlbie_va(va, pid, ap, ric);
+       fixup_tlbie();
        asm volatile("eieio; tlbsync; ptesync": : :"memory");
 }
 
@@ -248,6 +277,7 @@ static inline void _tlbie_va_range(unsigned long start, unsigned long end,
        if (also_pwc)
                __tlbie_pid(pid, RIC_FLUSH_PWC);
        __tlbie_va_range(start, end, pid, page_size, psize);
+       fixup_tlbie();
        asm volatile("eieio; tlbsync; ptesync": : :"memory");
 }
 
@@ -311,6 +341,16 @@ void radix__local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmadd
 }
 EXPORT_SYMBOL(radix__local_flush_tlb_page);
 
+static bool mm_needs_flush_escalation(struct mm_struct *mm)
+{
+       /*
+        * P9 nest MMU has issues with the page walk cache
+        * caching PTEs and not flushing them properly when
+        * RIC = 0 for a PID/LPID invalidate
+        */
+       return atomic_read(&mm->context.copros) != 0;
+}
+
 #ifdef CONFIG_SMP
 void radix__flush_tlb_mm(struct mm_struct *mm)
 {
@@ -321,9 +361,12 @@ void radix__flush_tlb_mm(struct mm_struct *mm)
                return;
 
        preempt_disable();
-       if (!mm_is_thread_local(mm))
-               _tlbie_pid(pid, RIC_FLUSH_TLB);
-       else
+       if (!mm_is_thread_local(mm)) {
+               if (mm_needs_flush_escalation(mm))
+                       _tlbie_pid(pid, RIC_FLUSH_ALL);
+               else
+                       _tlbie_pid(pid, RIC_FLUSH_TLB);
+       } else
                _tlbiel_pid(pid, RIC_FLUSH_TLB);
        preempt_enable();
 }
@@ -435,10 +478,14 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
        }
 
        if (full) {
-               if (local)
+               if (local) {
                        _tlbiel_pid(pid, RIC_FLUSH_TLB);
-               else
-                       _tlbie_pid(pid, RIC_FLUSH_TLB);
+               } else {
+                       if (mm_needs_flush_escalation(mm))
+                               _tlbie_pid(pid, RIC_FLUSH_ALL);
+                       else
+                               _tlbie_pid(pid, RIC_FLUSH_TLB);
+               }
        } else {
                bool hflush = false;
                unsigned long hstart, hend;
@@ -465,6 +512,7 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                        if (hflush)
                                __tlbie_va_range(hstart, hend, pid,
                                                HPAGE_PMD_SIZE, MMU_PAGE_2M);
+                       fixup_tlbie();
                        asm volatile("eieio; tlbsync; ptesync": : :"memory");
                }
        }
@@ -548,6 +596,9 @@ static inline void __radix__flush_tlb_range_psize(struct mm_struct *mm,
        }
 
        if (full) {
+               if (!local && mm_needs_flush_escalation(mm))
+                       also_pwc = true;
+
                if (local)
                        _tlbiel_pid(pid, also_pwc ? RIC_FLUSH_ALL : RIC_FLUSH_TLB);
                else
@@ -603,46 +654,6 @@ void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr)
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
-void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa,
-                             unsigned long page_size)
-{
-       unsigned long rb,rs,prs,r;
-       unsigned long ap;
-       unsigned long ric = RIC_FLUSH_TLB;
-
-       ap = mmu_get_ap(radix_get_mmu_psize(page_size));
-       rb = gpa & ~(PPC_BITMASK(52, 63));
-       rb |= ap << PPC_BITLSHIFT(58);
-       rs = lpid & ((1UL << 32) - 1);
-       prs = 0; /* process scoped */
-       r = 1;   /* raidx format */
-
-       asm volatile("ptesync": : :"memory");
-       asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
-                    : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
-       asm volatile("eieio; tlbsync; ptesync": : :"memory");
-       trace_tlbie(lpid, 0, rb, rs, ric, prs, r);
-}
-EXPORT_SYMBOL(radix__flush_tlb_lpid_va);
-
-void radix__flush_tlb_lpid(unsigned long lpid)
-{
-       unsigned long rb,rs,prs,r;
-       unsigned long ric = RIC_FLUSH_ALL;
-
-       rb = 0x2 << PPC_BITLSHIFT(53); /* IS = 2 */
-       rs = lpid & ((1UL << 32) - 1);
-       prs = 0; /* partition scoped */
-       r = 1;   /* raidx format */
-
-       asm volatile("ptesync": : :"memory");
-       asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
-                    : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory");
-       asm volatile("eieio; tlbsync; ptesync": : :"memory");
-       trace_tlbie(lpid, 0, rb, rs, ric, prs, r);
-}
-EXPORT_SYMBOL(radix__flush_tlb_lpid);
-
 void radix__flush_pmd_tlb_range(struct vm_area_struct *vma,
                                unsigned long start, unsigned long end)
 {
index d8015235ba765b03c6ace2d73413e18bfd1cdbda..5e526c54247efa129851ddd70908d3706e240f74 100644 (file)
@@ -1153,6 +1153,7 @@ static void setup_pebs_sample_data(struct perf_event *event,
        if (pebs == NULL)
                return;
 
+       regs->flags &= ~PERF_EFLAGS_EXACT;
        sample_type = event->attr.sample_type;
        dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
 
@@ -1197,7 +1198,6 @@ static void setup_pebs_sample_data(struct perf_event *event,
         */
        *regs = *iregs;
        regs->flags = pebs->flags;
-       set_linear_ip(regs, pebs->ip);
 
        if (sample_type & PERF_SAMPLE_REGS_INTR) {
                regs->ax = pebs->ax;
@@ -1233,13 +1233,22 @@ static void setup_pebs_sample_data(struct perf_event *event,
 #endif
        }
 
-       if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
-               regs->ip = pebs->real_ip;
-               regs->flags |= PERF_EFLAGS_EXACT;
-       } else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
-               regs->flags |= PERF_EFLAGS_EXACT;
-       else
-               regs->flags &= ~PERF_EFLAGS_EXACT;
+       if (event->attr.precise_ip > 1) {
+               /* Haswell and later have the eventing IP, so use it: */
+               if (x86_pmu.intel_cap.pebs_format >= 2) {
+                       set_linear_ip(regs, pebs->real_ip);
+                       regs->flags |= PERF_EFLAGS_EXACT;
+               } else {
+                       /* Otherwise use PEBS off-by-1 IP: */
+                       set_linear_ip(regs, pebs->ip);
+
+                       /* ... and try to fix it up using the LBR entries: */
+                       if (intel_pmu_pebs_fixup_ip(regs))
+                               regs->flags |= PERF_EFLAGS_EXACT;
+               }
+       } else
+               set_linear_ip(regs, pebs->ip);
+
 
        if ((sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) &&
            x86_pmu.intel_cap.pebs_format >= 1)
index cf5961ca867746ae2eadb4a2b6f2c9068cec48c4..4cd6a3b71824293ae3edb664bc5ed6e48ca5a459 100644 (file)
@@ -218,13 +218,11 @@ static inline int alternatives_text_reserved(void *start, void *end)
  */
 #define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2,   \
                           output, input...)                                  \
-{                                                                            \
        asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\
                "call %P[new2]", feature2)                                    \
                : output, ASM_CALL_CONSTRAINT                                 \
                : [old] "i" (oldfunc), [new1] "i" (newfunc1),                 \
-                 [new2] "i" (newfunc2), ## input);                           \
-}
+                 [new2] "i" (newfunc2), ## input)
 
 /*
  * use this macro(s) if you need more than one output parameter
index 2851077b6051b257e710dd437e2cdba7b1516e56..32e666e1231e77f128252b2f9354f708081cafdb 100644 (file)
@@ -36,6 +36,7 @@ extern asmlinkage void kvm_posted_intr_wakeup_ipi(void);
 extern asmlinkage void kvm_posted_intr_nested_ipi(void);
 extern asmlinkage void error_interrupt(void);
 extern asmlinkage void irq_work_interrupt(void);
+extern asmlinkage void uv_bau_message_intr1(void);
 
 extern asmlinkage void spurious_interrupt(void);
 extern asmlinkage void thermal_interrupt(void);
index ecb9ddef128f82d0d162895bb596d606508f13a6..62c79e26a59ace46ac4b7fc4a3a400e79dbedb70 100644 (file)
@@ -3833,7 +3833,7 @@ union uvh_rh_gam_mmioh_overlay_config0_mmr_u {
 #define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR uv_undefined("UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR")
 #define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR uv_undefined("UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR")
 #define UV3H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR 0x1603000UL
-#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR 0x483000UL
+#define UV4H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR 0x484000UL
 #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR (                         \
        is_uv1_hub() ? UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR :          \
        is_uv2_hub() ? UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG1_MMR :          \
index 50bee5fe114013622ee858e4a3b7b16d1ffa8a05..2c3a1b4294eb40d202b4e14435cf3682b9f34d5e 100644 (file)
@@ -140,6 +140,9 @@ static const __initconst struct idt_data apic_idts[] = {
 # ifdef CONFIG_IRQ_WORK
        INTG(IRQ_WORK_VECTOR,           irq_work_interrupt),
 # endif
+#ifdef CONFIG_X86_UV
+       INTG(UV_BAU_MESSAGE,            uv_bau_message_intr1),
+#endif
        INTG(SPURIOUS_APIC_VECTOR,      spurious_interrupt),
        INTG(ERROR_APIC_VECTOR,         error_interrupt),
 #endif
index bc1a27280c4bf77899afad4b85bf53212d385cab..fae86e36e39988283ea84063f4856fbc81585fe8 100644 (file)
@@ -546,7 +546,7 @@ static void __init kvm_guest_init(void)
        }
 
        if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
-           !kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
+           kvm_para_has_feature(KVM_FEATURE_STEAL_TIME))
                pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others;
 
        if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
@@ -635,7 +635,7 @@ static __init int kvm_setup_pv_tlb_flush(void)
        int cpu;
 
        if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
-           !kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
+           kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
                for_each_possible_cpu(cpu) {
                        zalloc_cpumask_var_node(per_cpu_ptr(&__pv_tlb_mask, cpu),
                                GFP_KERNEL, cpu_to_node(cpu));
index 2d87603f91795b29c5ea0f84703d316a49c0573d..657c934090428bbdb9cef01d4bf06e7b9b14f8d9 100644 (file)
@@ -10711,6 +10711,11 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
        struct vcpu_vmx *vmx = to_vmx(vcpu);
        u32 exec_control, vmcs12_exec_ctrl;
 
+       if (vmx->nested.dirty_vmcs12) {
+               prepare_vmcs02_full(vcpu, vmcs12, from_vmentry);
+               vmx->nested.dirty_vmcs12 = false;
+       }
+
        /*
         * First, the fields that are shadowed.  This must be kept in sync
         * with vmx_shadow_fields.h.
@@ -10948,11 +10953,6 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
        /* Note: modifies VM_ENTRY/EXIT_CONTROLS and GUEST/HOST_IA32_EFER */
        vmx_set_efer(vcpu, vcpu->arch.efer);
 
-       if (vmx->nested.dirty_vmcs12) {
-               prepare_vmcs02_full(vcpu, vmcs12, from_vmentry);
-               vmx->nested.dirty_vmcs12 = false;
-       }
-
        /* Shadow page tables on either EPT or shadow page tables. */
        if (nested_vmx_load_cr3(vcpu, vmcs12->guest_cr3, nested_cpu_has_ept(vmcs12),
                                entry_failure_code))
index db77e087adaf874f6556f5f1d0cb5bdcaf54c42f..b36caae0fb2f71ee60f4c169157cdbe6955f9a7c 100644 (file)
@@ -2255,8 +2255,6 @@ static int __init uv_bau_init(void)
                        init_uvhub(uvhub, vector, uv_base_pnode);
        }
 
-       alloc_intr_gate(vector, uv_bau_message_intr1);
-
        for_each_possible_blade(uvhub) {
                if (uv_blade_nr_possible_cpus(uvhub)) {
                        unsigned long val;
index 2f15a2ac4209cac748339aba85a4c09f87e88af5..d70c15de417b269983a433713faf6bfcffd717ac 100644 (file)
@@ -16,7 +16,7 @@ KCOV_INSTRUMENT := n
 # in turn leaves some undefined symbols like __fentry__ in purgatory and not
 # sure how to relocate those. Like kexec-tools, use custom flags.
 
-KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -MD -Os -mcmodel=large
+KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -Os -mcmodel=large
 KBUILD_CFLAGS += -m$(BITS)
 KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
 
index 98a3a43484c8b410f3a217cd8cb11bd8d6750370..44abb8a0a5e522b7a8f73111aad6fd8fc5297402 100644 (file)
@@ -3147,7 +3147,7 @@ static int ia_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
                            "  Size of Tx Buffer  :  %u\n"
                            "  Number of Rx Buffer:  %u\n"
                            "  Size of Rx Buffer  :  %u\n"
-                           "  Packets Receiverd  :  %u\n"
+                           "  Packets Receive  :  %u\n"
                            "  Packets Transmitted:  %u\n"
                            "  Cells Received     :  %u\n"
                            "  Cells Transmitted  :  %u\n"
index c18e048f23c6d7aa2d3e0af53ff0d3a273945253..d55d29d31da4eec6f932c0f2704dd8ca7c271b50 100644 (file)
@@ -1058,13 +1058,13 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
                pr_warn("Can't create new usermode queue because %d queues were already created\n",
                                dqm->total_queue_count);
                retval = -EPERM;
-               goto out;
+               goto out_unlock;
        }
 
        if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
                retval = allocate_sdma_queue(dqm, &q->sdma_id);
                if (retval)
-                       goto out;
+                       goto out_unlock;
                q->properties.sdma_queue_id =
                        q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE;
                q->properties.sdma_engine_id =
@@ -1075,7 +1075,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
 
        if (!mqd) {
                retval = -ENOMEM;
-               goto out;
+               goto out_deallocate_sdma_queue;
        }
        /*
         * Eviction state logic: we only mark active queues as evicted
@@ -1093,7 +1093,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
        retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
                                &q->gart_mqd_addr, &q->properties);
        if (retval)
-               goto out;
+               goto out_deallocate_sdma_queue;
 
        list_add(&q->list, &qpd->queues_list);
        qpd->queue_count++;
@@ -1114,7 +1114,13 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
        pr_debug("Total of %d queues are accountable so far\n",
                        dqm->total_queue_count);
 
-out:
+       mutex_unlock(&dqm->lock);
+       return retval;
+
+out_deallocate_sdma_queue:
+       if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+               deallocate_sdma_queue(dqm, q->sdma_id);
+out_unlock:
        mutex_unlock(&dqm->lock);
        return retval;
 }
@@ -1433,8 +1439,10 @@ static int process_termination_cpsch(struct device_queue_manager *dqm,
 
        /* Clear all user mode queues */
        list_for_each_entry(q, &qpd->queues_list, list) {
-               if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+               if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
                        dqm->sdma_queue_count--;
+                       deallocate_sdma_queue(dqm, q->sdma_id);
+               }
 
                if (q->properties.is_active)
                        dqm->queue_count--;
index 7614375489a4b72c774db4185829b54c65f13aeb..89ba4c670ec5831f855dd374b5631ef87dc99bbb 100644 (file)
@@ -188,8 +188,7 @@ static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer,
        packet->sh_mem_ape1_base = qpd->sh_mem_ape1_base;
        packet->sh_mem_ape1_limit = qpd->sh_mem_ape1_limit;
 
-       /* TODO: scratch support */
-       packet->sh_hidden_private_base_vmid = 0;
+       packet->sh_hidden_private_base_vmid = qpd->sh_hidden_private_base;
 
        packet->gds_addr_lo = lower_32_bits(qpd->gds_context_area);
        packet->gds_addr_hi = upper_32_bits(qpd->gds_context_area);
index 616c9634585e4010254cd946af40bdc0f50b11ac..9f83a65b5ea9e2a4e873c310b32158f8df569473 100644 (file)
@@ -2025,9 +2025,9 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
        .coupled_pm = false,
        .has_nvdisplay = false,
        .num_primary_formats = ARRAY_SIZE(tegra124_primary_formats),
-       .primary_formats = tegra114_primary_formats,
+       .primary_formats = tegra124_primary_formats,
        .num_overlay_formats = ARRAY_SIZE(tegra124_overlay_formats),
-       .overlay_formats = tegra114_overlay_formats,
+       .overlay_formats = tegra124_overlay_formats,
        .modifiers = tegra124_modifiers,
 };
 
@@ -2178,7 +2178,7 @@ static int tegra_dc_couple(struct tegra_dc *dc)
                struct device_link *link;
                struct device *partner;
 
-               partner = driver_find_device(dc->dev->driver, NULL, 0,
+               partner = driver_find_device(dc->dev->driver, NULL, NULL,
                                             tegra_dc_match_by_pipe);
                if (!partner)
                        return -EPROBE_DEFER;
index b445b3bb0bb11fe262363042a2eb56e458f6ffc2..f273e28c39db2ec5f667a6b4fd27d1377f8e31a4 100644 (file)
@@ -888,6 +888,11 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
        }
 
        setup = of_device_get_match_data(&pdev->dev);
+       if (!setup) {
+               dev_err(&pdev->dev, "Can't get device data\n");
+               ret = -ENODEV;
+               goto clk_free;
+       }
        i2c_dev->setup = *setup;
 
        ret = device_property_read_u32(i2c_dev->dev, "i2c-scl-rising-time-ns",
index 9183d148d644484c11f4e26fc87ff332c4fbb4eb..cb1d2ab13c661ac77f0221efc8c520de20fa3312 100644 (file)
@@ -207,6 +207,22 @@ int rdma_addr_size(struct sockaddr *addr)
 }
 EXPORT_SYMBOL(rdma_addr_size);
 
+int rdma_addr_size_in6(struct sockaddr_in6 *addr)
+{
+       int ret = rdma_addr_size((struct sockaddr *) addr);
+
+       return ret <= sizeof(*addr) ? ret : 0;
+}
+EXPORT_SYMBOL(rdma_addr_size_in6);
+
+int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr)
+{
+       int ret = rdma_addr_size((struct sockaddr *) addr);
+
+       return ret <= sizeof(*addr) ? ret : 0;
+}
+EXPORT_SYMBOL(rdma_addr_size_kss);
+
 static struct rdma_addr_client self;
 
 void rdma_addr_register_client(struct rdma_addr_client *client)
@@ -586,6 +602,15 @@ static void process_one_req(struct work_struct *_work)
        list_del(&req->list);
        mutex_unlock(&lock);
 
+       /*
+        * Although the work will normally have been canceled by the
+        * workqueue, it can still be requeued as long as it is on the
+        * req_list, so it could have been requeued before we grabbed &lock.
+        * We need to cancel it after it is removed from req_list to really be
+        * sure it is safe to free.
+        */
+       cancel_delayed_work(&req->work);
+
        req->callback(req->status, (struct sockaddr *)&req->src_addr,
                req->addr, req->context);
        put_client(req->client);
index bb065c9449be46617bd82e2b26d7648aa00212a3..b7459cf524e454f946d683fbddcc2e9d070cb42d 100644 (file)
@@ -290,6 +290,7 @@ void ib_dealloc_device(struct ib_device *device)
 {
        WARN_ON(device->reg_state != IB_DEV_UNREGISTERED &&
                device->reg_state != IB_DEV_UNINITIALIZED);
+       rdma_restrack_clean(&device->res);
        put_device(&device->dev);
 }
 EXPORT_SYMBOL(ib_dealloc_device);
@@ -600,8 +601,6 @@ void ib_unregister_device(struct ib_device *device)
        }
        up_read(&lists_rwsem);
 
-       rdma_restrack_clean(&device->res);
-
        ib_device_unregister_rdmacg(device);
        ib_device_unregister_sysfs(device);
 
index e5a1e7d813265fc3f0947d3a6aa643367745d9cc..d933336d7e01eb0cb4ca4451d440040dd8131af9 100644 (file)
@@ -632,6 +632,9 @@ static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf,
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
+       if (!rdma_addr_size_in6(&cmd.addr))
+               return -EINVAL;
+
        ctx = ucma_get_ctx(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
@@ -645,22 +648,21 @@ static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf,
                         int in_len, int out_len)
 {
        struct rdma_ucm_bind cmd;
-       struct sockaddr *addr;
        struct ucma_context *ctx;
        int ret;
 
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
-       addr = (struct sockaddr *) &cmd.addr;
-       if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr)))
+       if (cmd.reserved || !cmd.addr_size ||
+           cmd.addr_size != rdma_addr_size_kss(&cmd.addr))
                return -EINVAL;
 
        ctx = ucma_get_ctx(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       ret = rdma_bind_addr(ctx->cm_id, addr);
+       ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr);
        ucma_put_ctx(ctx);
        return ret;
 }
@@ -670,23 +672,22 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file,
                               int in_len, int out_len)
 {
        struct rdma_ucm_resolve_ip cmd;
-       struct sockaddr *src, *dst;
        struct ucma_context *ctx;
        int ret;
 
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
-       src = (struct sockaddr *) &cmd.src_addr;
-       dst = (struct sockaddr *) &cmd.dst_addr;
-       if (!rdma_addr_size(src) || !rdma_addr_size(dst))
+       if (!rdma_addr_size_in6(&cmd.src_addr) ||
+           !rdma_addr_size_in6(&cmd.dst_addr))
                return -EINVAL;
 
        ctx = ucma_get_ctx(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
+       ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
+                               (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
        ucma_put_ctx(ctx);
        return ret;
 }
@@ -696,24 +697,23 @@ static ssize_t ucma_resolve_addr(struct ucma_file *file,
                                 int in_len, int out_len)
 {
        struct rdma_ucm_resolve_addr cmd;
-       struct sockaddr *src, *dst;
        struct ucma_context *ctx;
        int ret;
 
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
-       src = (struct sockaddr *) &cmd.src_addr;
-       dst = (struct sockaddr *) &cmd.dst_addr;
-       if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) ||
-           !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst)))
+       if (cmd.reserved ||
+           (cmd.src_size && (cmd.src_size != rdma_addr_size_kss(&cmd.src_addr))) ||
+           !cmd.dst_size || (cmd.dst_size != rdma_addr_size_kss(&cmd.dst_addr)))
                return -EINVAL;
 
        ctx = ucma_get_ctx(file, cmd.id);
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms);
+       ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr,
+                               (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms);
        ucma_put_ctx(ctx);
        return ret;
 }
@@ -1166,6 +1166,11 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
+       if (!ctx->cm_id->device) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        resp.qp_attr_mask = 0;
        memset(&qp_attr, 0, sizeof qp_attr);
        qp_attr.qp_state = cmd.qp_state;
@@ -1307,7 +1312,7 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       if (unlikely(cmd.optval > KMALLOC_MAX_SIZE))
+       if (unlikely(cmd.optlen > KMALLOC_MAX_SIZE))
                return -EINVAL;
 
        optval = memdup_user((void __user *) (unsigned long) cmd.optval,
@@ -1331,7 +1336,7 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
 {
        struct rdma_ucm_notify cmd;
        struct ucma_context *ctx;
-       int ret;
+       int ret = -EINVAL;
 
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
@@ -1340,7 +1345,9 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
        if (IS_ERR(ctx))
                return PTR_ERR(ctx);
 
-       ret = rdma_notify(ctx->cm_id, (enum ib_event_type) cmd.event);
+       if (ctx->cm_id->device)
+               ret = rdma_notify(ctx->cm_id, (enum ib_event_type)cmd.event);
+
        ucma_put_ctx(ctx);
        return ret;
 }
@@ -1426,7 +1433,7 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file,
        join_cmd.response = cmd.response;
        join_cmd.uid = cmd.uid;
        join_cmd.id = cmd.id;
-       join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr);
+       join_cmd.addr_size = rdma_addr_size_in6(&cmd.addr);
        if (!join_cmd.addr_size)
                return -EINVAL;
 
@@ -1445,7 +1452,7 @@ static ssize_t ucma_join_multicast(struct ucma_file *file,
        if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
                return -EFAULT;
 
-       if (!rdma_addr_size((struct sockaddr *)&cmd.addr))
+       if (!rdma_addr_size_kss(&cmd.addr))
                return -EINVAL;
 
        return ucma_process_join(file, &cmd, out_len);
index db2ff352d75f665b075d512e73dce619fdf230c1..ec638778661ccd7aadecb857bfdb9b8e59929524 100644 (file)
@@ -4383,7 +4383,7 @@ err_dma_alloc_buf:
        eq->l0_dma = 0;
 
        if (mhop_num == 1)
-               for (i -= i; i >= 0; i--)
+               for (i -= 1; i >= 0; i--)
                        dma_free_coherent(dev, buf_chk_sz, eq->buf[i],
                                          eq->buf_dma[i]);
        else if (mhop_num == 2) {
index da091de4e69d81eda73de4e3ce758830aaa1413c..7f8bda3a20058753c7bc3109c985895b2fb46664 100644 (file)
@@ -3448,9 +3448,12 @@ static void destroy_umrc_res(struct mlx5_ib_dev *dev)
        if (err)
                mlx5_ib_warn(dev, "mr cache cleanup failed\n");
 
-       mlx5_ib_destroy_qp(dev->umrc.qp);
-       ib_free_cq(dev->umrc.cq);
-       ib_dealloc_pd(dev->umrc.pd);
+       if (dev->umrc.qp)
+               mlx5_ib_destroy_qp(dev->umrc.qp);
+       if (dev->umrc.cq)
+               ib_free_cq(dev->umrc.cq);
+       if (dev->umrc.pd)
+               ib_dealloc_pd(dev->umrc.pd);
 }
 
 enum {
@@ -3552,12 +3555,15 @@ static int create_umr_res(struct mlx5_ib_dev *dev)
 
 error_4:
        mlx5_ib_destroy_qp(qp);
+       dev->umrc.qp = NULL;
 
 error_3:
        ib_free_cq(cq);
+       dev->umrc.cq = NULL;
 
 error_2:
        ib_dealloc_pd(pd);
+       dev->umrc.pd = NULL;
 
 error_0:
        kfree(attr);
index c51c602f06d6ea6d9c4737abbf4a6ab6f09fa6eb..3e0b3f0238d69315a8bd16d2177a0e5a96f8746e 100644 (file)
@@ -739,6 +739,9 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev)
 {
        int i;
 
+       if (!dev->cache.wq)
+               return 0;
+
        dev->cache.stopped = 1;
        flush_workqueue(dev->cache.wq);
 
index db4bf97c0e156cdda65f09934bd48f7b0e4a5de4..0ffb9b93e22de4f81e0e192afb1fbc8b34f2e861 100644 (file)
@@ -833,7 +833,8 @@ static struct qedr_dev *qedr_add(struct qed_dev *cdev, struct pci_dev *pdev,
 
        dev->num_cnq = dev->ops->rdma_get_min_cnq_msix(cdev);
        if (!dev->num_cnq) {
-               DP_ERR(dev, "not enough CNQ resources.\n");
+               DP_ERR(dev, "Failed. At least one CNQ is required.\n");
+               rc = -ENOMEM;
                goto init_err;
        }
 
index 875b17272d65289d2cfa826f3635683831e19886..419a158e8fca78a930bdf2ee03e1297a4a15f1ba 100644 (file)
@@ -1841,14 +1841,15 @@ static void qedr_reset_qp_hwq_info(struct qedr_qp_hwq_info *qph)
 
 static int qedr_update_qp_state(struct qedr_dev *dev,
                                struct qedr_qp *qp,
+                               enum qed_roce_qp_state cur_state,
                                enum qed_roce_qp_state new_state)
 {
        int status = 0;
 
-       if (new_state == qp->state)
+       if (new_state == cur_state)
                return 0;
 
-       switch (qp->state) {
+       switch (cur_state) {
        case QED_ROCE_QP_STATE_RESET:
                switch (new_state) {
                case QED_ROCE_QP_STATE_INIT:
@@ -1955,6 +1956,7 @@ int qedr_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        struct qedr_dev *dev = get_qedr_dev(&qp->dev->ibdev);
        const struct ib_global_route *grh = rdma_ah_read_grh(&attr->ah_attr);
        enum ib_qp_state old_qp_state, new_qp_state;
+       enum qed_roce_qp_state cur_state;
        int rc = 0;
 
        DP_DEBUG(dev, QEDR_MSG_QP,
@@ -2086,18 +2088,23 @@ int qedr_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                SET_FIELD(qp_params.modify_flags,
                          QED_ROCE_MODIFY_QP_VALID_ACK_TIMEOUT, 1);
 
-               qp_params.ack_timeout = attr->timeout;
-               if (attr->timeout) {
-                       u32 temp;
-
-                       temp = 4096 * (1UL << attr->timeout) / 1000 / 1000;
-                       /* FW requires [msec] */
-                       qp_params.ack_timeout = temp;
-               } else {
-                       /* Infinite */
+               /* The received timeout value is an exponent used like this:
+                *    "12.7.34 LOCAL ACK TIMEOUT
+                *    Value representing the transport (ACK) timeout for use by
+                *    the remote, expressed as: 4.096 * 2^timeout [usec]"
+                * The FW expects timeout in msec so we need to divide the usec
+                * result by 1000. We'll approximate 1000~2^10, and 4.096 ~ 2^2,
+                * so we get: 2^2 * 2^timeout / 2^10 = 2^(timeout - 8).
+                * The value of zero means infinite so we use a 'max_t' to make
+                * sure that sub 1 msec values will be configured as 1 msec.
+                */
+               if (attr->timeout)
+                       qp_params.ack_timeout =
+                                       1 << max_t(int, attr->timeout - 8, 0);
+               else
                        qp_params.ack_timeout = 0;
-               }
        }
+
        if (attr_mask & IB_QP_RETRY_CNT) {
                SET_FIELD(qp_params.modify_flags,
                          QED_ROCE_MODIFY_QP_VALID_RETRY_CNT, 1);
@@ -2170,13 +2177,25 @@ int qedr_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                qp->dest_qp_num = attr->dest_qp_num;
        }
 
+       cur_state = qp->state;
+
+       /* Update the QP state before the actual ramrod to prevent a race with
+        * fast path. Modifying the QP state to error will cause the device to
+        * flush the CQEs and while polling the flushed CQEs will considered as
+        * a potential issue if the QP isn't in error state.
+        */
+       if ((attr_mask & IB_QP_STATE) && qp->qp_type != IB_QPT_GSI &&
+           !udata && qp_params.new_state == QED_ROCE_QP_STATE_ERR)
+               qp->state = QED_ROCE_QP_STATE_ERR;
+
        if (qp->qp_type != IB_QPT_GSI)
                rc = dev->ops->rdma_modify_qp(dev->rdma_ctx,
                                              qp->qed_qp, &qp_params);
 
        if (attr_mask & IB_QP_STATE) {
                if ((qp->qp_type != IB_QPT_GSI) && (!udata))
-                       rc = qedr_update_qp_state(dev, qp, qp_params.new_state);
+                       rc = qedr_update_qp_state(dev, qp, cur_state,
+                                                 qp_params.new_state);
                qp->state = qp_params.new_state;
        }
 
index a05a560d3cba628eb8a5ed23e07a753c1efb0acd..a6b7baf31cddf1d4dee1d90eddee38cfe67b8a9d 100644 (file)
@@ -887,7 +887,7 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps
 
        q = bdev_get_queue(p->path.dev->bdev);
        attached_handler_name = scsi_dh_attached_handler_name(q, GFP_KERNEL);
-       if (attached_handler_name) {
+       if (attached_handler_name || m->hw_handler_name) {
                INIT_DELAYED_WORK(&p->activate_path, activate_path_work);
                r = setup_scsi_dh(p->path.dev->bdev, m, attached_handler_name, &ti->error);
                if (r) {
index 45328d8b2859640d04a01b6b7b14cd9990fa2b7e..353ea0ede0911c4931e78fcd06aa8b0547f7a214 100644 (file)
@@ -466,7 +466,7 @@ static int dm_get_bdev_for_ioctl(struct mapped_device *md,
 {
        struct dm_target *tgt;
        struct dm_table *map;
-       int srcu_idx, r;
+       int srcu_idx, r, r2;
 
 retry:
        r = -ENOTTY;
@@ -492,9 +492,11 @@ retry:
                goto out;
 
        bdgrab(*bdev);
-       r = blkdev_get(*bdev, *mode, _dm_claim_ptr);
-       if (r < 0)
+       r2 = blkdev_get(*bdev, *mode, _dm_claim_ptr);
+       if (r2 < 0) {
+               r = r2;
                goto out;
+       }
 
        dm_put_live_table(md, srcu_idx);
        return r;
index 7c0b27d132b1bca8aa546cedac726cf5e92c6613..b479bd81120b3432e015b76496c3f3ea1d32580c 100644 (file)
@@ -1889,6 +1889,8 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base,
        do {
                uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi);
                mask = (1 << (cfi->device_type * 8)) - 1;
+               if (ofs >= map->size)
+                       return 0;
                result = map_read(map, base + ofs);
                bank++;
        } while ((result.x[0] & mask) == CFI_MFR_CONTINUATION);
index fcbe4fd6e684bcc45721d52b4845e4018cb8edeb..ca0a70389ba95521e6cd140c1fcc676413d8a651 100644 (file)
@@ -426,7 +426,7 @@ static int get_strength(struct atmel_pmecc_user *user)
 
 static int get_sectorsize(struct atmel_pmecc_user *user)
 {
-       return user->cache.cfg & PMECC_LOOKUP_TABLE_SIZE_1024 ? 1024 : 512;
+       return user->cache.cfg & PMECC_CFG_SECTOR1024 ? 1024 : 512;
 }
 
 static void atmel_pmecc_gen_syndrome(struct atmel_pmecc_user *user, int sector)
index c669554d70bb7c7ba2fe3091ed1c58bd3026229f..b7b11301885334315700dc8e3386253dd8178afb 100644 (file)
@@ -1528,39 +1528,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
                        goto err_close;
        }
 
-       /* If the mode uses primary, then the following is handled by
-        * bond_change_active_slave().
-        */
-       if (!bond_uses_primary(bond)) {
-               /* set promiscuity level to new slave */
-               if (bond_dev->flags & IFF_PROMISC) {
-                       res = dev_set_promiscuity(slave_dev, 1);
-                       if (res)
-                               goto err_close;
-               }
-
-               /* set allmulti level to new slave */
-               if (bond_dev->flags & IFF_ALLMULTI) {
-                       res = dev_set_allmulti(slave_dev, 1);
-                       if (res)
-                               goto err_close;
-               }
-
-               netif_addr_lock_bh(bond_dev);
-
-               dev_mc_sync_multiple(slave_dev, bond_dev);
-               dev_uc_sync_multiple(slave_dev, bond_dev);
-
-               netif_addr_unlock_bh(bond_dev);
-       }
-
-       if (BOND_MODE(bond) == BOND_MODE_8023AD) {
-               /* add lacpdu mc addr to mc list */
-               u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
-
-               dev_mc_add(slave_dev, lacpdu_multicast);
-       }
-
        res = vlan_vids_add_by_dev(slave_dev, bond_dev);
        if (res) {
                netdev_err(bond_dev, "Couldn't add bond vlan ids to %s\n",
@@ -1725,6 +1692,40 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
                goto err_upper_unlink;
        }
 
+       /* If the mode uses primary, then the following is handled by
+        * bond_change_active_slave().
+        */
+       if (!bond_uses_primary(bond)) {
+               /* set promiscuity level to new slave */
+               if (bond_dev->flags & IFF_PROMISC) {
+                       res = dev_set_promiscuity(slave_dev, 1);
+                       if (res)
+                               goto err_sysfs_del;
+               }
+
+               /* set allmulti level to new slave */
+               if (bond_dev->flags & IFF_ALLMULTI) {
+                       res = dev_set_allmulti(slave_dev, 1);
+                       if (res) {
+                               if (bond_dev->flags & IFF_PROMISC)
+                                       dev_set_promiscuity(slave_dev, -1);
+                               goto err_sysfs_del;
+                       }
+               }
+
+               netif_addr_lock_bh(bond_dev);
+               dev_mc_sync_multiple(slave_dev, bond_dev);
+               dev_uc_sync_multiple(slave_dev, bond_dev);
+               netif_addr_unlock_bh(bond_dev);
+
+               if (BOND_MODE(bond) == BOND_MODE_8023AD) {
+                       /* add lacpdu mc addr to mc list */
+                       u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR;
+
+                       dev_mc_add(slave_dev, lacpdu_multicast);
+               }
+       }
+
        bond->slave_cnt++;
        bond_compute_features(bond);
        bond_set_carrier(bond);
@@ -1748,6 +1749,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
        return 0;
 
 /* Undo stages on error */
+err_sysfs_del:
+       bond_sysfs_slave_del(new_slave);
+
 err_upper_unlink:
        bond_upper_dev_unlink(bond, new_slave);
 
@@ -1755,9 +1759,6 @@ err_unregister:
        netdev_rx_handler_unregister(slave_dev);
 
 err_detach:
-       if (!bond_uses_primary(bond))
-               bond_hw_addr_flush(bond_dev, slave_dev);
-
        vlan_vids_del_by_dev(slave_dev, bond_dev);
        if (rcu_access_pointer(bond->primary_slave) == new_slave)
                RCU_INIT_POINTER(bond->primary_slave, NULL);
index 8a0bb000d05699f28e42d3a5547fffabfcc13341..4e53c5ce23ffe484fbccdfc75db1b5bb5382185d 100644 (file)
@@ -1409,6 +1409,7 @@ static const struct of_device_id mt7530_of_match[] = {
        { .compatible = "mediatek,mt7530" },
        { /* sentinel */ },
 };
+MODULE_DEVICE_TABLE(of, mt7530_of_match);
 
 static struct mdio_driver mt7530_mdio_driver = {
        .probe  = mt7530_probe,
@@ -1424,4 +1425,3 @@ mdio_module_driver(mt7530_mdio_driver);
 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
 MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:mediatek-mt7530");
index 25e9a551cc8c3e726ad23234f5de5c20ec0caec6..3f6fb635738c998ea4b69e0e3ef9ca77e7bef6dc 100644 (file)
@@ -1132,6 +1132,7 @@ static void mvneta_port_up(struct mvneta_port *pp)
        }
        mvreg_write(pp, MVNETA_TXQ_CMD, q_map);
 
+       q_map = 0;
        /* Enable all initialized RXQs. */
        for (queue = 0; queue < rxq_number; queue++) {
                struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
index 1a0c3bf86ead3ad66f377eae5ab0abede7f93d43..752a72499b4f16ebb22c126c258ca35a0f19619d 100644 (file)
@@ -156,57 +156,63 @@ static int mlx4_en_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
 static u8 mlx4_en_dcbnl_set_all(struct net_device *netdev)
 {
        struct mlx4_en_priv *priv = netdev_priv(netdev);
+       struct mlx4_en_port_profile *prof = priv->prof;
        struct mlx4_en_dev *mdev = priv->mdev;
+       u8 tx_pause, tx_ppp, rx_pause, rx_ppp;
 
        if (!(priv->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
                return 1;
 
        if (priv->cee_config.pfc_state) {
                int tc;
+               rx_ppp = prof->rx_ppp;
+               tx_ppp = prof->tx_ppp;
 
-               priv->prof->rx_pause = 0;
-               priv->prof->tx_pause = 0;
                for (tc = 0; tc < CEE_DCBX_MAX_PRIO; tc++) {
                        u8 tc_mask = 1 << tc;
 
                        switch (priv->cee_config.dcb_pfc[tc]) {
                        case pfc_disabled:
-                               priv->prof->tx_ppp &= ~tc_mask;
-                               priv->prof->rx_ppp &= ~tc_mask;
+                               tx_ppp &= ~tc_mask;
+                               rx_ppp &= ~tc_mask;
                                break;
                        case pfc_enabled_full:
-                               priv->prof->tx_ppp |= tc_mask;
-                               priv->prof->rx_ppp |= tc_mask;
+                               tx_ppp |= tc_mask;
+                               rx_ppp |= tc_mask;
                                break;
                        case pfc_enabled_tx:
-                               priv->prof->tx_ppp |= tc_mask;
-                               priv->prof->rx_ppp &= ~tc_mask;
+                               tx_ppp |= tc_mask;
+                               rx_ppp &= ~tc_mask;
                                break;
                        case pfc_enabled_rx:
-                               priv->prof->tx_ppp &= ~tc_mask;
-                               priv->prof->rx_ppp |= tc_mask;
+                               tx_ppp &= ~tc_mask;
+                               rx_ppp |= tc_mask;
                                break;
                        default:
                                break;
                        }
                }
-               en_dbg(DRV, priv, "Set pfc on\n");
+               rx_pause = !!(rx_ppp || tx_ppp) ? 0 : prof->rx_pause;
+               tx_pause = !!(rx_ppp || tx_ppp) ? 0 : prof->tx_pause;
        } else {
-               priv->prof->rx_pause = 1;
-               priv->prof->tx_pause = 1;
-               en_dbg(DRV, priv, "Set pfc off\n");
+               rx_ppp = 0;
+               tx_ppp = 0;
+               rx_pause = prof->rx_pause;
+               tx_pause = prof->tx_pause;
        }
 
        if (mlx4_SET_PORT_general(mdev->dev, priv->port,
                                  priv->rx_skb_size + ETH_FCS_LEN,
-                                 priv->prof->tx_pause,
-                                 priv->prof->tx_ppp,
-                                 priv->prof->rx_pause,
-                                 priv->prof->rx_ppp)) {
+                                 tx_pause, tx_ppp, rx_pause, rx_ppp)) {
                en_err(priv, "Failed setting pause params\n");
                return 1;
        }
 
+       prof->tx_ppp = tx_ppp;
+       prof->rx_ppp = rx_ppp;
+       prof->tx_pause = tx_pause;
+       prof->rx_pause = rx_pause;
+
        return 0;
 }
 
@@ -408,6 +414,7 @@ static int mlx4_en_dcbnl_ieee_setpfc(struct net_device *dev,
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_port_profile *prof = priv->prof;
        struct mlx4_en_dev *mdev = priv->mdev;
+       u32 tx_pause, tx_ppp, rx_pause, rx_ppp;
        int err;
 
        en_dbg(DRV, priv, "cap: 0x%x en: 0x%x mbc: 0x%x delay: %d\n",
@@ -416,23 +423,26 @@ static int mlx4_en_dcbnl_ieee_setpfc(struct net_device *dev,
                        pfc->mbc,
                        pfc->delay);
 
-       prof->rx_pause = !pfc->pfc_en;
-       prof->tx_pause = !pfc->pfc_en;
-       prof->rx_ppp = pfc->pfc_en;
-       prof->tx_ppp = pfc->pfc_en;
+       rx_pause = prof->rx_pause && !pfc->pfc_en;
+       tx_pause = prof->tx_pause && !pfc->pfc_en;
+       rx_ppp = pfc->pfc_en;
+       tx_ppp = pfc->pfc_en;
 
        err = mlx4_SET_PORT_general(mdev->dev, priv->port,
                                    priv->rx_skb_size + ETH_FCS_LEN,
-                                   prof->tx_pause,
-                                   prof->tx_ppp,
-                                   prof->rx_pause,
-                                   prof->rx_ppp);
-       if (err)
+                                   tx_pause, tx_ppp, rx_pause, rx_ppp);
+       if (err) {
                en_err(priv, "Failed setting pause params\n");
-       else
-               mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
-                                               prof->rx_ppp, prof->rx_pause,
-                                               prof->tx_ppp, prof->tx_pause);
+               return err;
+       }
+
+       mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
+                                       rx_ppp, rx_pause, tx_ppp, tx_pause);
+
+       prof->tx_ppp = tx_ppp;
+       prof->rx_ppp = rx_ppp;
+       prof->rx_pause = rx_pause;
+       prof->tx_pause = tx_pause;
 
        return err;
 }
index ebc1f566a4d953ab623c5fb4ca6dc018375280e3..f3302edba8b47b6fc67008aec7826e09b94514c1 100644 (file)
@@ -1046,27 +1046,32 @@ static int mlx4_en_set_pauseparam(struct net_device *dev,
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
+       u8 tx_pause, tx_ppp, rx_pause, rx_ppp;
        int err;
 
        if (pause->autoneg)
                return -EINVAL;
 
-       priv->prof->tx_pause = pause->tx_pause != 0;
-       priv->prof->rx_pause = pause->rx_pause != 0;
+       tx_pause = !!(pause->tx_pause);
+       rx_pause = !!(pause->rx_pause);
+       rx_ppp = priv->prof->rx_ppp && !(tx_pause || rx_pause);
+       tx_ppp = priv->prof->tx_ppp && !(tx_pause || rx_pause);
+
        err = mlx4_SET_PORT_general(mdev->dev, priv->port,
                                    priv->rx_skb_size + ETH_FCS_LEN,
-                                   priv->prof->tx_pause,
-                                   priv->prof->tx_ppp,
-                                   priv->prof->rx_pause,
-                                   priv->prof->rx_ppp);
-       if (err)
-               en_err(priv, "Failed setting pause params\n");
-       else
-               mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
-                                               priv->prof->rx_ppp,
-                                               priv->prof->rx_pause,
-                                               priv->prof->tx_ppp,
-                                               priv->prof->tx_pause);
+                                   tx_pause, tx_ppp, rx_pause, rx_ppp);
+       if (err) {
+               en_err(priv, "Failed setting pause params, err = %d\n", err);
+               return err;
+       }
+
+       mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
+                                       rx_ppp, rx_pause, tx_ppp, tx_pause);
+
+       priv->prof->tx_pause = tx_pause;
+       priv->prof->rx_pause = rx_pause;
+       priv->prof->tx_ppp = tx_ppp;
+       priv->prof->rx_ppp = rx_ppp;
 
        return err;
 }
index 2c2965497ed35c5b74d0baeed8ff89ae7f0e52d6..d25e16d2c3191ecff8ed758353203de5f7dc9c07 100644 (file)
@@ -163,9 +163,9 @@ static void mlx4_en_get_profile(struct mlx4_en_dev *mdev)
                params->udp_rss = 0;
        }
        for (i = 1; i <= MLX4_MAX_PORTS; i++) {
-               params->prof[i].rx_pause = 1;
+               params->prof[i].rx_pause = !(pfcrx || pfctx);
                params->prof[i].rx_ppp = pfcrx;
-               params->prof[i].tx_pause = 1;
+               params->prof[i].tx_pause = !(pfcrx || pfctx);
                params->prof[i].tx_ppp = pfctx;
                params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
                params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
index 606a0e0beeae6961ae4e8c7a357d737834be614e..29e50f787349c986cdb8b954c783b54efeab770f 100644 (file)
@@ -5088,6 +5088,7 @@ static void rem_slave_fs_rule(struct mlx4_dev *dev, int slave)
                                                 &tracker->res_tree[RES_FS_RULE]);
                                        list_del(&fs_rule->com.list);
                                        spin_unlock_irq(mlx4_tlock(dev));
+                                       kfree(fs_rule->mirr_mbox);
                                        kfree(fs_rule);
                                        state = 0;
                                        break;
index 25deaa5a534c72b38272dc9fefade1ddf74afa5f..c032319f1cb90b4569cf76caabb8d03007ef44c5 100644 (file)
@@ -46,7 +46,7 @@ config MLX5_MPFS
 
 config MLX5_ESWITCH
        bool "Mellanox Technologies MLX5 SRIOV E-Switch support"
-       depends on MLX5_CORE_EN
+       depends on MLX5_CORE_EN && NET_SWITCHDEV
        default y
        ---help---
          Mellanox Technologies Ethernet SRIOV E-Switch support in ConnectX NIC.
index cc8048f68f114452af863a6ef373b5013de710e6..59ebfdae6695debb0f74c2f6f6d741c3dc5478cd 100644 (file)
@@ -477,6 +477,9 @@ static int mlx5e_get_coalesce(struct net_device *netdev,
        return mlx5e_ethtool_get_coalesce(priv, coal);
 }
 
+#define MLX5E_MAX_COAL_TIME            MLX5_MAX_CQ_PERIOD
+#define MLX5E_MAX_COAL_FRAMES          MLX5_MAX_CQ_COUNT
+
 static void
 mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
 {
@@ -511,6 +514,20 @@ int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
        if (!MLX5_CAP_GEN(mdev, cq_moderation))
                return -EOPNOTSUPP;
 
+       if (coal->tx_coalesce_usecs > MLX5E_MAX_COAL_TIME ||
+           coal->rx_coalesce_usecs > MLX5E_MAX_COAL_TIME) {
+               netdev_info(priv->netdev, "%s: maximum coalesce time supported is %lu usecs\n",
+                           __func__, MLX5E_MAX_COAL_TIME);
+               return -ERANGE;
+       }
+
+       if (coal->tx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES ||
+           coal->rx_max_coalesced_frames > MLX5E_MAX_COAL_FRAMES) {
+               netdev_info(priv->netdev, "%s: maximum coalesced frames supported is %lu\n",
+                           __func__, MLX5E_MAX_COAL_FRAMES);
+               return -ERANGE;
+       }
+
        mutex_lock(&priv->state_lock);
        new_channels.params = priv->channels.params;
 
index da94c8cba5ee1b7e8f6309d81fa7db29a1db10b6..9b4827d36e3eeb067738047db8c612fc149e5ca5 100644 (file)
@@ -2572,6 +2572,9 @@ int mlx5e_open(struct net_device *netdev)
                mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
        mutex_unlock(&priv->state_lock);
 
+       if (mlx5e_vxlan_allowed(priv->mdev))
+               udp_tunnel_get_rx_info(netdev);
+
        return err;
 }
 
@@ -4069,7 +4072,7 @@ static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
        }
 }
 
-#if IS_ENABLED(CONFIG_NET_SWITCHDEV) && IS_ENABLED(CONFIG_MLX5_ESWITCH)
+#if IS_ENABLED(CONFIG_MLX5_ESWITCH)
 static const struct switchdev_ops mlx5e_switchdev_ops = {
        .switchdev_port_attr_get        = mlx5e_attr_get,
 };
@@ -4175,7 +4178,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
 
        mlx5e_set_netdev_dev_addr(netdev);
 
-#if IS_ENABLED(CONFIG_NET_SWITCHDEV) && IS_ENABLED(CONFIG_MLX5_ESWITCH)
+#if IS_ENABLED(CONFIG_MLX5_ESWITCH)
        if (MLX5_VPORT_MANAGER(mdev))
                netdev->switchdev_ops = &mlx5e_switchdev_ops;
 #endif
@@ -4327,12 +4330,6 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
 #ifdef CONFIG_MLX5_CORE_EN_DCB
        mlx5e_dcbnl_init_app(priv);
 #endif
-       /* Device already registered: sync netdev system state */
-       if (mlx5e_vxlan_allowed(mdev)) {
-               rtnl_lock();
-               udp_tunnel_get_rx_info(netdev);
-               rtnl_unlock();
-       }
 
        queue_work(priv->wq, &priv->set_rx_mode_work);
 
index 363d8dcb7f174e4b084f93a9379218753a4e41d8..500d817d2b0aea193dfc5523fc869a1f32882c90 100644 (file)
 #include "en_tc.h"
 #include "fs_core.h"
 
+#define MLX5E_REP_PARAMS_LOG_SQ_SIZE \
+       max(0x6, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)
+#define MLX5E_REP_PARAMS_LOG_RQ_SIZE \
+       max(0x6, MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)
+
 static const char mlx5e_rep_driver_name[] = "mlx5e_rep";
 
 static void mlx5e_rep_get_drvinfo(struct net_device *dev,
@@ -209,7 +214,7 @@ static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw,
 
 static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw,
                                 struct mlx5_eswitch_rep *rep,
-                                u16 *sqns_array, int sqns_num)
+                                u32 *sqns_array, int sqns_num)
 {
        struct mlx5_flow_handle *flow_rule;
        struct mlx5e_rep_priv *rpriv;
@@ -255,9 +260,9 @@ int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv)
        struct mlx5e_channel *c;
        int n, tc, num_sqs = 0;
        int err = -ENOMEM;
-       u16 *sqs;
+       u32 *sqs;
 
-       sqs = kcalloc(priv->channels.num * priv->channels.params.num_tc, sizeof(u16), GFP_KERNEL);
+       sqs = kcalloc(priv->channels.num * priv->channels.params.num_tc, sizeof(*sqs), GFP_KERNEL);
        if (!sqs)
                goto out;
 
@@ -288,7 +293,7 @@ void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv)
 static void mlx5e_rep_neigh_update_init_interval(struct mlx5e_rep_priv *rpriv)
 {
 #if IS_ENABLED(CONFIG_IPV6)
-       unsigned long ipv6_interval = NEIGH_VAR(&ipv6_stub->nd_tbl->parms,
+       unsigned long ipv6_interval = NEIGH_VAR(&nd_tbl.parms,
                                                DELAY_PROBE_TIME);
 #else
        unsigned long ipv6_interval = ~0UL;
@@ -424,7 +429,7 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb,
        case NETEVENT_NEIGH_UPDATE:
                n = ptr;
 #if IS_ENABLED(CONFIG_IPV6)
-               if (n->tbl != ipv6_stub->nd_tbl && n->tbl != &arp_tbl)
+               if (n->tbl != &nd_tbl && n->tbl != &arp_tbl)
 #else
                if (n->tbl != &arp_tbl)
 #endif
@@ -472,7 +477,7 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb,
                 * done per device delay prob time parameter.
                 */
 #if IS_ENABLED(CONFIG_IPV6)
-               if (!p->dev || (p->tbl != ipv6_stub->nd_tbl && p->tbl != &arp_tbl))
+               if (!p->dev || (p->tbl != &nd_tbl && p->tbl != &arp_tbl))
 #else
                if (!p->dev || p->tbl != &arp_tbl)
 #endif
@@ -668,7 +673,6 @@ static int mlx5e_rep_open(struct net_device *dev)
        struct mlx5e_priv *priv = netdev_priv(dev);
        struct mlx5e_rep_priv *rpriv = priv->ppriv;
        struct mlx5_eswitch_rep *rep = rpriv->rep;
-       struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
        int err;
 
        mutex_lock(&priv->state_lock);
@@ -676,8 +680,9 @@ static int mlx5e_rep_open(struct net_device *dev)
        if (err)
                goto unlock;
 
-       if (!mlx5_eswitch_set_vport_state(esw, rep->vport,
-                                         MLX5_ESW_VPORT_ADMIN_STATE_UP))
+       if (!mlx5_modify_vport_admin_state(priv->mdev,
+                       MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
+                       rep->vport, MLX5_ESW_VPORT_ADMIN_STATE_UP))
                netif_carrier_on(dev);
 
 unlock:
@@ -690,11 +695,12 @@ static int mlx5e_rep_close(struct net_device *dev)
        struct mlx5e_priv *priv = netdev_priv(dev);
        struct mlx5e_rep_priv *rpriv = priv->ppriv;
        struct mlx5_eswitch_rep *rep = rpriv->rep;
-       struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
        int ret;
 
        mutex_lock(&priv->state_lock);
-       (void)mlx5_eswitch_set_vport_state(esw, rep->vport, MLX5_ESW_VPORT_ADMIN_STATE_DOWN);
+       mlx5_modify_vport_admin_state(priv->mdev,
+                       MLX5_QUERY_VPORT_STATE_IN_OP_MOD_ESW_VPORT,
+                       rep->vport, MLX5_ESW_VPORT_ADMIN_STATE_DOWN);
        ret = mlx5e_close_locked(dev);
        mutex_unlock(&priv->state_lock);
        return ret;
@@ -877,9 +883,9 @@ static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
                                         MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
                                         MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
 
-       params->log_sq_size = MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
+       params->log_sq_size = MLX5E_REP_PARAMS_LOG_SQ_SIZE;
        params->rq_wq_type  = MLX5_WQ_TYPE_LINKED_LIST;
-       params->log_rq_size = MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
+       params->log_rq_size = MLX5E_REP_PARAMS_LOG_RQ_SIZE;
 
        params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
        mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
@@ -899,9 +905,7 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
 
        netdev->ethtool_ops       = &mlx5e_rep_ethtool_ops;
 
-#ifdef CONFIG_NET_SWITCHDEV
        netdev->switchdev_ops = &mlx5e_rep_switchdev_ops;
-#endif
 
        netdev->features         |= NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_TC | NETIF_F_NETNS_LOCAL;
        netdev->hw_features      |= NETIF_F_HW_TC;
index fa86a1466718037f89a5bdb4b2d67e9bbe2b341e..43234cabf4441db2e6318387b98c275da3ca9b68 100644 (file)
@@ -963,7 +963,7 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
                tbl = &arp_tbl;
 #if IS_ENABLED(CONFIG_IPV6)
        else if (m_neigh->family == AF_INET6)
-               tbl = ipv6_stub->nd_tbl;
+               tbl = &nd_tbl;
 #endif
        else
                return;
@@ -2608,19 +2608,19 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv,
        if (err != -EAGAIN)
                flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
 
+       if (!(flow->flags & MLX5E_TC_FLOW_ESWITCH) ||
+           !(flow->esw_attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP))
+               kvfree(parse_attr);
+
        err = rhashtable_insert_fast(&tc->ht, &flow->node,
                                     tc->ht_params);
-       if (err)
-               goto err_del_rule;
+       if (err) {
+               mlx5e_tc_del_flow(priv, flow);
+               kfree(flow);
+       }
 
-       if (flow->flags & MLX5E_TC_FLOW_ESWITCH &&
-           !(flow->esw_attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP))
-               kvfree(parse_attr);
        return err;
 
-err_del_rule:
-       mlx5e_tc_del_flow(priv, flow);
-
 err_free:
        kvfree(parse_attr);
        kfree(flow);
index f7948e983637da5e887d47cd3af80ebdc599c872..997e24dcb053ee2f2c87f2bc27c37918e5a7a23d 100644 (file)
@@ -1380,6 +1380,55 @@ mlxsw_sp_ipip_entry_ol_up_event(struct mlxsw_sp *mlxsw_sp,
                                                  decap_fib_entry);
 }
 
+static int
+mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif,
+                       struct mlxsw_sp_vr *ul_vr, bool enable)
+{
+       struct mlxsw_sp_rif_ipip_lb_config lb_cf = lb_rif->lb_config;
+       struct mlxsw_sp_rif *rif = &lb_rif->common;
+       struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
+       char ritr_pl[MLXSW_REG_RITR_LEN];
+       u32 saddr4;
+
+       switch (lb_cf.ul_protocol) {
+       case MLXSW_SP_L3_PROTO_IPV4:
+               saddr4 = be32_to_cpu(lb_cf.saddr.addr4);
+               mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF,
+                                   rif->rif_index, rif->vr_id, rif->dev->mtu);
+               mlxsw_reg_ritr_loopback_ipip4_pack(ritr_pl, lb_cf.lb_ipipt,
+                           MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET,
+                           ul_vr->id, saddr4, lb_cf.okey);
+               break;
+
+       case MLXSW_SP_L3_PROTO_IPV6:
+               return -EAFNOSUPPORT;
+       }
+
+       return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
+}
+
+static int mlxsw_sp_netdevice_ipip_ol_update_mtu(struct mlxsw_sp *mlxsw_sp,
+                                                struct net_device *ol_dev)
+{
+       struct mlxsw_sp_ipip_entry *ipip_entry;
+       struct mlxsw_sp_rif_ipip_lb *lb_rif;
+       struct mlxsw_sp_vr *ul_vr;
+       int err = 0;
+
+       ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, ol_dev);
+       if (ipip_entry) {
+               lb_rif = ipip_entry->ol_lb;
+               ul_vr = &mlxsw_sp->router->vrs[lb_rif->ul_vr_id];
+               err = mlxsw_sp_rif_ipip_lb_op(lb_rif, ul_vr, true);
+               if (err)
+                       goto out;
+               lb_rif->common.mtu = ol_dev->mtu;
+       }
+
+out:
+       return err;
+}
+
 static void mlxsw_sp_netdevice_ipip_ol_up_event(struct mlxsw_sp *mlxsw_sp,
                                                struct net_device *ol_dev)
 {
@@ -1660,6 +1709,8 @@ int mlxsw_sp_netdevice_ipip_ol_event(struct mlxsw_sp *mlxsw_sp,
                extack = info->extack;
                return mlxsw_sp_netdevice_ipip_ol_change_event(mlxsw_sp,
                                                               ol_dev, extack);
+       case NETDEV_CHANGEMTU:
+               return mlxsw_sp_netdevice_ipip_ol_update_mtu(mlxsw_sp, ol_dev);
        }
        return 0;
 }
@@ -6843,33 +6894,6 @@ mlxsw_sp_rif_ipip_lb_setup(struct mlxsw_sp_rif *rif,
        rif_lb->lb_config = params_lb->lb_config;
 }
 
-static int
-mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif,
-                       struct mlxsw_sp_vr *ul_vr, bool enable)
-{
-       struct mlxsw_sp_rif_ipip_lb_config lb_cf = lb_rif->lb_config;
-       struct mlxsw_sp_rif *rif = &lb_rif->common;
-       struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
-       char ritr_pl[MLXSW_REG_RITR_LEN];
-       u32 saddr4;
-
-       switch (lb_cf.ul_protocol) {
-       case MLXSW_SP_L3_PROTO_IPV4:
-               saddr4 = be32_to_cpu(lb_cf.saddr.addr4);
-               mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF,
-                                   rif->rif_index, rif->vr_id, rif->dev->mtu);
-               mlxsw_reg_ritr_loopback_ipip4_pack(ritr_pl, lb_cf.lb_ipipt,
-                           MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET,
-                           ul_vr->id, saddr4, lb_cf.okey);
-               break;
-
-       case MLXSW_SP_L3_PROTO_IPV6:
-               return -EAFNOSUPPORT;
-       }
-
-       return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
-}
-
 static int
 mlxsw_sp_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif)
 {
index 56451edf01c2c689ee8199aa765f59e4ffa21d8e..ecd7c33baf3c9c1d014bc460d0d9c9048c08e548 100644 (file)
@@ -74,7 +74,9 @@ nfp_meta_has_prev(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
 
 static void nfp_prog_push(struct nfp_prog *nfp_prog, u64 insn)
 {
-       if (nfp_prog->__prog_alloc_len == nfp_prog->prog_len) {
+       if (nfp_prog->__prog_alloc_len / sizeof(u64) == nfp_prog->prog_len) {
+               pr_warn("instruction limit reached (%u NFP instructions)\n",
+                       nfp_prog->prog_len);
                nfp_prog->error = -ENOSPC;
                return;
        }
@@ -2463,6 +2465,8 @@ static int nfp_translate(struct nfp_prog *nfp_prog)
                err = cb(nfp_prog, meta);
                if (err)
                        return err;
+               if (nfp_prog->error)
+                       return nfp_prog->error;
 
                nfp_prog->n_translated++;
        }
index dafc079ab6b97b47665ec363ecd6b47065a1e41f..14941303189dcffcbb1d302d925389a785c257d0 100644 (file)
@@ -320,13 +320,11 @@ static inline void qede_update_tx_producer(struct qede_tx_queue *txq)
        barrier();
        writel(txq->tx_db.raw, txq->doorbell_addr);
 
-       /* mmiowb is needed to synchronize doorbell writes from more than one
-        * processor. It guarantees that the write arrives to the device before
-        * the queue lock is released and another start_xmit is called (possibly
-        * on another CPU). Without this barrier, the next doorbell can bypass
-        * this doorbell. This is applicable to IA64/Altix systems.
+       /* Fence required to flush the write combined buffer, since another
+        * CPU may write to the same doorbell address and data may be lost
+        * due to relaxed order nature of write combined bar.
         */
-       mmiowb();
+       wmb();
 }
 
 static int qede_xdp_xmit(struct qede_dev *edev, struct qede_fastpath *fp,
@@ -1249,16 +1247,10 @@ static int qede_rx_process_cqe(struct qede_dev *edev,
 
        csum_flag = qede_check_csum(parse_flag);
        if (unlikely(csum_flag == QEDE_CSUM_ERROR)) {
-               if (qede_pkt_is_ip_fragmented(fp_cqe, parse_flag)) {
+               if (qede_pkt_is_ip_fragmented(fp_cqe, parse_flag))
                        rxq->rx_ip_frags++;
-               } else {
-                       DP_NOTICE(edev,
-                                 "CQE has error, flags = %x, dropping incoming packet\n",
-                                 parse_flag);
+               else
                        rxq->rx_hw_errors++;
-                       qede_recycle_rx_bd_ring(rxq, fp_cqe->bd_num);
-                       return 0;
-               }
        }
 
        /* Basic validation passed; Need to prepare an SKB. This would also
index 0bf7d175925036644894aedf4835eece7c01877a..b4779acb6b5c1f64b54f296a9727099e22f0ca4e 100644 (file)
@@ -8660,12 +8660,12 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!tp->counters)
                return -ENOMEM;
 
+       pci_set_drvdata(pdev, dev);
+
        rc = register_netdev(dev);
        if (rc < 0)
                return rc;
 
-       pci_set_drvdata(pdev, dev);
-
        netif_info(tp, probe, dev, "%s at 0x%p, %pM, XID %08x IRQ %d\n",
                   rtl_chip_infos[chipset].name, ioaddr, dev->dev_addr,
                   (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), pdev->irq);
index a6ec41c399d6c980b86ac1242179e99de542e5ea..465c42e305084393821ddb304f7827e831d65d81 100644 (file)
@@ -858,7 +858,7 @@ static void rndis_set_multicast(struct work_struct *w)
        if (flags & IFF_PROMISC) {
                filter = NDIS_PACKET_TYPE_PROMISCUOUS;
        } else {
-               if (flags & IFF_ALLMULTI)
+               if (!netdev_mc_empty(rdev->ndev) || (flags & IFF_ALLMULTI))
                        filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
                if (flags & IFF_BROADCAST)
                        filter |= NDIS_PACKET_TYPE_BROADCAST;
index 56c701b73c127c15db191b151b8f5e084782f892..befed2d22bf47eae68dac94953b8e9079c1cb5d1 100644 (file)
@@ -1197,11 +1197,6 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
                goto err_dev_open;
        }
 
-       netif_addr_lock_bh(dev);
-       dev_uc_sync_multiple(port_dev, dev);
-       dev_mc_sync_multiple(port_dev, dev);
-       netif_addr_unlock_bh(dev);
-
        err = vlan_vids_add_by_dev(port_dev, dev);
        if (err) {
                netdev_err(dev, "Failed to add vlan ids to device %s\n",
@@ -1241,6 +1236,11 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
                goto err_option_port_add;
        }
 
+       netif_addr_lock_bh(dev);
+       dev_uc_sync_multiple(port_dev, dev);
+       dev_mc_sync_multiple(port_dev, dev);
+       netif_addr_unlock_bh(dev);
+
        port->index = -1;
        list_add_tail_rcu(&port->list, &team->port_list);
        team_port_enable(team, port);
@@ -1265,8 +1265,6 @@ err_enable_netpoll:
        vlan_vids_del_by_dev(port_dev, dev);
 
 err_vids_add:
-       dev_uc_unsync(port_dev, dev);
-       dev_mc_unsync(port_dev, dev);
        dev_close(port_dev);
 
 err_dev_open:
index 60a604cc7647e460539d0482c69f9ffc8f882aa1..55a78eb96961ef35c5dfccf94bca45ccda13aa09 100644 (file)
@@ -2351,6 +2351,7 @@ static int lan78xx_reset(struct lan78xx_net *dev)
        u32 buf;
        int ret = 0;
        unsigned long timeout;
+       u8 sig;
 
        ret = lan78xx_read_reg(dev, HW_CFG, &buf);
        buf |= HW_CFG_LRST_;
@@ -2450,6 +2451,15 @@ static int lan78xx_reset(struct lan78xx_net *dev)
        /* LAN7801 only has RGMII mode */
        if (dev->chipid == ID_REV_CHIP_ID_7801_)
                buf &= ~MAC_CR_GMII_EN_;
+
+       if (dev->chipid == ID_REV_CHIP_ID_7800_) {
+               ret = lan78xx_read_raw_eeprom(dev, 0, 1, &sig);
+               if (!ret && sig != EEPROM_INDICATOR) {
+                       /* Implies there is no external eeprom. Set mac speed */
+                       netdev_info(dev->net, "No External EEPROM. Setting MAC Speed\n");
+                       buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_;
+               }
+       }
        ret = lan78xx_write_reg(dev, MAC_CR, buf);
 
        ret = lan78xx_read_reg(dev, MAC_TX, &buf);
@@ -2863,8 +2873,7 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
        if (ret < 0) {
                netdev_warn(dev->net,
                            "lan78xx_setup_irq_domain() failed : %d", ret);
-               kfree(pdata);
-               return ret;
+               goto out1;
        }
 
        dev->net->hard_header_len += TX_OVERHEAD;
@@ -2872,14 +2881,32 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
 
        /* Init all registers */
        ret = lan78xx_reset(dev);
+       if (ret) {
+               netdev_warn(dev->net, "Registers INIT FAILED....");
+               goto out2;
+       }
 
        ret = lan78xx_mdio_init(dev);
+       if (ret) {
+               netdev_warn(dev->net, "MDIO INIT FAILED.....");
+               goto out2;
+       }
 
        dev->net->flags |= IFF_MULTICAST;
 
        pdata->wol = WAKE_MAGIC;
 
        return ret;
+
+out2:
+       lan78xx_remove_irq_domain(dev);
+
+out1:
+       netdev_warn(dev->net, "Bind routine FAILED");
+       cancel_work_sync(&pdata->set_multicast);
+       cancel_work_sync(&pdata->set_vlan);
+       kfree(pdata);
+       return ret;
 }
 
 static void lan78xx_unbind(struct lan78xx_net *dev, struct usb_interface *intf)
@@ -2891,6 +2918,8 @@ static void lan78xx_unbind(struct lan78xx_net *dev, struct usb_interface *intf)
        lan78xx_remove_mdio(dev);
 
        if (pdata) {
+               cancel_work_sync(&pdata->set_multicast);
+               cancel_work_sync(&pdata->set_vlan);
                netif_dbg(dev, ifdown, dev->net, "free pdata");
                kfree(pdata);
                pdata = NULL;
index 76ac48095c29e6a06d9bf38fff801b8fa682e399..ca066b785e9f550b27e24412c6ac9bcdd6ecdc97 100644 (file)
@@ -1104,6 +1104,9 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x0846, 0x68a2, 8)},
        {QMI_FIXED_INTF(0x12d1, 0x140c, 1)},    /* Huawei E173 */
        {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)},    /* Huawei E1820 */
+       {QMI_FIXED_INTF(0x1435, 0xd181, 3)},    /* Wistron NeWeb D18Q1 */
+       {QMI_FIXED_INTF(0x1435, 0xd181, 4)},    /* Wistron NeWeb D18Q1 */
+       {QMI_FIXED_INTF(0x1435, 0xd181, 5)},    /* Wistron NeWeb D18Q1 */
        {QMI_FIXED_INTF(0x16d8, 0x6003, 0)},    /* CMOTech 6003 */
        {QMI_FIXED_INTF(0x16d8, 0x6007, 0)},    /* CMOTech CHE-628S */
        {QMI_FIXED_INTF(0x16d8, 0x6008, 0)},    /* CMOTech CMU-301 */
@@ -1180,6 +1183,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x19d2, 0x2002, 4)},    /* ZTE (Vodafone) K3765-Z */
        {QMI_FIXED_INTF(0x2001, 0x7e19, 4)},    /* D-Link DWM-221 B1 */
        {QMI_FIXED_INTF(0x2001, 0x7e35, 4)},    /* D-Link DWM-222 */
+       {QMI_FIXED_INTF(0x2020, 0x2033, 4)},    /* BroadMobi BM806U */
        {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)},    /* Sierra Wireless MC7700 */
        {QMI_FIXED_INTF(0x114f, 0x68a2, 8)},    /* Sierra Wireless MC7750 */
        {QMI_FIXED_INTF(0x1199, 0x68a2, 8)},    /* Sierra Wireless MC7710 in QMI mode */
@@ -1240,6 +1244,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x413c, 0x81b6, 8)},    /* Dell Wireless 5811e */
        {QMI_FIXED_INTF(0x413c, 0x81b6, 10)},   /* Dell Wireless 5811e */
        {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)},    /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
+       {QMI_FIXED_INTF(0x03f0, 0x9d1d, 1)},    /* HP lt4120 Snapdragon X5 LTE */
        {QMI_FIXED_INTF(0x22de, 0x9061, 3)},    /* WeTelecom WPD-600N */
        {QMI_FIXED_INTF(0x1e0e, 0x9001, 5)},    /* SIMCom 7230E */
        {QMI_QUIRK_SET_DTR(0x2c7c, 0x0125, 4)}, /* Quectel EC25, EC20 R2.0  Mini PCIe */
index 139c61c8244ad9099ed8d6377b74eff446354e10..ac40924fe437d35226caeeb26aea1af3ef6d0fbb 100644 (file)
@@ -578,12 +578,13 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
        if (!IS_ERR(neigh)) {
                sock_confirm_neigh(skb, neigh);
                ret = neigh_output(neigh, skb);
+               rcu_read_unlock_bh();
+               return ret;
        }
 
        rcu_read_unlock_bh();
 err:
-       if (unlikely(ret < 0))
-               vrf_tx_error(skb->dev, skb);
+       vrf_tx_error(skb->dev, skb);
        return ret;
 }
 
index 15fa00d79fc66bb7eb7d7c770c6980ee45333355..1ad97a40940de6ebdc2648aaab0093f5d5d19579 100644 (file)
@@ -6802,7 +6802,7 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
                return;
 
        /* ignore non-ISO3166 country codes */
-       for (i = 0; i < sizeof(req->alpha2); i++)
+       for (i = 0; i < 2; i++)
                if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
                        brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n",
                                  req->alpha2[0], req->alpha2[1]);
index 9be0b051066a23214a2b29a0cac18ef64548427e..ebe35e6a40e7bdf36f520ccd355ea217932c8d1a 100644 (file)
@@ -75,6 +75,10 @@ static int brcmf_roamoff;
 module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
 MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
 
+static int brcmf_iapp_enable;
+module_param_named(iapp, brcmf_iapp_enable, int, 0);
+MODULE_PARM_DESC(iapp, "Enable partial support for the obsoleted Inter-Access Point Protocol");
+
 #ifdef DEBUG
 /* always succeed brcmf_bus_started() */
 static int brcmf_ignore_probe_fail;
@@ -441,6 +445,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
        settings->feature_disable = brcmf_feature_disable;
        settings->fcmode = brcmf_fcmode;
        settings->roamoff = !!brcmf_roamoff;
+       settings->iapp = !!brcmf_iapp_enable;
 #ifdef DEBUG
        settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
 #endif
index a62f8e70b32078ef3d83e38c3eca4b3362c44aba..ef914619e8e152bebe1403a2d17ac94092d72bbb 100644 (file)
@@ -58,6 +58,7 @@ struct brcmf_mp_device {
        unsigned int    feature_disable;
        int             fcmode;
        bool            roamoff;
+       bool            iapp;
        bool            ignore_probe_fail;
        struct brcmfmac_pd_cc *country_codes;
        union {
index 930e423f83a86803e02c9e7795a7f4cfc013fa43..44b7774ebd025d960edc7b8e03321ae3cd08f4ee 100644 (file)
@@ -230,6 +230,37 @@ static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
        schedule_work(&ifp->multicast_work);
 }
 
+/**
+ * brcmf_skb_is_iapp - checks if skb is an IAPP packet
+ *
+ * @skb: skb to check
+ */
+static bool brcmf_skb_is_iapp(struct sk_buff *skb)
+{
+       static const u8 iapp_l2_update_packet[6] __aligned(2) = {
+               0x00, 0x01, 0xaf, 0x81, 0x01, 0x00,
+       };
+       unsigned char *eth_data;
+#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+       const u16 *a, *b;
+#endif
+
+       if (skb->len - skb->mac_len != 6 ||
+           !is_multicast_ether_addr(eth_hdr(skb)->h_dest))
+               return false;
+
+       eth_data = skb_mac_header(skb) + ETH_HLEN;
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+       return !(((*(const u32 *)eth_data) ^ (*(const u32 *)iapp_l2_update_packet)) |
+                ((*(const u16 *)(eth_data + 4)) ^ (*(const u16 *)(iapp_l2_update_packet + 4))));
+#else
+       a = (const u16 *)eth_data;
+       b = (const u16 *)iapp_l2_update_packet;
+
+       return !((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]));
+#endif
+}
+
 static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
                                           struct net_device *ndev)
 {
@@ -250,6 +281,23 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
                goto done;
        }
 
+       /* Some recent Broadcom's firmwares disassociate STA when they receive
+        * an 802.11f ADD frame. This behavior can lead to a local DoS security
+        * issue. Attacker may trigger disassociation of any STA by sending a
+        * proper Ethernet frame to the wireless interface.
+        *
+        * Moreover this feature may break AP interfaces in some specific
+        * setups. This applies e.g. to the bridge with hairpin mode enabled and
+        * IFLA_BRPORT_MCAST_TO_UCAST set. IAPP packet generated by a firmware
+        * will get passed back to the wireless interface and cause immediate
+        * disassociation of a just-connected STA.
+        */
+       if (!drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {
+               dev_kfree_skb(skb);
+               ret = -EINVAL;
+               goto done;
+       }
+
        /* Make sure there's enough writeable headroom */
        if (skb_headroom(skb) < drvr->hdrlen || skb_header_cloned(skb)) {
                head_delta = max_t(int, drvr->hdrlen - skb_headroom(skb), 0);
@@ -325,6 +373,15 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
 
 void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
 {
+       /* Most of Broadcom's firmwares send 802.11f ADD frame every time a new
+        * STA connects to the AP interface. This is an obsoleted standard most
+        * users don't use, so don't pass these frames up unless requested.
+        */
+       if (!ifp->drvr->settings->iapp && brcmf_skb_is_iapp(skb)) {
+               brcmu_pkt_buf_free_skb(skb);
+               return;
+       }
+
        if (skb->pkt_type == PACKET_MULTICAST)
                ifp->ndev->stats.multicast++;
 
index 90a1d14cf7d2b4040a72dc26ce3d2c4f37b7d682..ab1469473e4ffe6238d035188a5251bebd656ab9 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/stringify.h>
 #include "iwl-config.h"
 #include "iwl-agn-hw.h"
+#include "fw/file.h"
 
 /* Highest firmware API version supported */
 #define IWL9000_UCODE_API_MAX  36
@@ -265,6 +266,67 @@ const struct iwl_cfg iwl9560_2ac_cfg_soc = {
        .integrated = true,
        .soc_latency = 5000,
 };
+
+const struct iwl_cfg iwl9460_2ac_cfg_shared_clk = {
+       .name = "Intel(R) Dual Band Wireless AC 9460",
+       .fw_name_pre = IWL9000A_FW_PRE,
+       .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+       .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+       IWL_DEVICE_9000,
+       .ht_params = &iwl9000_ht_params,
+       .nvm_ver = IWL9000_NVM_VERSION,
+       .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+       .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+       .integrated = true,
+       .soc_latency = 5000,
+       .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
+const struct iwl_cfg iwl9461_2ac_cfg_shared_clk = {
+       .name = "Intel(R) Dual Band Wireless AC 9461",
+       .fw_name_pre = IWL9000A_FW_PRE,
+       .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+       .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+       IWL_DEVICE_9000,
+       .ht_params = &iwl9000_ht_params,
+       .nvm_ver = IWL9000_NVM_VERSION,
+       .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+       .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+       .integrated = true,
+       .soc_latency = 5000,
+       .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
+const struct iwl_cfg iwl9462_2ac_cfg_shared_clk = {
+       .name = "Intel(R) Dual Band Wireless AC 9462",
+       .fw_name_pre = IWL9000A_FW_PRE,
+       .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+       .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+       IWL_DEVICE_9000,
+       .ht_params = &iwl9000_ht_params,
+       .nvm_ver = IWL9000_NVM_VERSION,
+       .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+       .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+       .integrated = true,
+       .soc_latency = 5000,
+       .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
+const struct iwl_cfg iwl9560_2ac_cfg_shared_clk = {
+       .name = "Intel(R) Dual Band Wireless AC 9560",
+       .fw_name_pre = IWL9000A_FW_PRE,
+       .fw_name_pre_b_or_c_step = IWL9000B_FW_PRE,
+       .fw_name_pre_rf_next_step = IWL9000RFB_FW_PRE,
+       IWL_DEVICE_9000,
+       .ht_params = &iwl9000_ht_params,
+       .nvm_ver = IWL9000_NVM_VERSION,
+       .nvm_calib_ver = IWL9000_TX_POWER_VERSION,
+       .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
+       .integrated = true,
+       .soc_latency = 5000,
+       .extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
+};
+
 MODULE_FIRMWARE(IWL9000A_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL9000B_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL9000RFB_MODULE_FIRMWARE(IWL9000_UCODE_API_MAX));
index 1a05d506ac9a5f6ee7e1affe8dfb4f797b525bd4..2cb303c5c42e259083e43ebe66360d9263a0dbb2 100644 (file)
@@ -441,6 +441,7 @@ enum iwl_fw_phy_cfg {
        FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
        FW_PHY_CFG_RX_CHAIN_POS = 20,
        FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
+       FW_PHY_CFG_SHARED_CLK = BIT(31),
 };
 
 #define IWL_UCODE_MAX_CS               1
index 258d439bb0a9ce40782371fc33281270891bd5a5..f0f5636dd3ea8bca460013659a7db43d58431ce8 100644 (file)
@@ -398,6 +398,7 @@ struct iwl_cfg {
        u8 ucode_api_max;
        u8 ucode_api_min;
        u32 min_umac_error_event_table;
+       u32 extra_phy_cfg_flags;
 };
 
 /*
@@ -477,6 +478,10 @@ extern const struct iwl_cfg iwl9460_2ac_cfg_soc;
 extern const struct iwl_cfg iwl9461_2ac_cfg_soc;
 extern const struct iwl_cfg iwl9462_2ac_cfg_soc;
 extern const struct iwl_cfg iwl9560_2ac_cfg_soc;
+extern const struct iwl_cfg iwl9460_2ac_cfg_shared_clk;
+extern const struct iwl_cfg iwl9461_2ac_cfg_shared_clk;
+extern const struct iwl_cfg iwl9462_2ac_cfg_shared_clk;
+extern const struct iwl_cfg iwl9560_2ac_cfg_shared_clk;
 extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
 extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
 extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
index 0920be637b575009e70f579862d4ae612f09c44d..3c59109bea206ab778cc7748b1987a460ad32fa1 100644 (file)
@@ -433,6 +433,10 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
 
        /* Set parameters */
        phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm));
+
+       /* set flags extra PHY configuration flags from the device's cfg */
+       phy_cfg_cmd.phy_cfg |= cpu_to_le32(mvm->cfg->extra_phy_cfg_flags);
+
        phy_cfg_cmd.calib_control.event_trigger =
                mvm->fw->default_calib[ucode_type].event_trigger;
        phy_cfg_cmd.calib_control.flow_trigger =
index ebf511150f4d02561362d8f3973ec2751cb8d3ef..7152fdc00fb17cb4ef5c173f72c829c706e13231 100644 (file)
@@ -2132,10 +2132,10 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
                 * Send the bcast station. At this stage the TBTT and DTIM time
                 * events are added and applied to the scheduler
                 */
-               iwl_mvm_send_add_bcast_sta(mvm, vif);
+               ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
                if (ret)
                        goto out_unbind;
-               iwl_mvm_add_mcast_sta(mvm, vif);
+               ret = iwl_mvm_add_mcast_sta(mvm, vif);
                if (ret) {
                        iwl_mvm_send_rm_bcast_sta(mvm, vif);
                        goto out_unbind;
@@ -3494,6 +3494,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
                ret = 0;
                goto out;
        case NL80211_IFTYPE_STATION:
+               mvmvif->csa_bcn_pending = false;
                break;
        case NL80211_IFTYPE_MONITOR:
                /* always disable PS when a monitor interface is active */
@@ -3537,7 +3538,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
        }
 
        if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) {
-               u32 duration = 2 * vif->bss_conf.beacon_int;
+               u32 duration = 3 * vif->bss_conf.beacon_int;
 
                /* iwl_mvm_protect_session() reads directly from the
                 * device (the system time), so make sure it is
@@ -3550,6 +3551,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
                /* Protect the session to make sure we hear the first
                 * beacon on the new channel.
                 */
+               mvmvif->csa_bcn_pending = true;
                iwl_mvm_protect_session(mvm, vif, duration, duration,
                                        vif->bss_conf.beacon_int / 2,
                                        true);
@@ -3988,6 +3990,7 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
        if (vif->type == NL80211_IFTYPE_STATION) {
                struct iwl_mvm_sta *mvmsta;
 
+               mvmvif->csa_bcn_pending = false;
                mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
                                                          mvmvif->ap_sta_id);
 
index 89ff02d7c87663ce7a1351940308292234f85a48..625b238a3f0a71c72897eb97a00be7ffb2ddddf1 100644 (file)
@@ -438,6 +438,9 @@ struct iwl_mvm_vif {
        bool csa_failed;
        u16 csa_target_freq;
 
+       /* Indicates that we are waiting for a beacon on a new channel */
+       bool csa_bcn_pending;
+
        /* TCP Checksum Offload */
        netdev_features_t features;
 };
index 305cd56bf7464f8788b0fa384746efea2367c01e..7f5434b34d0d737e87b5511070b4cdc4cb96315e 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  * Copyright(c) 2017           Intel Deutschland GmbH
+ * Copyright(c) 2018           Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
  * The full GNU General Public License is included in this distribution
  * in the file called COPYING.
  *
@@ -34,6 +30,7 @@
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2018           Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -286,6 +283,20 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
                return;
 
        ctxt->ref--;
+
+       /*
+        * Move unused phy's to a default channel. When the phy is moved the,
+        * fw will cleanup immediate quiet bit if it was previously set,
+        * otherwise we might not be able to reuse this phy.
+        */
+       if (ctxt->ref == 0) {
+               struct ieee80211_channel *chan;
+               struct cfg80211_chan_def chandef;
+
+               chan = &mvm->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[0];
+               cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
+               iwl_mvm_phy_ctxt_changed(mvm, ctxt, &chandef, 1, 1);
+       }
 }
 
 static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
index 630e23cb0ffb55f9cbbc4ef4496beba4d4bc62c2..80067eb9ea0510ad17136a496562d581ea8edce6 100644 (file)
@@ -1695,7 +1695,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm,
                             u32 qmask, enum nl80211_iftype iftype,
                             enum iwl_sta_type type)
 {
-       if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
+       if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
+           sta->sta_id == IWL_MVM_INVALID_STA) {
                sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype);
                if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA))
                        return -ENOSPC;
@@ -2478,28 +2479,12 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
        /*
         * Note the possible cases:
-        *  1. In DQA mode with an enabled TXQ - TXQ needs to become agg'ed
-        *  2. Non-DQA mode: the TXQ hasn't yet been enabled, so find a free
-        *      one and mark it as reserved
-        *  3. In DQA mode, but no traffic yet on this TID: same treatment as in
-        *      non-DQA mode, since the TXQ hasn't yet been allocated
-        * Don't support case 3 for new TX path as it is not expected to happen
-        * and aggregation will be offloaded soon anyway
+        *  1. An enabled TXQ - TXQ needs to become agg'ed
+        *  2. The TXQ hasn't yet been enabled, so find a free one and mark
+        *      it as reserved
         */
        txq_id = mvmsta->tid_data[tid].txq_id;
-       if (iwl_mvm_has_new_tx_api(mvm)) {
-               if (txq_id == IWL_MVM_INVALID_QUEUE) {
-                       ret = -ENXIO;
-                       goto release_locks;
-               }
-       } else if (unlikely(mvm->queue_info[txq_id].status ==
-                           IWL_MVM_QUEUE_SHARED)) {
-               ret = -ENXIO;
-               IWL_DEBUG_TX_QUEUES(mvm,
-                                   "Can't start tid %d agg on shared queue!\n",
-                                   tid);
-               goto release_locks;
-       } else if (mvm->queue_info[txq_id].status != IWL_MVM_QUEUE_READY) {
+       if (txq_id == IWL_MVM_INVALID_QUEUE) {
                txq_id = iwl_mvm_find_free_queue(mvm, mvmsta->sta_id,
                                                 IWL_MVM_DQA_MIN_DATA_QUEUE,
                                                 IWL_MVM_DQA_MAX_DATA_QUEUE);
@@ -2508,16 +2493,16 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                        IWL_ERR(mvm, "Failed to allocate agg queue\n");
                        goto release_locks;
                }
-               /*
-                * TXQ shouldn't be in inactive mode for non-DQA, so getting
-                * an inactive queue from iwl_mvm_find_free_queue() is
-                * certainly a bug
-                */
-               WARN_ON(mvm->queue_info[txq_id].status ==
-                       IWL_MVM_QUEUE_INACTIVE);
 
                /* TXQ hasn't yet been enabled, so mark it only as reserved */
                mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED;
+       } else if (unlikely(mvm->queue_info[txq_id].status ==
+                           IWL_MVM_QUEUE_SHARED)) {
+               ret = -ENXIO;
+               IWL_DEBUG_TX_QUEUES(mvm,
+                                   "Can't start tid %d agg on shared queue!\n",
+                                   tid);
+               goto release_locks;
        }
 
        spin_unlock(&mvm->queue_info_lock);
@@ -2696,8 +2681,10 @@ out:
 
 static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm,
                                        struct iwl_mvm_sta *mvmsta,
-                                       u16 txq_id)
+                                       struct iwl_mvm_tid_data *tid_data)
 {
+       u16 txq_id = tid_data->txq_id;
+
        if (iwl_mvm_has_new_tx_api(mvm))
                return;
 
@@ -2709,8 +2696,10 @@ static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm,
         * allocated through iwl_mvm_enable_txq, so we can just mark it back as
         * free.
         */
-       if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED)
+       if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED) {
                mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_FREE;
+               tid_data->txq_id = IWL_MVM_INVALID_QUEUE;
+       }
 
        spin_unlock_bh(&mvm->queue_info_lock);
 }
@@ -2741,7 +2730,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
        mvmsta->agg_tids &= ~BIT(tid);
 
-       iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id);
+       iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
 
        switch (tid_data->state) {
        case IWL_AGG_ON:
@@ -2808,7 +2797,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        mvmsta->agg_tids &= ~BIT(tid);
        spin_unlock_bh(&mvmsta->lock);
 
-       iwl_mvm_unreserve_agg_queue(mvm, mvmsta, txq_id);
+       iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
 
        if (old_state >= IWL_AGG_ON) {
                iwl_mvm_drain_sta(mvm, mvmsta, true);
@@ -3233,17 +3222,9 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
                }
                sta_id = mvm_sta->sta_id;
 
-               if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
-                   keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
-                   keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) {
-                       ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id,
-                                                   false);
-                       goto end;
-               }
-
                /*
                 * It is possible that the 'sta' parameter is NULL, and thus
-                * there is a need to retrieve  the sta from the local station
+                * there is a need to retrieve the sta from the local station
                 * table.
                 */
                if (!sta) {
@@ -3258,6 +3239,17 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
 
                if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif))
                        return -EINVAL;
+       } else {
+               struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+               sta_id = mvmvif->mcast_sta.sta_id;
+       }
+
+       if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
+           keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
+           keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) {
+               ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, false);
+               goto end;
        }
 
        /* If the key_offset is not pre-assigned, we need to find a
index acb217e666dbc6c38a88e88bb84f8992f01c8082..cd91bc44259c63c549062a62bd08cc7705e2748d 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
  * The full GNU General Public License is included in this distribution
  * in the file called COPYING.
  *
@@ -35,6 +31,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -198,9 +195,13 @@ static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm,
                                        struct ieee80211_vif *vif,
                                        const char *errmsg)
 {
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
        if (vif->type != NL80211_IFTYPE_STATION)
                return false;
-       if (vif->bss_conf.assoc && vif->bss_conf.dtim_period)
+
+       if (!mvmvif->csa_bcn_pending && vif->bss_conf.assoc &&
+           vif->bss_conf.dtim_period)
                return false;
        if (errmsg)
                IWL_ERR(mvm, "%s\n", errmsg);
@@ -344,7 +345,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
                         * and know the dtim period.
                         */
                        iwl_mvm_te_check_disconnect(mvm, te_data->vif,
-                               "No association and the time event is over already...");
+                               "No beacon heard and the time event is over already...");
                        break;
                default:
                        break;
index af6dfceab6b855baad6cfb2878dc431ce924f79c..7dfe4cde55e39d2445c672904a429bda09269485 100644 (file)
@@ -1894,14 +1894,12 @@ int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal, u32 flags)
        struct iwl_mvm_int_sta *int_sta = sta;
        struct iwl_mvm_sta *mvm_sta = sta;
 
-       if (iwl_mvm_has_new_tx_api(mvm)) {
-               if (internal)
-                       return iwl_mvm_flush_sta_tids(mvm, int_sta->sta_id,
-                                                     BIT(IWL_MGMT_TID), flags);
+       BUILD_BUG_ON(offsetof(struct iwl_mvm_int_sta, sta_id) !=
+                    offsetof(struct iwl_mvm_sta, sta_id));
 
+       if (iwl_mvm_has_new_tx_api(mvm))
                return iwl_mvm_flush_sta_tids(mvm, mvm_sta->sta_id,
-                                             0xFF, flags);
-       }
+                                             0xff | BIT(IWL_MGMT_TID), flags);
 
        if (internal)
                return iwl_mvm_flush_tx_path(mvm, int_sta->tfd_queue_msk,
index 56fc28750a41277364202c0fa109df905e084202..e323d3abb6ac28f4742e31d77ac45ded0ecec879 100644 (file)
@@ -579,25 +579,25 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
        {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_soc)},
        {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_soc)},
        {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x003C, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0060, iwl9460_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0064, iwl9461_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x00A0, iwl9462_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x00A4, iwl9462_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0230, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0234, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0238, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x023C, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0260, iwl9461_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x0264, iwl9461_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x02A0, iwl9462_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x02A4, iwl9462_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x4030, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x4034, iwl9560_2ac_cfg_soc)},
-       {IWL_PCI_DEVICE(0x31DC, 0x40A4, iwl9462_2ac_cfg_soc)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x003C, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0060, iwl9460_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0064, iwl9461_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x00A0, iwl9462_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x00A4, iwl9462_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0230, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0234, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0238, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x023C, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0260, iwl9461_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x0264, iwl9461_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x02A0, iwl9462_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x02A4, iwl9462_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x4030, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x4034, iwl9560_2ac_cfg_shared_clk)},
+       {IWL_PCI_DEVICE(0x31DC, 0x40A4, iwl9462_2ac_cfg_shared_clk)},
        {IWL_PCI_DEVICE(0x34F0, 0x0030, iwl9560_2ac_cfg_soc)},
        {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_soc)},
        {IWL_PCI_DEVICE(0x34F0, 0x02A4, iwl9462_2ac_cfg_soc)},
index dd9464920456fd550f8da9bab2e345ae843d1d15..ef22b275d0505b5bd9580182b2c67730f3181dc8 100644 (file)
@@ -474,6 +474,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
                shost->dma_boundary = 0xffffffff;
 
        shost->use_blk_mq = scsi_use_blk_mq;
+       shost->use_blk_mq = scsi_use_blk_mq || shost->hostt->force_blk_mq;
 
        device_initialize(&shost->shost_gendev);
        dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
index 5293e6827ce557043943415523ff1cbb0c49d977..3a9eca163db8117e7bbf1132c7965d5253850668 100644 (file)
@@ -1045,11 +1045,7 @@ static void set_performant_mode(struct ctlr_info *h, struct CommandList *c,
                c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
                if (unlikely(!h->msix_vectors))
                        return;
-               if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
-                       c->Header.ReplyQueue =
-                               raw_smp_processor_id() % h->nreply_queues;
-               else
-                       c->Header.ReplyQueue = reply_queue % h->nreply_queues;
+               c->Header.ReplyQueue = reply_queue;
        }
 }
 
@@ -1063,10 +1059,7 @@ static void set_ioaccel1_performant_mode(struct ctlr_info *h,
         * Tell the controller to post the reply to the queue for this
         * processor.  This seems to give the best I/O throughput.
         */
-       if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
-               cp->ReplyQueue = smp_processor_id() % h->nreply_queues;
-       else
-               cp->ReplyQueue = reply_queue % h->nreply_queues;
+       cp->ReplyQueue = reply_queue;
        /*
         * Set the bits in the address sent down to include:
         *  - performant mode bit (bit 0)
@@ -1087,10 +1080,7 @@ static void set_ioaccel2_tmf_performant_mode(struct ctlr_info *h,
        /* Tell the controller to post the reply to the queue for this
         * processor.  This seems to give the best I/O throughput.
         */
-       if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
-               cp->reply_queue = smp_processor_id() % h->nreply_queues;
-       else
-               cp->reply_queue = reply_queue % h->nreply_queues;
+       cp->reply_queue = reply_queue;
        /* Set the bits in the address sent down to include:
         *  - performant mode bit not used in ioaccel mode 2
         *  - pull count (bits 0-3)
@@ -1109,10 +1099,7 @@ static void set_ioaccel2_performant_mode(struct ctlr_info *h,
         * Tell the controller to post the reply to the queue for this
         * processor.  This seems to give the best I/O throughput.
         */
-       if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
-               cp->reply_queue = smp_processor_id() % h->nreply_queues;
-       else
-               cp->reply_queue = reply_queue % h->nreply_queues;
+       cp->reply_queue = reply_queue;
        /*
         * Set the bits in the address sent down to include:
         *  - performant mode bit not used in ioaccel mode 2
@@ -1157,6 +1144,8 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,
 {
        dial_down_lockup_detection_during_fw_flash(h, c);
        atomic_inc(&h->commands_outstanding);
+
+       reply_queue = h->reply_map[raw_smp_processor_id()];
        switch (c->cmd_type) {
        case CMD_IOACCEL1:
                set_ioaccel1_performant_mode(h, c, reply_queue);
@@ -7376,6 +7365,26 @@ static void hpsa_disable_interrupt_mode(struct ctlr_info *h)
        h->msix_vectors = 0;
 }
 
+static void hpsa_setup_reply_map(struct ctlr_info *h)
+{
+       const struct cpumask *mask;
+       unsigned int queue, cpu;
+
+       for (queue = 0; queue < h->msix_vectors; queue++) {
+               mask = pci_irq_get_affinity(h->pdev, queue);
+               if (!mask)
+                       goto fallback;
+
+               for_each_cpu(cpu, mask)
+                       h->reply_map[cpu] = queue;
+       }
+       return;
+
+fallback:
+       for_each_possible_cpu(cpu)
+               h->reply_map[cpu] = 0;
+}
+
 /* If MSI/MSI-X is supported by the kernel we will try to enable it on
  * controllers that are capable. If not, we use legacy INTx mode.
  */
@@ -7771,6 +7780,10 @@ static int hpsa_pci_init(struct ctlr_info *h)
        err = hpsa_interrupt_mode(h);
        if (err)
                goto clean1;
+
+       /* setup mapping between CPU and reply queue */
+       hpsa_setup_reply_map(h);
+
        err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr);
        if (err)
                goto clean2;    /* intmode+region, pci */
@@ -8480,6 +8493,28 @@ static struct workqueue_struct *hpsa_create_controller_wq(struct ctlr_info *h,
        return wq;
 }
 
+static void hpda_free_ctlr_info(struct ctlr_info *h)
+{
+       kfree(h->reply_map);
+       kfree(h);
+}
+
+static struct ctlr_info *hpda_alloc_ctlr_info(void)
+{
+       struct ctlr_info *h;
+
+       h = kzalloc(sizeof(*h), GFP_KERNEL);
+       if (!h)
+               return NULL;
+
+       h->reply_map = kzalloc(sizeof(*h->reply_map) * nr_cpu_ids, GFP_KERNEL);
+       if (!h->reply_map) {
+               kfree(h);
+               return NULL;
+       }
+       return h;
+}
+
 static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        int dac, rc;
@@ -8517,7 +8552,7 @@ reinit_after_soft_reset:
         * the driver.  See comments in hpsa.h for more info.
         */
        BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT);
-       h = kzalloc(sizeof(*h), GFP_KERNEL);
+       h = hpda_alloc_ctlr_info();
        if (!h) {
                dev_err(&pdev->dev, "Failed to allocate controller head\n");
                return -ENOMEM;
@@ -8916,7 +8951,7 @@ static void hpsa_remove_one(struct pci_dev *pdev)
        h->lockup_detected = NULL;                      /* init_one 2 */
        /* (void) pci_disable_pcie_error_reporting(pdev); */    /* init_one 1 */
 
-       kfree(h);                                       /* init_one 1 */
+       hpda_free_ctlr_info(h);                         /* init_one 1 */
 }
 
 static int hpsa_suspend(__attribute__((unused)) struct pci_dev *pdev,
index 018f980a701ce406e9edf0119240c39df47b9858..fb9f5e7f8209447771d07016bca7924774b143af 100644 (file)
@@ -158,6 +158,7 @@ struct bmic_controller_parameters {
 #pragma pack()
 
 struct ctlr_info {
+       unsigned int *reply_map;
        int     ctlr;
        char    devname[8];
        char    *product_name;
index b1b1d3a3b1734d64eccf1a856f272a1334141719..daefe8172b04a7f584c3c587b3a1fcc304839cf0 100644 (file)
@@ -3579,11 +3579,9 @@ static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt)
 static int ibmvfc_adisc_needs_plogi(struct ibmvfc_passthru_mad *mad,
                                    struct ibmvfc_target *tgt)
 {
-       if (memcmp(&mad->fc_iu.response[2], &tgt->ids.port_name,
-                  sizeof(tgt->ids.port_name)))
+       if (wwn_to_u64((u8 *)&mad->fc_iu.response[2]) != tgt->ids.port_name)
                return 1;
-       if (memcmp(&mad->fc_iu.response[4], &tgt->ids.node_name,
-                  sizeof(tgt->ids.node_name)))
+       if (wwn_to_u64((u8 *)&mad->fc_iu.response[4]) != tgt->ids.node_name)
                return 1;
        if (be32_to_cpu(mad->fc_iu.response[6]) != tgt->scsi_id)
                return 1;
index 6198559abbd8f8e9ae9293a03ea511726946f953..dd66c11399a233a5fed6927da4e39f378a928195 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/kfifo.h>
 #include <linux/scatterlist.h>
 #include <linux/module.h>
+#include <linux/backing-dev.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -954,6 +955,13 @@ static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev)
 
 static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
 {
+       struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host);
+       struct iscsi_session *session = tcp_sw_host->session;
+       struct iscsi_conn *conn = session->leadconn;
+
+       if (conn->datadgst_en)
+               sdev->request_queue->backing_dev_info->capabilities
+                       |= BDI_CAP_STABLE_WRITES;
        blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY);
        blk_queue_dma_alignment(sdev->request_queue, 0);
        return 0;
index ba6503f37756312d9d0d1d2da23ae0e79180f1a6..27fab8235ea5c27326abfe4356b8629fbc8ca622 100644 (file)
@@ -2128,6 +2128,7 @@ enum MR_PD_TYPE {
 
 struct megasas_instance {
 
+       unsigned int *reply_map;
        __le32 *producer;
        dma_addr_t producer_h;
        __le32 *consumer;
index a71ee67df0847721a98b2a2504a6a41f7e68bd44..dde0798b8a91ff1e72a4562de46c08021cbfe665 100644 (file)
@@ -5165,6 +5165,26 @@ skip_alloc:
                instance->use_seqnum_jbod_fp = false;
 }
 
+static void megasas_setup_reply_map(struct megasas_instance *instance)
+{
+       const struct cpumask *mask;
+       unsigned int queue, cpu;
+
+       for (queue = 0; queue < instance->msix_vectors; queue++) {
+               mask = pci_irq_get_affinity(instance->pdev, queue);
+               if (!mask)
+                       goto fallback;
+
+               for_each_cpu(cpu, mask)
+                       instance->reply_map[cpu] = queue;
+       }
+       return;
+
+fallback:
+       for_each_possible_cpu(cpu)
+               instance->reply_map[cpu] = cpu % instance->msix_vectors;
+}
+
 /**
  * megasas_init_fw -   Initializes the FW
  * @instance:          Adapter soft state
@@ -5343,6 +5363,8 @@ static int megasas_init_fw(struct megasas_instance *instance)
                        goto fail_setup_irqs;
        }
 
+       megasas_setup_reply_map(instance);
+
        dev_info(&instance->pdev->dev,
                "firmware supports msix\t: (%d)", fw_msix_count);
        dev_info(&instance->pdev->dev,
@@ -6123,20 +6145,29 @@ static inline int megasas_alloc_mfi_ctrl_mem(struct megasas_instance *instance)
  */
 static int megasas_alloc_ctrl_mem(struct megasas_instance *instance)
 {
+       instance->reply_map = kzalloc(sizeof(unsigned int) * nr_cpu_ids,
+                                     GFP_KERNEL);
+       if (!instance->reply_map)
+               return -ENOMEM;
+
        switch (instance->adapter_type) {
        case MFI_SERIES:
                if (megasas_alloc_mfi_ctrl_mem(instance))
-                       return -ENOMEM;
+                       goto fail;
                break;
        case VENTURA_SERIES:
        case THUNDERBOLT_SERIES:
        case INVADER_SERIES:
                if (megasas_alloc_fusion_context(instance))
-                       return -ENOMEM;
+                       goto fail;
                break;
        }
 
        return 0;
+ fail:
+       kfree(instance->reply_map);
+       instance->reply_map = NULL;
+       return -ENOMEM;
 }
 
 /*
@@ -6148,6 +6179,7 @@ static int megasas_alloc_ctrl_mem(struct megasas_instance *instance)
  */
 static inline void megasas_free_ctrl_mem(struct megasas_instance *instance)
 {
+       kfree(instance->reply_map);
        if (instance->adapter_type == MFI_SERIES) {
                if (instance->producer)
                        pci_free_consistent(instance->pdev, sizeof(u32),
@@ -6540,7 +6572,6 @@ fail_io_attach:
                pci_free_irq_vectors(instance->pdev);
 fail_init_mfi:
        scsi_host_put(host);
-
 fail_alloc_instance:
        pci_disable_device(pdev);
 
@@ -6746,6 +6777,8 @@ megasas_resume(struct pci_dev *pdev)
        if (rval < 0)
                goto fail_reenable_msix;
 
+       megasas_setup_reply_map(instance);
+
        if (instance->adapter_type != MFI_SERIES) {
                megasas_reset_reply_desc(instance);
                if (megasas_ioc_init_fusion(instance)) {
index dc8e850fbfd2217d1a64ea1ff9522bc2eeca3a40..5ec3b74e8aedc046a08ce9944b5fc93ddfa02750 100644 (file)
@@ -2641,11 +2641,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
                        fp_possible = (io_info.fpOkForIo > 0) ? true : false;
        }
 
-       /* Use raw_smp_processor_id() for now until cmd->request->cpu is CPU
-          id by default, not CPU group id, otherwise all MSI-X queues won't
-          be utilized */
-       cmd->request_desc->SCSIIO.MSIxIndex = instance->msix_vectors ?
-               raw_smp_processor_id() % instance->msix_vectors : 0;
+       cmd->request_desc->SCSIIO.MSIxIndex =
+               instance->reply_map[raw_smp_processor_id()];
 
        praid_context = &io_request->RaidContext;
 
@@ -2971,10 +2968,9 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
        }
 
        cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
-       cmd->request_desc->SCSIIO.MSIxIndex =
-               instance->msix_vectors ?
-               (raw_smp_processor_id() % instance->msix_vectors) : 0;
 
+       cmd->request_desc->SCSIIO.MSIxIndex =
+               instance->reply_map[raw_smp_processor_id()];
 
        if (!fp_possible) {
                /* system pd firmware path */
index 3541caf3fceb4441b220d50b4fac1dc8b98b751d..1fa84d6a0f8b80b4a06af3f0dedede02d7f10403 100644 (file)
@@ -2484,6 +2484,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
                                sector_size = old_sector_size;
                                goto got_data;
                        }
+                       /* Remember that READ CAPACITY(16) succeeded */
+                       sdp->try_rc_10_first = 0;
                }
        }
 
index 7c28e8d4955a965805cdde3d2ddb07a7f8c5d6ea..45d04631888a4f67d0884971226074c6628a063d 100644 (file)
@@ -91,9 +91,6 @@ struct virtio_scsi_vq {
 struct virtio_scsi_target_state {
        seqcount_t tgt_seq;
 
-       /* Count of outstanding requests. */
-       atomic_t reqs;
-
        /* Currently active virtqueue for requests sent to this target. */
        struct virtio_scsi_vq *req_vq;
 };
@@ -152,8 +149,6 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf)
        struct virtio_scsi_cmd *cmd = buf;
        struct scsi_cmnd *sc = cmd->sc;
        struct virtio_scsi_cmd_resp *resp = &cmd->resp.cmd;
-       struct virtio_scsi_target_state *tgt =
-                               scsi_target(sc->device)->hostdata;
 
        dev_dbg(&sc->device->sdev_gendev,
                "cmd %p response %u status %#02x sense_len %u\n",
@@ -210,8 +205,6 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf)
        }
 
        sc->scsi_done(sc);
-
-       atomic_dec(&tgt->reqs);
 }
 
 static void virtscsi_vq_done(struct virtio_scsi *vscsi,
@@ -529,11 +522,20 @@ static void virtio_scsi_init_hdr_pi(struct virtio_device *vdev,
 }
 #endif
 
-static int virtscsi_queuecommand(struct virtio_scsi *vscsi,
-                                struct virtio_scsi_vq *req_vq,
+static struct virtio_scsi_vq *virtscsi_pick_vq_mq(struct virtio_scsi *vscsi,
+                                                 struct scsi_cmnd *sc)
+{
+       u32 tag = blk_mq_unique_tag(sc->request);
+       u16 hwq = blk_mq_unique_tag_to_hwq(tag);
+
+       return &vscsi->req_vqs[hwq];
+}
+
+static int virtscsi_queuecommand(struct Scsi_Host *shost,
                                 struct scsi_cmnd *sc)
 {
-       struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev);
+       struct virtio_scsi *vscsi = shost_priv(shost);
+       struct virtio_scsi_vq *req_vq = virtscsi_pick_vq_mq(vscsi, sc);
        struct virtio_scsi_cmd *cmd = scsi_cmd_priv(sc);
        unsigned long flags;
        int req_size;
@@ -576,79 +578,6 @@ static int virtscsi_queuecommand(struct virtio_scsi *vscsi,
        return 0;
 }
 
-static int virtscsi_queuecommand_single(struct Scsi_Host *sh,
-                                       struct scsi_cmnd *sc)
-{
-       struct virtio_scsi *vscsi = shost_priv(sh);
-       struct virtio_scsi_target_state *tgt =
-                               scsi_target(sc->device)->hostdata;
-
-       atomic_inc(&tgt->reqs);
-       return virtscsi_queuecommand(vscsi, &vscsi->req_vqs[0], sc);
-}
-
-static struct virtio_scsi_vq *virtscsi_pick_vq_mq(struct virtio_scsi *vscsi,
-                                                 struct scsi_cmnd *sc)
-{
-       u32 tag = blk_mq_unique_tag(sc->request);
-       u16 hwq = blk_mq_unique_tag_to_hwq(tag);
-
-       return &vscsi->req_vqs[hwq];
-}
-
-static struct virtio_scsi_vq *virtscsi_pick_vq(struct virtio_scsi *vscsi,
-                                              struct virtio_scsi_target_state *tgt)
-{
-       struct virtio_scsi_vq *vq;
-       unsigned long flags;
-       u32 queue_num;
-
-       local_irq_save(flags);
-       if (atomic_inc_return(&tgt->reqs) > 1) {
-               unsigned long seq;
-
-               do {
-                       seq = read_seqcount_begin(&tgt->tgt_seq);
-                       vq = tgt->req_vq;
-               } while (read_seqcount_retry(&tgt->tgt_seq, seq));
-       } else {
-               /* no writes can be concurrent because of atomic_t */
-               write_seqcount_begin(&tgt->tgt_seq);
-
-               /* keep previous req_vq if a reader just arrived */
-               if (unlikely(atomic_read(&tgt->reqs) > 1)) {
-                       vq = tgt->req_vq;
-                       goto unlock;
-               }
-
-               queue_num = smp_processor_id();
-               while (unlikely(queue_num >= vscsi->num_queues))
-                       queue_num -= vscsi->num_queues;
-               tgt->req_vq = vq = &vscsi->req_vqs[queue_num];
- unlock:
-               write_seqcount_end(&tgt->tgt_seq);
-       }
-       local_irq_restore(flags);
-
-       return vq;
-}
-
-static int virtscsi_queuecommand_multi(struct Scsi_Host *sh,
-                                      struct scsi_cmnd *sc)
-{
-       struct virtio_scsi *vscsi = shost_priv(sh);
-       struct virtio_scsi_target_state *tgt =
-                               scsi_target(sc->device)->hostdata;
-       struct virtio_scsi_vq *req_vq;
-
-       if (shost_use_blk_mq(sh))
-               req_vq = virtscsi_pick_vq_mq(vscsi, sc);
-       else
-               req_vq = virtscsi_pick_vq(vscsi, tgt);
-
-       return virtscsi_queuecommand(vscsi, req_vq, sc);
-}
-
 static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
 {
        DECLARE_COMPLETION_ONSTACK(comp);
@@ -775,7 +704,6 @@ static int virtscsi_target_alloc(struct scsi_target *starget)
                return -ENOMEM;
 
        seqcount_init(&tgt->tgt_seq);
-       atomic_set(&tgt->reqs, 0);
        tgt->req_vq = &vscsi->req_vqs[0];
 
        starget->hostdata = tgt;
@@ -805,33 +733,13 @@ static enum blk_eh_timer_return virtscsi_eh_timed_out(struct scsi_cmnd *scmnd)
        return BLK_EH_RESET_TIMER;
 }
 
-static struct scsi_host_template virtscsi_host_template_single = {
-       .module = THIS_MODULE,
-       .name = "Virtio SCSI HBA",
-       .proc_name = "virtio_scsi",
-       .this_id = -1,
-       .cmd_size = sizeof(struct virtio_scsi_cmd),
-       .queuecommand = virtscsi_queuecommand_single,
-       .change_queue_depth = virtscsi_change_queue_depth,
-       .eh_abort_handler = virtscsi_abort,
-       .eh_device_reset_handler = virtscsi_device_reset,
-       .eh_timed_out = virtscsi_eh_timed_out,
-       .slave_alloc = virtscsi_device_alloc,
-
-       .dma_boundary = UINT_MAX,
-       .use_clustering = ENABLE_CLUSTERING,
-       .target_alloc = virtscsi_target_alloc,
-       .target_destroy = virtscsi_target_destroy,
-       .track_queue_depth = 1,
-};
-
-static struct scsi_host_template virtscsi_host_template_multi = {
+static struct scsi_host_template virtscsi_host_template = {
        .module = THIS_MODULE,
        .name = "Virtio SCSI HBA",
        .proc_name = "virtio_scsi",
        .this_id = -1,
        .cmd_size = sizeof(struct virtio_scsi_cmd),
-       .queuecommand = virtscsi_queuecommand_multi,
+       .queuecommand = virtscsi_queuecommand,
        .change_queue_depth = virtscsi_change_queue_depth,
        .eh_abort_handler = virtscsi_abort,
        .eh_device_reset_handler = virtscsi_device_reset,
@@ -844,6 +752,7 @@ static struct scsi_host_template virtscsi_host_template_multi = {
        .target_destroy = virtscsi_target_destroy,
        .map_queues = virtscsi_map_queues,
        .track_queue_depth = 1,
+       .force_blk_mq = 1,
 };
 
 #define virtscsi_config_get(vdev, fld) \
@@ -936,7 +845,6 @@ static int virtscsi_probe(struct virtio_device *vdev)
        u32 sg_elems, num_targets;
        u32 cmd_per_lun;
        u32 num_queues;
-       struct scsi_host_template *hostt;
 
        if (!vdev->config->get) {
                dev_err(&vdev->dev, "%s failure: config access disabled\n",
@@ -949,12 +857,7 @@ static int virtscsi_probe(struct virtio_device *vdev)
 
        num_targets = virtscsi_config_get(vdev, max_target) + 1;
 
-       if (num_queues == 1)
-               hostt = &virtscsi_host_template_single;
-       else
-               hostt = &virtscsi_host_template_multi;
-
-       shost = scsi_host_alloc(hostt,
+       shost = scsi_host_alloc(&virtscsi_host_template,
                sizeof(*vscsi) + sizeof(vscsi->req_vqs[0]) * num_queues);
        if (!shost)
                return -ENOMEM;
index 8139bc70ad7dcf09b2d2311fc1eab9d450ab4814..12bcfbac2cc9de526e1bfdcaf558c9b3396976a3 100644 (file)
@@ -630,7 +630,7 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk)
 
        if (!len && vq->busyloop_timeout) {
                /* Both tx vq and rx socket were polled here */
-               mutex_lock(&vq->mutex);
+               mutex_lock_nested(&vq->mutex, 1);
                vhost_disable_notify(&net->dev, vq);
 
                preempt_disable();
@@ -763,7 +763,7 @@ static void handle_rx(struct vhost_net *net)
        struct iov_iter fixup;
        __virtio16 num_buffers;
 
-       mutex_lock(&vq->mutex);
+       mutex_lock_nested(&vq->mutex, 0);
        sock = vq->private_data;
        if (!sock)
                goto out;
index 1b3e8d2d5c8b44442616c1ee6fa9f7bf455b456d..5320039671b774fe8c07bb2218012ff55a03f617 100644 (file)
@@ -212,8 +212,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file)
        if (mask)
                vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask));
        if (mask & EPOLLERR) {
-               if (poll->wqh)
-                       remove_wait_queue(poll->wqh, &poll->wait);
+               vhost_poll_stop(poll);
                ret = -EINVAL;
        }
 
@@ -1245,14 +1244,12 @@ static int vq_log_access_ok(struct vhost_virtqueue *vq,
 /* Caller should have vq mutex and device mutex */
 int vhost_vq_access_ok(struct vhost_virtqueue *vq)
 {
-       if (vq->iotlb) {
-               /* When device IOTLB was used, the access validation
-                * will be validated during prefetching.
-                */
-               return 1;
-       }
-       return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used) &&
-               vq_log_access_ok(vq, vq->log_base);
+       int ret = vq_log_access_ok(vq, vq->log_base);
+
+       if (ret || vq->iotlb)
+               return ret;
+
+       return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used);
 }
 EXPORT_SYMBOL_GPL(vhost_vq_access_ok);
 
index 6639926eed4e8461d0c50b6a686df236e1c96338..b67eec3532a125c0c8ca0c97b7b0f22c650f7966 100644 (file)
@@ -640,7 +640,8 @@ static ssize_t ceph_sync_read(struct kiocb *iocb, struct iov_iter *to,
 struct ceph_aio_request {
        struct kiocb *iocb;
        size_t total_len;
-       int write;
+       bool write;
+       bool should_dirty;
        int error;
        struct list_head osd_reqs;
        unsigned num_reqs;
@@ -750,7 +751,7 @@ static void ceph_aio_complete_req(struct ceph_osd_request *req)
                }
        }
 
-       ceph_put_page_vector(osd_data->pages, num_pages, !aio_req->write);
+       ceph_put_page_vector(osd_data->pages, num_pages, aio_req->should_dirty);
        ceph_osdc_put_request(req);
 
        if (rc < 0)
@@ -847,6 +848,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
        size_t count = iov_iter_count(iter);
        loff_t pos = iocb->ki_pos;
        bool write = iov_iter_rw(iter) == WRITE;
+       bool should_dirty = !write && iter_is_iovec(iter);
 
        if (write && ceph_snap(file_inode(file)) != CEPH_NOSNAP)
                return -EROFS;
@@ -914,6 +916,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
                        if (aio_req) {
                                aio_req->iocb = iocb;
                                aio_req->write = write;
+                               aio_req->should_dirty = should_dirty;
                                INIT_LIST_HEAD(&aio_req->osd_reqs);
                                if (write) {
                                        aio_req->mtime = mtime;
@@ -971,7 +974,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
                                len = ret;
                }
 
-               ceph_put_page_vector(pages, num_pages, !write);
+               ceph_put_page_vector(pages, num_pages, should_dirty);
 
                ceph_osdc_put_request(req);
                if (ret < 0)
index c4a1cff9c76861b3eef7b1eea97d8591532bf798..7d30892da0641df03f1c1ec5118a69014c3b9332 100644 (file)
@@ -323,13 +323,24 @@ static inline int __vlan_insert_inner_tag(struct sk_buff *skb,
        skb_push(skb, VLAN_HLEN);
 
        /* Move the mac header sans proto to the beginning of the new header. */
-       memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
+       if (likely(mac_len > ETH_TLEN))
+               memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
        skb->mac_header -= VLAN_HLEN;
 
        veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN);
 
        /* first, the ethernet type */
-       veth->h_vlan_proto = vlan_proto;
+       if (likely(mac_len >= ETH_TLEN)) {
+               /* h_vlan_encapsulated_proto should already be populated, and
+                * skb->data has space for h_vlan_proto
+                */
+               veth->h_vlan_proto = vlan_proto;
+       } else {
+               /* h_vlan_encapsulated_proto should not be populated, and
+                * skb->data has no space for h_vlan_proto
+                */
+               veth->h_vlan_encapsulated_proto = skb->protocol;
+       }
 
        /* now, the TCI */
        veth->h_vlan_TCI = htons(vlan_tci);
index bebeaad897cc406d550175603a19a1c15e582942..29ed8fd6379a79f43d887be4fd9a7bfc9a46c897 100644 (file)
@@ -231,7 +231,7 @@ static inline void net_dim_exit_parking(struct net_dim *dim)
 }
 
 #define IS_SIGNIFICANT_DIFF(val, ref) \
-       (((100 * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */
+       (((100UL * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */
 
 static inline int net_dim_stats_compare(struct net_dim_stats *curr,
                                        struct net_dim_stats *prev)
index fe994d2e52869d06be7d26b48b942e666e60f2da..5c40f118c0fad6448796579b01acba5f77e1e4fa 100644 (file)
@@ -103,7 +103,7 @@ void llc_sk_reset(struct sock *sk);
 
 /* Access to a connection */
 int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
-void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
+int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
 void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
 void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit);
 void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit);
index 663b015dace553cc9be00035fa4a285f1f144a0d..30eb0652b025ca7d30bee1dd8ba9a2a138fcf672 100644 (file)
@@ -1068,6 +1068,8 @@ struct nft_object_ops {
 int nft_register_obj(struct nft_object_type *obj_type);
 void nft_unregister_obj(struct nft_object_type *obj_type);
 
+#define NFT_FLOWTABLE_DEVICE_MAX       8
+
 /**
  *     struct nft_flowtable - nf_tables flow table
  *
@@ -1080,6 +1082,7 @@ void nft_unregister_obj(struct nft_object_type *obj_type);
  *     @genmask: generation mask
  *     @use: number of references to this flow table
  *     @handle: unique object handle
+ *     @dev_name: array of device names
  *     @data: rhashtable and garbage collector
  *     @ops: array of hooks
  */
@@ -1093,6 +1096,7 @@ struct nft_flowtable {
        u32                             genmask:2,
                                        use:30;
        u64                             handle;
+       char                            *dev_name[NFT_FLOWTABLE_DEVICE_MAX];
        /* runtime data below here */
        struct nf_hook_ops              *ops ____cacheline_aligned;
        struct nf_flowtable             data;
index 2092d33194dd1f237cba04849d17b37d61a922e7..8da32678ce18e1003ea051870b2149a41c9daa44 100644 (file)
@@ -30,6 +30,7 @@ struct qdisc_rate_table {
 enum qdisc_state_t {
        __QDISC_STATE_SCHED,
        __QDISC_STATE_DEACTIVATED,
+       __QDISC_STATE_RUNNING,
 };
 
 struct qdisc_size_table {
index d656809f1217ae039abb54df1748ae3aead1dafa..415e0996001760312d82c475d97ebf8cfb426531 100644 (file)
@@ -130,6 +130,8 @@ void rdma_copy_addr(struct rdma_dev_addr *dev_addr,
                    const unsigned char *dst_dev_addr);
 
 int rdma_addr_size(struct sockaddr *addr);
+int rdma_addr_size_in6(struct sockaddr_in6 *addr);
+int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr);
 
 int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
                                 const union ib_gid *dgid,
index a8b7bf879cede4240d921a42f915a230163e5e4e..9c1e4bad6581d39bb4bcafc9205b38ed43e541cf 100644 (file)
@@ -452,6 +452,9 @@ struct scsi_host_template {
        /* True if the controller does not support WRITE SAME */
        unsigned no_write_same:1;
 
+       /* True if the low-level driver supports blk-mq only */
+       unsigned force_blk_mq:1;
+
        /*
         * Countdown for host blocking with no commands outstanding.
         */
index 4643865e917118208c2fcaab66aeb05b02c5e460..93e0e3a4d009d69c4ccbbdce14fda4c33e73e950 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -386,6 +386,17 @@ static int shm_fault(struct vm_fault *vmf)
        return sfd->vm_ops->fault(vmf);
 }
 
+static int shm_split(struct vm_area_struct *vma, unsigned long addr)
+{
+       struct file *file = vma->vm_file;
+       struct shm_file_data *sfd = shm_file_data(file);
+
+       if (sfd->vm_ops && sfd->vm_ops->split)
+               return sfd->vm_ops->split(vma, addr);
+
+       return 0;
+}
+
 #ifdef CONFIG_NUMA
 static int shm_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
 {
@@ -510,6 +521,7 @@ static const struct vm_operations_struct shm_vm_ops = {
        .open   = shm_open,     /* callback for a new vm-area open */
        .close  = shm_close,    /* callback for when the vm-area is released */
        .fault  = shm_fault,
+       .split  = shm_split,
 #if defined(CONFIG_NUMA)
        .set_policy = shm_set_policy,
        .get_policy = shm_get_policy,
index 3f8cb1e14588fe3258a1c3aa49874e008f5a266a..253ae2da13c38750166299ba265d0b4a6edabf4b 100644 (file)
@@ -427,16 +427,9 @@ EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
  * modify_user_hw_breakpoint - modify a user-space hardware breakpoint
  * @bp: the breakpoint structure to modify
  * @attr: new breakpoint attributes
- * @triggered: callback to trigger when we hit the breakpoint
- * @tsk: pointer to 'task_struct' of the process to which the address belongs
  */
 int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr)
 {
-       u64 old_addr = bp->attr.bp_addr;
-       u64 old_len = bp->attr.bp_len;
-       int old_type = bp->attr.bp_type;
-       int err = 0;
-
        /*
         * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it
         * will not be possible to raise IPIs that invoke __perf_event_disable.
@@ -451,27 +444,18 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
        bp->attr.bp_addr = attr->bp_addr;
        bp->attr.bp_type = attr->bp_type;
        bp->attr.bp_len = attr->bp_len;
+       bp->attr.disabled = 1;
 
-       if (attr->disabled)
-               goto end;
-
-       err = validate_hw_breakpoint(bp);
-       if (!err)
-               perf_event_enable(bp);
+       if (!attr->disabled) {
+               int err = validate_hw_breakpoint(bp);
 
-       if (err) {
-               bp->attr.bp_addr = old_addr;
-               bp->attr.bp_type = old_type;
-               bp->attr.bp_len = old_len;
-               if (!bp->attr.disabled)
-                       perf_event_enable(bp);
+               if (err)
+                       return err;
 
-               return err;
+               perf_event_enable(bp);
+               bp->attr.disabled = 0;
        }
 
-end:
-       bp->attr.disabled = attr->disabled;
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);
index e83987c55a08ade7429476f9f8c7554c9d80759f..46c2290a08f1803a2e41d01533b627e5045e6421 100644 (file)
@@ -1657,8 +1657,7 @@ static void start_scan_thread(void)
 }
 
 /*
- * Stop the automatic memory scanning thread. This function must be called
- * with the scan_mutex held.
+ * Stop the automatic memory scanning thread.
  */
 static void stop_scan_thread(void)
 {
@@ -1921,12 +1920,15 @@ static void kmemleak_do_cleanup(struct work_struct *work)
 {
        stop_scan_thread();
 
+       mutex_lock(&scan_mutex);
        /*
-        * Once the scan thread has stopped, it is safe to no longer track
-        * object freeing. Ordering of the scan thread stopping and the memory
-        * accesses below is guaranteed by the kthread_stop() function.
+        * Once it is made sure that kmemleak_scan has stopped, it is safe to no
+        * longer track object freeing. Ordering of the scan thread stopping and
+        * the memory accesses below is guaranteed by the kthread_stop()
+        * function.
         */
        kmemleak_free_enabled = 0;
+       mutex_unlock(&scan_mutex);
 
        if (!kmemleak_found_leaks)
                __kmemleak_do_cleanup();
index 670e99b68aa60567ecb4195bdace787e2378620c..9ec024b862aca01cb32d302584e6b110d11107a7 100644 (file)
@@ -714,9 +714,9 @@ static struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm)
  * invocations for reference counting, or use mem_cgroup_iter_break()
  * to cancel a hierarchy walk before the round-trip is complete.
  *
- * Reclaimers can specify a zone and a priority level in @reclaim to
+ * Reclaimers can specify a node and a priority level in @reclaim to
  * divide up the memcgs in the hierarchy among all concurrent
- * reclaimers operating on the same zone and priority.
+ * reclaimers operating on the same node and priority.
  */
 struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
                                   struct mem_cgroup *prev,
@@ -2299,7 +2299,7 @@ void memcg_kmem_put_cache(struct kmem_cache *cachep)
 }
 
 /**
- * memcg_kmem_charge: charge a kmem page
+ * memcg_kmem_charge_memcg: charge a kmem page
  * @page: page to charge
  * @gfp: reclaim mode
  * @order: allocation order
index 9886c6073828c7dd6f4975da84be07cd68ea6ca5..7172e0a80e13e8e1cc6d0e55939b70ba71ac9129 100644 (file)
@@ -123,13 +123,13 @@ void __reset_page_owner(struct page *page, unsigned int order)
 static inline bool check_recursive_alloc(struct stack_trace *trace,
                                        unsigned long ip)
 {
-       int i, count;
+       int i;
 
        if (!trace->nr_entries)
                return false;
 
-       for (i = 0, count = 0; i < trace->nr_entries; i++) {
-               if (trace->entries[i] == ip && ++count == 2)
+       for (i = 0; i < trace->nr_entries; i++) {
+               if (trace->entries[i] == ip)
                        return true;
        }
 
index 324446621b3ee0d5179e23076699372781440555..9095c39454251096cd4462263140a92264a12c23 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1283,6 +1283,7 @@ void __init kmem_cache_init(void)
                                  nr_node_ids * sizeof(struct kmem_cache_node *),
                                  SLAB_HWCACHE_ALIGN, 0, 0);
        list_add(&kmem_cache->list, &slab_caches);
+       memcg_link_cache(kmem_cache);
        slab_state = PARTIAL;
 
        /*
index 40b2db6db6b16df89ff5c313cab83c95b8c0f38e..33581be705f03ee97527ad61921c3339a05524d0 100644 (file)
@@ -1839,9 +1839,11 @@ static void vmstat_update(struct work_struct *w)
                 * to occur in the future. Keep on running the
                 * update worker thread.
                 */
+               preempt_disable();
                queue_delayed_work_on(smp_processor_id(), mm_percpu_wq,
                                this_cpu_ptr(&vmstat_work),
                                round_jiffies_relative(sysctl_stat_interval));
+               preempt_enable();
        }
 }
 
index 37fe9a644f22f29d2fdd360f1f6bd63a22cd2680..808d2dd4a8394556744b694f3684745d876e1001 100644 (file)
@@ -746,7 +746,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
 {
        struct batadv_neigh_node *neigh_curr = NULL;
        struct batadv_neigh_node *neigh_old = NULL;
-       struct batadv_orig_node *orig_dst_node;
+       struct batadv_orig_node *orig_dst_node = NULL;
        struct batadv_gw_node *gw_node = NULL;
        struct batadv_gw_node *curr_gw = NULL;
        struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo;
@@ -757,6 +757,9 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
 
        vid = batadv_get_vid(skb, 0);
 
+       if (is_multicast_ether_addr(ethhdr->h_dest))
+               goto out;
+
        orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
                                                 ethhdr->h_dest, vid);
        if (!orig_dst_node)
index d70640135e3ab2a925c8eab23ef918f6e81c016a..ee56af5c43e00801eb5a55fc7f91f0f5057b84e3 100644 (file)
@@ -814,8 +814,8 @@ static struct batadv_orig_node *
 batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv,
                              struct ethhdr *ethhdr)
 {
-       return batadv_transtable_search(bat_priv, ethhdr->h_source,
-                                       ethhdr->h_dest, BATADV_NO_FLAGS);
+       return batadv_transtable_search(bat_priv, NULL, ethhdr->h_dest,
+                                       BATADV_NO_FLAGS);
 }
 
 /**
index 12be205357146f0dcd55cc6e6f71dfb65fdeb33b..ef0cc6ea5f8da5b87c751d9eebfc0943fbe36a06 100644 (file)
@@ -2735,7 +2735,7 @@ __be16 skb_network_protocol(struct sk_buff *skb, int *depth)
                if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr))))
                        return 0;
 
-               eth = (struct ethhdr *)skb_mac_header(skb);
+               eth = (struct ethhdr *)skb->data;
                type = eth->h_proto;
        }
 
index 1e7acdc30732ef1f201309df528d26e8494d2770..857e4e6f751afad9f1570af158d5a190e4adeca4 100644 (file)
@@ -5028,8 +5028,10 @@ static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
        }
 
        mac_len = skb->data - skb_mac_header(skb);
-       memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
-               mac_len - VLAN_HLEN - ETH_TLEN);
+       if (likely(mac_len > VLAN_HLEN + ETH_TLEN)) {
+               memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
+                       mac_len - VLAN_HLEN - ETH_TLEN);
+       }
        skb->mac_header += VLAN_HLEN;
        return skb;
 }
index 6d21068f9b5531e34c0f8be180e2b835fdaae0d7..a7fd1c5a2a14935ef0b40f781b248f90de294cf0 100644 (file)
@@ -362,13 +362,18 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
        struct ip_tunnel *nt;
        struct net_device *dev;
        int t_hlen;
+       int mtu;
+       int err;
 
        BUG_ON(!itn->fb_tunnel_dev);
        dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms);
        if (IS_ERR(dev))
                return ERR_CAST(dev);
 
-       dev->mtu = ip_tunnel_bind_dev(dev);
+       mtu = ip_tunnel_bind_dev(dev);
+       err = dev_set_mtu(dev, mtu);
+       if (err)
+               goto err_dev_set_mtu;
 
        nt = netdev_priv(dev);
        t_hlen = nt->hlen + sizeof(struct iphdr);
@@ -376,6 +381,10 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
        dev->max_mtu = 0xFFF8 - dev->hard_header_len - t_hlen;
        ip_tunnel_add(itn, nt);
        return nt;
+
+err_dev_set_mtu:
+       unregister_netdevice(dev);
+       return ERR_PTR(err);
 }
 
 int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
@@ -1102,17 +1111,29 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
        nt->fwmark = fwmark;
        err = register_netdevice(dev);
        if (err)
-               goto out;
+               goto err_register_netdevice;
 
        if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
                eth_hw_addr_random(dev);
 
        mtu = ip_tunnel_bind_dev(dev);
-       if (!tb[IFLA_MTU])
-               dev->mtu = mtu;
+       if (tb[IFLA_MTU]) {
+               unsigned int max = 0xfff8 - dev->hard_header_len - nt->hlen;
+
+               mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU,
+                           (unsigned int)(max - sizeof(struct iphdr)));
+       }
+
+       err = dev_set_mtu(dev, mtu);
+       if (err)
+               goto err_dev_set_mtu;
 
        ip_tunnel_add(itn, nt);
-out:
+       return 0;
+
+err_dev_set_mtu:
+       unregister_netdevice(dev);
+err_register_netdevice:
        return err;
 }
 EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
index 51b1669334fe6baeea0045fcfdd631700c1ccbf2..3f091ccad9affb893aceab1c030c0846c196b130 100644 (file)
@@ -387,8 +387,6 @@ static int vti_tunnel_init(struct net_device *dev)
        memcpy(dev->dev_addr, &iph->saddr, 4);
        memcpy(dev->broadcast, &iph->daddr, 4);
 
-       dev->hard_header_len    = LL_MAX_HEADER + sizeof(struct iphdr);
-       dev->mtu                = ETH_DATA_LEN;
        dev->flags              = IFF_NOARP;
        dev->addr_len           = 4;
        dev->features           |= NETIF_F_LLTX;
index 2dad20eefd26aa8e05805bbbc474bd4e6ba4887f..9bd19cd188492ab09b9132d7010ea7fe79c498ab 100644 (file)
@@ -29,7 +29,7 @@ obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
 obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
 
 nf_nat_snmp_basic-y := nf_nat_snmp_basic-asn1.o nf_nat_snmp_basic_main.o
-nf_nat_snmp_basic-y : nf_nat_snmp_basic-asn1.h nf_nat_snmp_basic-asn1.c
+$(obj)/nf_nat_snmp_basic_main.o: $(obj)/nf_nat_snmp_basic-asn1.h
 obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
 clean-files := nf_nat_snmp_basic-asn1.c nf_nat_snmp_basic-asn1.h
 
index b50721d9d30ef6f98c419c5a745a6df5f1f6a62d..9db988f9a4d786b704893cd53e774635be757ed7 100644 (file)
@@ -154,8 +154,20 @@ static unsigned int ipv4_conntrack_local(void *priv,
                                         struct sk_buff *skb,
                                         const struct nf_hook_state *state)
 {
-       if (ip_is_fragment(ip_hdr(skb))) /* IP_NODEFRAG setsockopt set */
+       if (ip_is_fragment(ip_hdr(skb))) { /* IP_NODEFRAG setsockopt set */
+               enum ip_conntrack_info ctinfo;
+               struct nf_conn *tmpl;
+
+               tmpl = nf_ct_get(skb, &ctinfo);
+               if (tmpl && nf_ct_is_template(tmpl)) {
+                       /* when skipping ct, clear templates to avoid fooling
+                        * later targets/matches
+                        */
+                       skb->_nfct = 0;
+                       nf_ct_put(tmpl);
+               }
                return NF_ACCEPT;
+       }
 
        return nf_conntrack_in(state->net, PF_INET, state->hook, skb);
 }
index e9293bdebba04f5b329cd4fd4a6b5b676ade5988..4824b1e183a1dc61f5438bb1b56d6a465ca8bf00 100644 (file)
@@ -108,10 +108,12 @@ struct sock *nf_sk_lookup_slow_v4(struct net *net, const struct sk_buff *skb,
        int doff = 0;
 
        if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_TCP) {
-               struct udphdr _hdr, *hp;
+               struct tcphdr _hdr;
+               struct udphdr *hp;
 
                hp = skb_header_pointer(skb, ip_hdrlen(skb),
-                                       sizeof(_hdr), &_hdr);
+                                       iph->protocol == IPPROTO_UDP ?
+                                       sizeof(*hp) : sizeof(_hdr), &_hdr);
                if (hp == NULL)
                        return NULL;
 
index fda37f2862c923eb8b6d0b49d9442950fc6a7446..c3387dfd725bf99bcddefb9fb4f1dc98f5dd7f23 100644 (file)
@@ -349,6 +349,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
        req->ts_recent          = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0;
        treq->snt_synack        = 0;
        treq->tfo_listener      = false;
+       if (IS_ENABLED(CONFIG_SMC))
+               ireq->smc_ok = 0;
 
        ireq->ir_iif = inet_request_bound_dev_if(sk, skb);
 
index 9a1b3c1c1c1473829e6d975f97a864b9acd4a6d6..ff6cd98ce8d5b4f67d15a88040a662494f0de3b9 100644 (file)
@@ -6256,6 +6256,9 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
        if (want_cookie && !tmp_opt.saw_tstamp)
                tcp_clear_options(&tmp_opt);
 
+       if (IS_ENABLED(CONFIG_SMC) && want_cookie)
+               tmp_opt.smc_ok = 0;
+
        tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
        tcp_openreq_init(req, &tmp_opt, skb, sk);
        inet_rsk(req)->no_srccheck = inet_sk(sk)->transparent;
index a8a919520090920bd87e1c126c83cfae84405532..5cb18c8ba9b24e2d47fed14645600ce0821a9028 100644 (file)
@@ -1246,7 +1246,7 @@ static int __ip6_append_data(struct sock *sk,
                             const struct sockcm_cookie *sockc)
 {
        struct sk_buff *skb, *skb_prev = NULL;
-       unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu;
+       unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
        int exthdrlen = 0;
        int dst_exthdrlen = 0;
        int hh_len;
@@ -1282,6 +1282,12 @@ static int __ip6_append_data(struct sock *sk,
                      sizeof(struct frag_hdr) : 0) +
                     rt->rt6i_nfheader_len;
 
+       /* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
+        * the first fragment
+        */
+       if (headersize + transhdrlen > mtu)
+               goto emsgsize;
+
        if (cork->length + length > mtu - headersize && ipc6->dontfrag &&
            (sk->sk_protocol == IPPROTO_UDP ||
             sk->sk_protocol == IPPROTO_RAW)) {
@@ -1297,9 +1303,8 @@ static int __ip6_append_data(struct sock *sk,
 
        if (cork->length + length > maxnonfragsize - headersize) {
 emsgsize:
-               ipv6_local_error(sk, EMSGSIZE, fl6,
-                                mtu - headersize +
-                                sizeof(struct ipv6hdr));
+               pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0);
+               ipv6_local_error(sk, EMSGSIZE, fl6, pmtu);
                return -EMSGSIZE;
        }
 
index fa3ae1cb50d32628f6344500a2bb43b58832ece8..ce18cd20389dca77418301250fb02056bde54822 100644 (file)
@@ -622,11 +622,12 @@ static int vti6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        return 0;
 }
 
-static void vti6_link_config(struct ip6_tnl *t)
+static void vti6_link_config(struct ip6_tnl *t, bool keep_mtu)
 {
        struct net_device *dev = t->dev;
        struct __ip6_tnl_parm *p = &t->parms;
        struct net_device *tdev = NULL;
+       int mtu;
 
        memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
        memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
@@ -640,6 +641,11 @@ static void vti6_link_config(struct ip6_tnl *t)
        else
                dev->flags &= ~IFF_POINTOPOINT;
 
+       if (keep_mtu && dev->mtu) {
+               dev->mtu = clamp(dev->mtu, dev->min_mtu, dev->max_mtu);
+               return;
+       }
+
        if (p->flags & IP6_TNL_F_CAP_XMIT) {
                int strict = (ipv6_addr_type(&p->raddr) &
                              (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
@@ -656,20 +662,25 @@ static void vti6_link_config(struct ip6_tnl *t)
                tdev = __dev_get_by_index(t->net, p->link);
 
        if (tdev)
-               dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len,
-                                IPV6_MIN_MTU);
+               mtu = tdev->mtu - sizeof(struct ipv6hdr);
+       else
+               mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr);
+
+       dev->mtu = max_t(int, mtu, IPV6_MIN_MTU);
 }
 
 /**
  * vti6_tnl_change - update the tunnel parameters
  *   @t: tunnel to be changed
  *   @p: tunnel configuration parameters
+ *   @keep_mtu: MTU was set from userspace, don't re-compute it
  *
  * Description:
  *   vti6_tnl_change() updates the tunnel parameters
  **/
 static int
-vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
+vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p,
+               bool keep_mtu)
 {
        t->parms.laddr = p->laddr;
        t->parms.raddr = p->raddr;
@@ -679,11 +690,12 @@ vti6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
        t->parms.proto = p->proto;
        t->parms.fwmark = p->fwmark;
        dst_cache_reset(&t->dst_cache);
-       vti6_link_config(t);
+       vti6_link_config(t, keep_mtu);
        return 0;
 }
 
-static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
+static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p,
+                      bool keep_mtu)
 {
        struct net *net = dev_net(t->dev);
        struct vti6_net *ip6n = net_generic(net, vti6_net_id);
@@ -691,7 +703,7 @@ static int vti6_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
 
        vti6_tnl_unlink(ip6n, t);
        synchronize_net();
-       err = vti6_tnl_change(t, p);
+       err = vti6_tnl_change(t, p, keep_mtu);
        vti6_tnl_link(ip6n, t);
        netdev_state_change(t->dev);
        return err;
@@ -804,7 +816,7 @@ vti6_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                        } else
                                t = netdev_priv(dev);
 
-                       err = vti6_update(t, &p1);
+                       err = vti6_update(t, &p1, false);
                }
                if (t) {
                        err = 0;
@@ -866,10 +878,8 @@ static void vti6_dev_setup(struct net_device *dev)
        dev->priv_destructor = vti6_dev_free;
 
        dev->type = ARPHRD_TUNNEL6;
-       dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
-       dev->mtu = ETH_DATA_LEN;
        dev->min_mtu = IPV6_MIN_MTU;
-       dev->max_mtu = IP_MAX_MTU;
+       dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr);
        dev->flags |= IFF_NOARP;
        dev->addr_len = sizeof(struct in6_addr);
        netif_keep_dst(dev);
@@ -905,7 +915,7 @@ static int vti6_dev_init(struct net_device *dev)
 
        if (err)
                return err;
-       vti6_link_config(t);
+       vti6_link_config(t, true);
        return 0;
 }
 
@@ -1010,7 +1020,7 @@ static int vti6_changelink(struct net_device *dev, struct nlattr *tb[],
        } else
                t = netdev_priv(dev);
 
-       return vti6_update(t, &p);
+       return vti6_update(t, &p, tb && tb[IFLA_MTU]);
 }
 
 static size_t vti6_get_size(const struct net_device *dev)
index ebb2bf84232acd1fac088dbc4d3151701cc52a40..f14de4b6d639df72f6bbc34630581b1b6fdddfae 100644 (file)
@@ -116,9 +116,11 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
        }
 
        if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) {
-               struct udphdr _hdr, *hp;
+               struct tcphdr _hdr;
+               struct udphdr *hp;
 
-               hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr);
+               hp = skb_header_pointer(skb, thoff, tproto == IPPROTO_UDP ?
+                                       sizeof(*hp) : sizeof(_hdr), &_hdr);
                if (hp == NULL)
                        return NULL;
 
index b0d5c64e19780ce94feb112285ed1d85dbe07e9e..fc74352fac125877483b9d6ad83f89cfcdb8c4f8 100644 (file)
@@ -919,6 +919,9 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net,
        struct rt6_info *rt, *rt_cache;
        struct fib6_node *fn;
 
+       if (fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF)
+               flags &= ~RT6_LOOKUP_F_IFACE;
+
        rcu_read_lock();
        fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
 restart:
@@ -1626,11 +1629,10 @@ static void rt6_age_examine_exception(struct rt6_exception_bucket *bucket,
                struct neighbour *neigh;
                __u8 neigh_flags = 0;
 
-               neigh = dst_neigh_lookup(&rt->dst, &rt->rt6i_gateway);
-               if (neigh) {
+               neigh = __ipv6_neigh_lookup_noref(rt->dst.dev, &rt->rt6i_gateway);
+               if (neigh)
                        neigh_flags = neigh->flags;
-                       neigh_release(neigh);
-               }
+
                if (!(neigh_flags & NTF_ROUTER)) {
                        RT6_TRACE("purging route %p via non-router but gateway\n",
                                  rt);
@@ -1654,7 +1656,8 @@ void rt6_age_exceptions(struct rt6_info *rt,
        if (!rcu_access_pointer(rt->rt6i_exception_bucket))
                return;
 
-       spin_lock_bh(&rt6_exception_lock);
+       rcu_read_lock_bh();
+       spin_lock(&rt6_exception_lock);
        bucket = rcu_dereference_protected(rt->rt6i_exception_bucket,
                                    lockdep_is_held(&rt6_exception_lock));
 
@@ -1668,7 +1671,8 @@ void rt6_age_exceptions(struct rt6_info *rt,
                        bucket++;
                }
        }
-       spin_unlock_bh(&rt6_exception_lock);
+       spin_unlock(&rt6_exception_lock);
+       rcu_read_unlock_bh();
 }
 
 struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
index 7a78dcfda68a17e10e5e951db21d8113c7f65301..f343e6f0fc95a89fa5f386430dc161600367338c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/net.h>
 #include <linux/module.h>
 #include <net/ip.h>
+#include <net/ip_tunnels.h>
 #include <net/lwtunnel.h>
 #include <net/netevent.h>
 #include <net/netns/generic.h>
@@ -211,11 +212,6 @@ static int seg6_do_srh(struct sk_buff *skb)
 
        tinfo = seg6_encap_lwtunnel(dst->lwtstate);
 
-       if (likely(!skb->encapsulation)) {
-               skb_reset_inner_headers(skb);
-               skb->encapsulation = 1;
-       }
-
        switch (tinfo->mode) {
        case SEG6_IPTUN_MODE_INLINE:
                if (skb->protocol != htons(ETH_P_IPV6))
@@ -224,10 +220,12 @@ static int seg6_do_srh(struct sk_buff *skb)
                err = seg6_do_srh_inline(skb, tinfo->srh);
                if (err)
                        return err;
-
-               skb_reset_inner_headers(skb);
                break;
        case SEG6_IPTUN_MODE_ENCAP:
+               err = iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6);
+               if (err)
+                       return err;
+
                if (skb->protocol == htons(ETH_P_IPV6))
                        proto = IPPROTO_IPV6;
                else if (skb->protocol == htons(ETH_P_IP))
@@ -239,6 +237,8 @@ static int seg6_do_srh(struct sk_buff *skb)
                if (err)
                        return err;
 
+               skb_set_inner_transport_header(skb, skb_transport_offset(skb));
+               skb_set_inner_protocol(skb, skb->protocol);
                skb->protocol = htons(ETH_P_IPV6);
                break;
        case SEG6_IPTUN_MODE_L2ENCAP:
@@ -262,8 +262,6 @@ static int seg6_do_srh(struct sk_buff *skb)
        ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
        skb_set_transport_header(skb, sizeof(struct ipv6hdr));
 
-       skb_set_inner_protocol(skb, skb->protocol);
-
        return 0;
 }
 
index e7a3a6b6cf5650f1036b875688b48f3ee2f9c967..e997141aed8c059c40e6e5f0229e256317a8b483 100644 (file)
@@ -217,6 +217,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        treq->snt_isn = cookie;
        treq->ts_off = 0;
        treq->txhash = net_tx_rndhash();
+       if (IS_ENABLED(CONFIG_SMC))
+               ireq->smc_ok = 0;
 
        /*
         * We need to lookup the dst_entry to get the correct window size.
index f59648018060f3bb40dc0c5ebc6cba1fd9c571b7..163121192acae1c88f6a81d7a594c189da3678da 100644 (file)
@@ -389,7 +389,7 @@ static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
        llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
        rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
        if (likely(!rc)) {
-               llc_conn_send_pdu(sk, skb);
+               rc = llc_conn_send_pdu(sk, skb);
                llc_conn_ac_inc_vs_by_1(sk, skb);
        }
        return rc;
@@ -916,7 +916,7 @@ static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
        llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
        rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
        if (likely(!rc)) {
-               llc_conn_send_pdu(sk, skb);
+               rc = llc_conn_send_pdu(sk, skb);
                llc_conn_ac_inc_vs_by_1(sk, skb);
        }
        return rc;
@@ -935,14 +935,17 @@ static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
 int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
 {
        struct llc_sock *llc = llc_sk(sk);
+       int ret;
 
        if (llc->ack_must_be_send) {
-               llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
+               ret = llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
                llc->ack_must_be_send = 0 ;
                llc->ack_pf = 0;
-       } else
-               llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
-       return 0;
+       } else {
+               ret = llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
+       }
+
+       return ret;
 }
 
 /**
index 9177dbb16dce22d46d390b4d48b191576d967452..110e32bcb39976c9e319329f6ca9ba5809614aa8 100644 (file)
@@ -30,7 +30,7 @@
 #endif
 
 static int llc_find_offset(int state, int ev_type);
-static void llc_conn_send_pdus(struct sock *sk);
+static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *skb);
 static int llc_conn_service(struct sock *sk, struct sk_buff *skb);
 static int llc_exec_conn_trans_actions(struct sock *sk,
                                       struct llc_conn_state_trans *trans,
@@ -193,11 +193,11 @@ out_skb_put:
        return rc;
 }
 
-void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
+int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
 {
        /* queue PDU to send to MAC layer */
        skb_queue_tail(&sk->sk_write_queue, skb);
-       llc_conn_send_pdus(sk);
+       return llc_conn_send_pdus(sk, skb);
 }
 
 /**
@@ -255,7 +255,7 @@ void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit)
        if (howmany_resend > 0)
                llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
        /* any PDUs to re-send are queued up; start sending to MAC */
-       llc_conn_send_pdus(sk);
+       llc_conn_send_pdus(sk, NULL);
 out:;
 }
 
@@ -296,7 +296,7 @@ void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit)
        if (howmany_resend > 0)
                llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO;
        /* any PDUs to re-send are queued up; start sending to MAC */
-       llc_conn_send_pdus(sk);
+       llc_conn_send_pdus(sk, NULL);
 out:;
 }
 
@@ -340,12 +340,16 @@ out:
 /**
  *     llc_conn_send_pdus - Sends queued PDUs
  *     @sk: active connection
+ *     @hold_skb: the skb held by caller, or NULL if does not care
  *
- *     Sends queued pdus to MAC layer for transmission.
+ *     Sends queued pdus to MAC layer for transmission. When @hold_skb is
+ *     NULL, always return 0. Otherwise, return 0 if @hold_skb is sent
+ *     successfully, or 1 for failure.
  */
-static void llc_conn_send_pdus(struct sock *sk)
+static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *hold_skb)
 {
        struct sk_buff *skb;
+       int ret = 0;
 
        while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) {
                struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
@@ -357,10 +361,20 @@ static void llc_conn_send_pdus(struct sock *sk)
                        skb_queue_tail(&llc_sk(sk)->pdu_unack_q, skb);
                        if (!skb2)
                                break;
-                       skb = skb2;
+                       dev_queue_xmit(skb2);
+               } else {
+                       bool is_target = skb == hold_skb;
+                       int rc;
+
+                       if (is_target)
+                               skb_get(skb);
+                       rc = dev_queue_xmit(skb);
+                       if (is_target)
+                               ret = rc;
                }
-               dev_queue_xmit(skb);
        }
+
+       return ret;
 }
 
 /**
index c4acc7340eb1014bb0941bf6054908c178595770..530e12ae52d7f0d8fed9b8e05611d1c9a75e4ef1 100644 (file)
@@ -74,15 +74,77 @@ static void nft_trans_destroy(struct nft_trans *trans)
        kfree(trans);
 }
 
+/* removal requests are queued in the commit_list, but not acted upon
+ * until after all new rules are in place.
+ *
+ * Therefore, nf_register_net_hook(net, &nat_hook) runs before pending
+ * nf_unregister_net_hook().
+ *
+ * nf_register_net_hook thus fails if a nat hook is already in place
+ * even if the conflicting hook is about to be removed.
+ *
+ * If collision is detected, search commit_log for DELCHAIN matching
+ * the new nat hooknum; if we find one collision is temporary:
+ *
+ * Either transaction is aborted (new/colliding hook is removed), or
+ * transaction is committed (old hook is removed).
+ */
+static bool nf_tables_allow_nat_conflict(const struct net *net,
+                                        const struct nf_hook_ops *ops)
+{
+       const struct nft_trans *trans;
+       bool ret = false;
+
+       if (!ops->nat_hook)
+               return false;
+
+       list_for_each_entry(trans, &net->nft.commit_list, list) {
+               const struct nf_hook_ops *pending_ops;
+  &n