Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 31 Mar 2018 17:50:30 +0000 (07:50 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 31 Mar 2018 17:50:30 +0000 (07:50 -1000)
Pull x86 fixes from Ingo Molnar:
 "Two UV platform fixes, and a kbuild fix"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/platform/UV: Fix critical UV MMR address error
  x86/platform/uv/BAU: Add APIC idt entry
  x86/purgatory: Avoid creating stray .<pid>.d files, remove -MD from KBUILD_CFLAGS

185 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/Kconfig.cpu
arch/x86/Makefile
arch/x86/boot/compressed/misc.c
arch/x86/entry/entry_64.S
arch/x86/entry/vdso/vdso32/vclock_gettime.c
arch/x86/entry/vsyscall/vsyscall_64.c
arch/x86/events/core.c
arch/x86/events/intel/core.c
arch/x86/events/intel/ds.c
arch/x86/events/intel/uncore_snbep.c
arch/x86/events/perf_event.h
arch/x86/include/asm/alternative.h
arch/x86/include/asm/barrier.h
arch/x86/include/asm/io.h
arch/x86/kernel/idt.c
arch/x86/kernel/kvm.c
arch/x86/kernel/pci-nommu.c
arch/x86/kernel/traps.c
arch/x86/kvm/vmx.c
arch/x86/platform/efi/efi_64.c
arch/x86/um/asm/barrier.h
drivers/atm/iphase.c
drivers/dma/stm32-dmamux.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/tty/vt/vt.c
drivers/vhost/net.c
drivers/vhost/vhost.c
fs/ceph/file.c
include/linux/if_vlan.h
include/linux/jump_label.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
init/main.c
ipc/mqueue.c
ipc/shm.c
kernel/events/core.c
kernel/jump_label.c
kernel/locking/mutex.c
kernel/sched/debug.c
kernel/time/posix-timers.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
tools/testing/selftests/x86/ptrace_syscall.c

index e18cab7..a2ce89a 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 1688b5a..021aa9c 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 32d4e80..74bd2bd 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 356f794..e5dd1ad 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 7534c60..9b1ce27 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 73c0cda..6e950b8 100644 (file)
@@ -1060,41 +1060,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
 
@@ -1152,7 +1153,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
@@ -4626,7 +4627,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/
@@ -8434,7 +8435,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
@@ -8447,7 +8448,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
@@ -12875,6 +12876,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
@@ -13644,7 +13658,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 486db37..9f77440 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 16
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
 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 78a6470..199ebc1 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 1189598..5e7d758 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 b0d8431..ae2b8c9 100644 (file)
                };
        };
 
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x40000000 0>;
+       };
+
        ahb {
                compatible = "simple-bus";
                #address-cells = <1>;
index 40de3b6..2477ebc 100644 (file)
                };
        };
 
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0>;
+       };
+
        ahb {
                compatible = "simple-bus";
                #address-cells = <1>;
index a7a5dc7..e7d2db8 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 6102e4e..354aff4 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 51e6f1d..b2758dd 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 9c99e81..5b85889 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 a4d6dc0..f4dd7f9 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 a3e7807..62eb7d6 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 7e5d7a0..36cd23c 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 d443e48..8805a59 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 fb061cf..30a0773 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 a5bc92d..921840a 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 03c6a3c..4c375e1 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 03f1950..204bdb9 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 2605118..0b81ca1 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 0abeb0e..37671fe 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 8eea90f..19b45ba 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 a2c5c95..2e2bacb 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 051b3d6..3a15b6d 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 945e2c2..8ca5d5b 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 3ac87e5..1ecfd8f 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 f880388..061aa0f 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 5cb4e46..5d9bafe 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 8888e62..e1c083f 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 d332646..f86a202 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 a0675e9..656933c 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 929d9ef..3f980ba 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 28c980e..adf469f 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 71d1b19..a07f537 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 8b8d229..638411f 100644 (file)
@@ -315,19 +315,6 @@ config X86_L1_CACHE_SHIFT
        default "4" if MELAN || M486 || MGEODEGX1
        default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
 
-config X86_PPRO_FENCE
-       bool "PentiumPro memory ordering errata workaround"
-       depends on M686 || M586MMX || M586TSC || M586 || M486 || MGEODEGX1
-       ---help---
-         Old PentiumPro multiprocessor systems had errata that could cause
-         memory operations to violate the x86 ordering standard in rare cases.
-         Enabling this option will attempt to work around some (but not all)
-         occurrences of this problem, at the cost of much heavier spinlock and
-         memory barrier operations.
-
-         If unsure, say n here. Even distro kernels should think twice before
-         enabling this: there are few systems, and an unlikely bug.
-
 config X86_F00F_BUG
        def_bool y
        depends on M586MMX || M586TSC || M586 || M486
index 498c1b8..1c4d012 100644 (file)
@@ -223,6 +223,15 @@ KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr)
 
 LDFLAGS := -m elf_$(UTS_MACHINE)
 
+#
+# The 64-bit kernel must be aligned to 2MB.  Pass -z max-page-size=0x200000 to
+# the linker to force 2MB page size regardless of the default page size used
+# by the linker.
+#
+ifdef CONFIG_X86_64
+LDFLAGS += $(call ld-option, -z max-page-size=0x200000)
+endif
+
 # Speed up the build
 KBUILD_CFLAGS += -pipe
 # Workaround for a gcc prelease that unfortunately was shipped in a suse release
index 98761a1..252fee3 100644 (file)
@@ -309,6 +309,10 @@ static void parse_elf(void *output)
 
                switch (phdr->p_type) {
                case PT_LOAD:
+#ifdef CONFIG_X86_64
+                       if ((phdr->p_align % 0x200000) != 0)
+                               error("Alignment of LOAD segment isn't multiple of 2MB");
+#endif
 #ifdef CONFIG_RELOCATABLE
                        dest = output;
                        dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
index 805f527..18ed349 100644 (file)
@@ -1138,7 +1138,7 @@ apicinterrupt3 HYPERV_REENLIGHTENMENT_VECTOR \
 #endif /* CONFIG_HYPERV */
 
 idtentry debug                 do_debug                has_error_code=0        paranoid=1 shift_ist=DEBUG_STACK
-idtentry int3                  do_int3                 has_error_code=0        paranoid=1 shift_ist=DEBUG_STACK
+idtentry int3                  do_int3                 has_error_code=0
 idtentry stack_segment         do_stack_segment        has_error_code=1
 
 #ifdef CONFIG_XEN
index 7780bbf..9242b28 100644 (file)
@@ -5,8 +5,6 @@
 #undef CONFIG_OPTIMIZE_INLINING
 #endif
 
-#undef CONFIG_X86_PPRO_FENCE
-
 #ifdef CONFIG_X86_64
 
 /*
index 8560ef6..317be36 100644 (file)
@@ -347,7 +347,7 @@ void __init set_vsyscall_pgtable_user_bits(pgd_t *root)
        set_pgd(pgd, __pgd(pgd_val(*pgd) | _PAGE_USER));
        p4d = p4d_offset(pgd, VSYSCALL_ADDR);
 #if CONFIG_PGTABLE_LEVELS >= 5
-       p4d->p4d |= _PAGE_USER;
+       set_p4d(p4d, __p4d(p4d_val(*p4d) | _PAGE_USER));
 #endif
        pud = pud_offset(p4d, VSYSCALL_ADDR);
        set_pud(pud, __pud(pud_val(*pud) | _PAGE_USER));
index 140d332..88797c8 100644 (file)
@@ -2118,7 +2118,8 @@ static int x86_pmu_event_init(struct perf_event *event)
                        event->destroy(event);
        }
 
-       if (READ_ONCE(x86_pmu.attr_rdpmc))
+       if (READ_ONCE(x86_pmu.attr_rdpmc) &&
+           !(event->hw.flags & PERF_X86_EVENT_LARGE_PEBS))
                event->hw.flags |= PERF_X86_EVENT_RDPMC_ALLOWED;
 
        return err;
index 56457cb..1e41d75 100644 (file)
@@ -2952,9 +2952,9 @@ static void intel_pebs_aliases_skl(struct perf_event *event)
        return intel_pebs_aliases_precdist(event);
 }
 
-static unsigned long intel_pmu_free_running_flags(struct perf_event *event)
+static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event)
 {
-       unsigned long flags = x86_pmu.free_running_flags;
+       unsigned long flags = x86_pmu.large_pebs_flags;
 
        if (event->attr.use_clockid)
                flags &= ~PERF_SAMPLE_TIME;
@@ -2976,8 +2976,8 @@ static int intel_pmu_hw_config(struct perf_event *event)
                if (!event->attr.freq) {
                        event->hw.flags |= PERF_X86_EVENT_AUTO_RELOAD;
                        if (!(event->attr.sample_type &
-                             ~intel_pmu_free_running_flags(event)))
-                               event->hw.flags |= PERF_X86_EVENT_FREERUNNING;
+                             ~intel_pmu_large_pebs_flags(event)))
+                               event->hw.flags |= PERF_X86_EVENT_LARGE_PEBS;
                }
                if (x86_pmu.pebs_aliases)
                        x86_pmu.pebs_aliases(event);
@@ -3194,7 +3194,7 @@ static unsigned bdw_limit_period(struct perf_event *event, unsigned left)
                        X86_CONFIG(.event=0xc0, .umask=0x01)) {
                if (left < 128)
                        left = 128;
-               left &= ~0x3fu;
+               left &= ~0x3fULL;
        }
        return left;
 }
@@ -3460,7 +3460,7 @@ static __initconst const struct x86_pmu core_pmu = {
        .event_map              = intel_pmu_event_map,
        .max_events             = ARRAY_SIZE(intel_perfmon_event_map),
        .apic                   = 1,
-       .free_running_flags     = PEBS_FREERUNNING_FLAGS,
+       .large_pebs_flags       = LARGE_PEBS_FLAGS,
 
        /*
         * Intel PMCs cannot be accessed sanely above 32-bit width,
@@ -3502,7 +3502,7 @@ static __initconst const struct x86_pmu intel_pmu = {
        .event_map              = intel_pmu_event_map,
        .max_events             = ARRAY_SIZE(intel_perfmon_event_map),
        .apic                   = 1,
-       .free_running_flags     = PEBS_FREERUNNING_FLAGS,
+       .large_pebs_flags       = LARGE_PEBS_FLAGS,
        /*
         * Intel PMCs cannot be accessed sanely above 32 bit width,
         * so we install an artificial 1<<31 period regardless of
index 18c25ab..d801523 100644 (file)
@@ -935,7 +935,7 @@ void intel_pmu_pebs_add(struct perf_event *event)
        bool needed_cb = pebs_needs_sched_cb(cpuc);
 
        cpuc->n_pebs++;
-       if (hwc->flags & PERF_X86_EVENT_FREERUNNING)
+       if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
                cpuc->n_large_pebs++;
 
        pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
@@ -975,7 +975,7 @@ void intel_pmu_pebs_del(struct perf_event *event)
        bool needed_cb = pebs_needs_sched_cb(cpuc);
 
        cpuc->n_pebs--;
-       if (hwc->flags & PERF_X86_EVENT_FREERUNNING)
+       if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
                cpuc->n_large_pebs--;
 
        pebs_update_state(needed_cb, cpuc, event->ctx->pmu);
@@ -1530,7 +1530,7 @@ void __init intel_ds_init(void)
                        x86_pmu.pebs_record_size =
                                                sizeof(struct pebs_record_skl);
                        x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
-                       x86_pmu.free_running_flags |= PERF_SAMPLE_TIME;
+                       x86_pmu.large_pebs_flags |= PERF_SAMPLE_TIME;
                        break;
 
                default:
index 22ec65b..c98b943 100644 (file)
@@ -3343,6 +3343,7 @@ static struct extra_reg skx_uncore_cha_extra_regs[] = {
        SNBEP_CBO_EVENT_EXTRA_REG(0x9134, 0xffff, 0x4),
        SNBEP_CBO_EVENT_EXTRA_REG(0x35, 0xff, 0x8),
        SNBEP_CBO_EVENT_EXTRA_REG(0x36, 0xff, 0x8),
+       SNBEP_CBO_EVENT_EXTRA_REG(0x38, 0xff, 0x3),
        EVENT_EXTRA_END
 };
 
@@ -3562,24 +3563,27 @@ static struct intel_uncore_type *skx_msr_uncores[] = {
        NULL,
 };
 
+/*
+ * To determine the number of CHAs, it should read bits 27:0 in the CAPID6
+ * register which located at Device 30, Function 3, Offset 0x9C. PCI ID 0x2083.
+ */
+#define SKX_CAPID6             0x9c
+#define SKX_CHA_BIT_MASK       GENMASK(27, 0)
+
 static int skx_count_chabox(void)
 {
-       struct pci_dev *chabox_dev = NULL;
-       int bus, count = 0;
+       struct pci_dev *dev = NULL;
+       u32 val = 0;
 
-       while (1) {
-               chabox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x208d, chabox_dev);
-               if (!chabox_dev)
-                       break;
-               if (count == 0)
-                       bus = chabox_dev->bus->number;
-               if (bus != chabox_dev->bus->number)
-                       break;
-               count++;
-       }
+       dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x2083, dev);
+       if (!dev)
+               goto out;
 
-       pci_dev_put(chabox_dev);
-       return count;
+       pci_read_config_dword(dev, SKX_CAPID6, &val);
+       val &= SKX_CHA_BIT_MASK;
+out:
+       pci_dev_put(dev);
+       return hweight32(val);
 }
 
 void skx_uncore_cpu_init(void)
index 78f91ec..39cd061 100644 (file)
@@ -69,7 +69,7 @@ struct event_constraint {
 #define PERF_X86_EVENT_RDPMC_ALLOWED   0x0100 /* grant rdpmc permission */
 #define PERF_X86_EVENT_EXCL_ACCT       0x0200 /* accounted EXCL event */
 #define PERF_X86_EVENT_AUTO_RELOAD     0x0400 /* use PEBS auto-reload */
-#define PERF_X86_EVENT_FREERUNNING     0x0800 /* use freerunning PEBS */
+#define PERF_X86_EVENT_LARGE_PEBS      0x0800 /* use large PEBS */
 
 
 struct amd_nb {
@@ -88,7 +88,7 @@ struct amd_nb {
  * REGS_USER can be handled for events limited to ring 3.
  *
  */
-#define PEBS_FREERUNNING_FLAGS \
+#define LARGE_PEBS_FLAGS \
        (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \
        PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \
        PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \
@@ -608,7 +608,7 @@ struct x86_pmu {
        struct event_constraint *pebs_constraints;
        void            (*pebs_aliases)(struct perf_event *event);
        int             max_pebs_events;
-       unsigned long   free_running_flags;
+       unsigned long   large_pebs_flags;
 
        /*
         * Intel LBR
index cf5961c..4cd6a3b 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 e1259f0..042b5e8 100644 (file)
@@ -52,11 +52,7 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
 #define barrier_nospec() alternative_2("", "mfence", X86_FEATURE_MFENCE_RDTSC, \
                                           "lfence", X86_FEATURE_LFENCE_RDTSC)
 
-#ifdef CONFIG_X86_PPRO_FENCE
-#define dma_rmb()      rmb()
-#else
 #define dma_rmb()      barrier()
-#endif
 #define dma_wmb()      barrier()
 
 #ifdef CONFIG_X86_32
@@ -68,30 +64,6 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
 #define __smp_wmb()    barrier()
 #define __smp_store_mb(var, value) do { (void)xchg(&var, value); } while (0)
 
-#if defined(CONFIG_X86_PPRO_FENCE)
-
-/*
- * For this option x86 doesn't have a strong TSO memory
- * model and we should fall back to full barriers.
- */
-
-#define __smp_store_release(p, v)                                      \
-do {                                                                   \
-       compiletime_assert_atomic_type(*p);                             \
-       __smp_mb();                                                     \
-       WRITE_ONCE(*p, v);                                              \
-} while (0)
-
-#define __smp_load_acquire(p)                                          \
-({                                                                     \
-       typeof(*p) ___p1 = READ_ONCE(*p);                               \
-       compiletime_assert_atomic_type(*p);                             \
-       __smp_mb();                                                     \
-       ___p1;                                                          \
-})
-
-#else /* regular x86 TSO memory ordering */
-
 #define __smp_store_release(p, v)                                      \
 do {                                                                   \
        compiletime_assert_atomic_type(*p);                             \
@@ -107,8 +79,6 @@ do {                                                                 \
        ___p1;                                                          \
 })
 
-#endif
-
 /* Atomic operations are already serializing on x86 */
 #define __smp_mb__before_atomic()      barrier()
 #define __smp_mb__after_atomic()       barrier()
index 95e9486..f6e5b93 100644 (file)
@@ -232,21 +232,6 @@ extern void set_iounmap_nonlazy(void);
  */
 #define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
 
-/*
- *     Cache management
- *
- *     This needed for two cases
- *     1. Out of order aware processors
- *     2. Accidentally out of order processors (PPro errata #51)
- */
-
-static inline void flush_write_buffers(void)
-{
-#if defined(CONFIG_X86_PPRO_FENCE)
-       asm volatile("lock; addl $0,0(%%esp)": : :"memory");
-#endif
-}
-
 #endif /* __KERNEL__ */
 
 extern void native_io_delay(void);
index 5d039c8..2c3a1b4 100644 (file)
@@ -163,7 +163,6 @@ static const __initconst struct idt_data early_pf_idts[] = {
  */
 static const __initconst struct idt_data dbg_idts[] = {
        INTG(X86_TRAP_DB,       debug),
-       INTG(X86_TRAP_BP,       int3),
 };
 #endif
 
@@ -186,7 +185,6 @@ gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss;
 static const __initconst struct idt_data ist_idts[] = {
        ISTG(X86_TRAP_DB,       debug,          DEBUG_STACK),
        ISTG(X86_TRAP_NMI,      nmi,            NMI_STACK),
-       SISTG(X86_TRAP_BP,      int3,           DEBUG_STACK),
        ISTG(X86_TRAP_DF,       double_fault,   DOUBLEFAULT_STACK),
 #ifdef CONFIG_X86_MCE
        ISTG(X86_TRAP_MC,       &machine_check, MCE_STACK),
index bc1a272..fae86e3 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 618285e..ac7ea3a 100644 (file)
@@ -37,7 +37,6 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
        WARN_ON(size == 0);
        if (!check_addr("map_single", dev, bus, size))
                return NOMMU_MAPPING_ERROR;
-       flush_write_buffers();
        return bus;
 }
 
@@ -72,25 +71,9 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
                        return 0;
                s->dma_length = s->length;
        }
-       flush_write_buffers();
        return nents;
 }
 
-static void nommu_sync_single_for_device(struct device *dev,
-                       dma_addr_t addr, size_t size,
-                       enum dma_data_direction dir)
-{
-       flush_write_buffers();
-}
-
-
-static void nommu_sync_sg_for_device(struct device *dev,
-                       struct scatterlist *sg, int nelems,
-                       enum dma_data_direction dir)
-{
-       flush_write_buffers();
-}
-
 static int nommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
        return dma_addr == NOMMU_MAPPING_ERROR;
@@ -101,8 +84,6 @@ const struct dma_map_ops nommu_dma_ops = {
        .free                   = dma_generic_free_coherent,
        .map_sg                 = nommu_map_sg,
        .map_page               = nommu_map_page,
-       .sync_single_for_device = nommu_sync_single_for_device,
-       .sync_sg_for_device     = nommu_sync_sg_for_device,
        .is_phys                = 1,
        .mapping_error          = nommu_mapping_error,
        .dma_supported          = x86_dma_supported,
index 3d9b230..03f3d76 100644 (file)
@@ -577,7 +577,6 @@ do_general_protection(struct pt_regs *regs, long error_code)
 }
 NOKPROBE_SYMBOL(do_general_protection);
 
-/* May run on IST stack. */
 dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
 {
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -592,6 +591,13 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
        if (poke_int3_handler(regs))
                return;
 
+       /*
+        * Use ist_enter despite the fact that we don't use an IST stack.
+        * We can be called from a kprobe in non-CONTEXT_KERNEL kernel
+        * mode or even during context tracking state changes.
+        *
+        * This means that we can't schedule.  That's okay.
+        */
        ist_enter(regs);
        RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
@@ -609,15 +615,10 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
                        SIGTRAP) == NOTIFY_STOP)
                goto exit;
 
-       /*
-        * Let others (NMI) know that the debug stack is in use
-        * as we may switch to the interrupt stack.
-        */
-       debug_stack_usage_inc();
        cond_local_irq_enable(regs);
        do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL);
        cond_local_irq_disable(regs);
-       debug_stack_usage_dec();
+
 exit:
        ist_exit(regs);
 }
index 2d87603..657c934 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 c310a82..f9cfbc0 100644 (file)
@@ -227,7 +227,7 @@ int __init efi_alloc_page_tables(void)
        if (!pud) {
                if (CONFIG_PGTABLE_LEVELS > 4)
                        free_page((unsigned long) pgd_page_vaddr(*pgd));
-               free_page((unsigned long)efi_pgd);
+               free_pages((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER);
                return -ENOMEM;
        }
 
index b7d7340..f31e5d9 100644 (file)
 
 #endif /* CONFIG_X86_32 */
 
-#ifdef CONFIG_X86_PPRO_FENCE
-#define dma_rmb()      rmb()
-#else /* CONFIG_X86_PPRO_FENCE */
 #define dma_rmb()      barrier()
-#endif /* CONFIG_X86_PPRO_FENCE */
 #define dma_wmb()      barrier()
 
 #include <asm-generic/barrier.h>
index 98a3a43..44abb8a 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 4dbb30c..b922db9 100644 (file)
@@ -118,14 +118,15 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
        spin_lock_irqsave(&dmamux->lock, flags);
        mux->chan_id = find_first_zero_bit(dmamux->dma_inuse,
                                           dmamux->dma_requests);
-       set_bit(mux->chan_id, dmamux->dma_inuse);
-       spin_unlock_irqrestore(&dmamux->lock, flags);
 
        if (mux->chan_id == dmamux->dma_requests) {
+               spin_unlock_irqrestore(&dmamux->lock, flags);
                dev_err(&pdev->dev, "Run out of free DMA requests\n");
                ret = -ENOMEM;
-               goto error;
+               goto error_chan_id;
        }
+       set_bit(mux->chan_id, dmamux->dma_inuse);
+       spin_unlock_irqrestore(&dmamux->lock, flags);
 
        /* Look for DMA Master */
        for (i = 1, min = 0, max = dmamux->dma_reqs[i];
@@ -173,6 +174,8 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
 
 error:
        clear_bit(mux->chan_id, dmamux->dma_inuse);
+
+error_chan_id:
        kfree(mux);
        return ERR_PTR(ret);
 }
index b21285a..1bd5f26 100644 (file)
@@ -821,13 +821,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 =
@@ -838,7 +838,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;
        }
 
        dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
@@ -848,7 +848,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++;
@@ -869,7 +869,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;
 }
@@ -1188,8 +1194,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 0ecbd1f..0c3bc00 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 fbffe19..90b25ce 100644 (file)
@@ -2009,9 +2009,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,
 };
 
 static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
@@ -2160,7 +2160,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 b445b3b..f273e28 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 9183d14..cb1d2ab 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 bb065c9..b7459cf 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 e5a1e7d..d933336 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 db2ff35..ec63877 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 da091de..7f8bda3 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 c51c602..3e0b3f0 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 db4bf97..0ffb9b9 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 875b172..419a158 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 a05a560..a6b7baf 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 45328d8..353ea0e 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 7c0b27d..b479bd8 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 fcbe4fd..ca0a703 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 c669554..b7b1130 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 8a0bb00..4e53c5c 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 25e9a55..3f6fb63 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 1a0c3bf..752a724 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 ebc1f56..f3302ed 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 2c29654..d25e16d 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 606a0e0..29e50f7 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 25deaa5..c032319 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 cc8048f..59ebfda 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 da94c8c..9b4827d 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 363d8dc..500d817 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 fa86a14..43234ca 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 f7948e9..997e24d 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 56451ed..ecd7c33 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 dafc079..1494130 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 0bf7d17..b4779ac 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 a6ec41c..465c42e 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 56c701b..befed2d 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 60a604c..55a78eb 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 76ac480..ca066b7 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 139c61c..ac40924 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 15fa00d..1ad97a4 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 9be0b05..ebe35e6 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 a62f8e7..ef91461 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 930e423..44b7774 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 90a1d14..ab14694 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 1a05d50..2cb303c 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 258d439..f0f5636 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 0920be6..3c59109 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 ebf5111..7152fdc 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 89ff02d..625b238 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 305cd56..7f5434b 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 630e23c..80067eb 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 acb217e..cd91bc4 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 af6dfce..7dfe4cd 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 56fc287..e323d3a 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 dd94649..ef22b27 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 5293e68..3a9eca1 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 018f980..fb9f5e7 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 b1b1d3a..daefe81 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 6198559..dd66c11 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 ba6503f..27fab82 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 a71ee67..dde0798 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 dc8e850..5ec3b74 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 3541caf..1fa84d6 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 7c28e8d..45d0463 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 88b902c..b4e57c5 100644 (file)
@@ -1727,7 +1727,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
        default_attr(vc);
        update_attr(vc);
 
-       vc->vc_tab_stop[0]      = 0x01010100;
+       vc->vc_tab_stop[0]      =
        vc->vc_tab_stop[1]      =
        vc->vc_tab_stop[2]      =
        vc->vc_tab_stop[3]      =
@@ -1771,7 +1771,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
                vc->vc_pos -= (vc->vc_x << 1);
                while (vc->vc_x < vc->vc_cols - 1) {
                        vc->vc_x++;
-                       if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31)))
+                       if (vc->vc_tab_stop[7 & (vc->vc_x >> 5)] & (1 << (vc->vc_x & 31)))
                                break;
                }
                vc->vc_pos += (vc->vc_x << 1);
@@ -1831,7 +1831,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
                        lf(vc);
                        return;
                case 'H':
-                       vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31));
+                       vc->vc_tab_stop[7 & (vc->vc_x >> 5)] |= (1 << (vc->vc_x & 31));
                        return;
                case 'Z':
                        respond_ID(tty);
@@ -2024,7 +2024,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
                        return;
                case 'g':
                        if (!vc->vc_par[0])
-                               vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31));
+                               vc->vc_tab_stop[7 & (vc->vc_x >> 5)] &= ~(1 << (vc->vc_x & 31));
                        else if (vc->vc_par[0] == 3) {
                                vc->vc_tab_stop[0] =
                                        vc->vc_tab_stop[1] =
index 8139bc7..12bcfba 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 1b3e8d2..5320039 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 6639926..b67eec3 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 c4a1cff..7d30892 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 2168cc6..b46b541 100644 (file)
@@ -151,7 +151,7 @@ extern struct jump_entry __start___jump_table[];
 extern struct jump_entry __stop___jump_table[];
 
 extern void jump_label_init(void);
-extern void jump_label_invalidate_init(void);
+extern void jump_label_invalidate_initmem(void);
 extern void jump_label_lock(void);
 extern void jump_label_unlock(void);
 extern void arch_jump_label_transform(struct jump_entry *entry,
@@ -199,7 +199,7 @@ static __always_inline void jump_label_init(void)
        static_key_initialized = true;
 }
 
-static inline void jump_label_invalidate_init(void) {}
+static inline void jump_label_invalidate_initmem(void) {}
 
 static __always_inline bool static_key_false(struct static_key *key)
 {
index bebeaad..29ed8fd 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 fe994d2..5c40f11 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 663b015..30eb065 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 2092d33..8da3267 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 d656809..415e099 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 a8b7bf8..9c1e4ba 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 969eaf1..21efbf6 100644 (file)
@@ -1001,7 +1001,7 @@ static int __ref kernel_init(void *unused)
        /* need to finish all async __init code before freeing the memory */
        async_synchronize_full();
        ftrace_free_init_mem();
-       jump_label_invalidate_init();
+       jump_label_invalidate_initmem();
        free_initmem();
        mark_readonly();
        system_state = SYSTEM_RUNNING;
index d7f309f..a808f29 100644 (file)
@@ -325,9 +325,8 @@ err:
 static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct inode *inode;
-       struct ipc_namespace *ns = data;
+       struct ipc_namespace *ns = sb->s_fs_info;
 
-       sb->s_fs_info = ns;
        sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV;
        sb->s_blocksize = PAGE_SIZE;
        sb->s_blocksize_bits = PAGE_SHIFT;
@@ -344,44 +343,18 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 }
 
-static struct file_system_type mqueue_fs_type;
-/*
- * Return value is pinned only by reference in ->mq_mnt; it will
- * live until ipcns dies.  Caller does not need to drop it.
- */
-static struct vfsmount *mq_internal_mount(void)
-{
-       struct ipc_namespace *ns = current->nsproxy->ipc_ns;
-       struct vfsmount *m = ns->mq_mnt;
-       if (m)
-               return m;
-       m = kern_mount_data(&mqueue_fs_type, ns);
-       spin_lock(&mq_lock);
-       if (unlikely(ns->mq_mnt)) {
-               spin_unlock(&mq_lock);
-               if (!IS_ERR(m))
-                       kern_unmount(m);
-               return ns->mq_mnt;
-       }
-       if (!IS_ERR(m))
-               ns->mq_mnt = m;
-       spin_unlock(&mq_lock);
-       return m;
-}
-
 static struct dentry *mqueue_mount(struct file_system_type *fs_type,
                         int flags, const char *dev_name,
                         void *data)
 {
-       struct vfsmount *m;
-       if (flags & SB_KERNMOUNT)
-               return mount_nodev(fs_type, flags, data, mqueue_fill_super);
-       m = mq_internal_mount();
-       if (IS_ERR(m))
-               return ERR_CAST(m);
-       atomic_inc(&m->mnt_sb->s_active);
-       down_write(&m->mnt_sb->s_umount);
-       return dget(m->mnt_root);
+       struct ipc_namespace *ns;
+       if (flags & SB_KERNMOUNT) {
+               ns = data;
+               data = NULL;
+       } else {
+               ns = current->nsproxy->ipc_ns;
+       }
+       return mount_ns(fs_type, flags, data, ns, ns->user_ns, mqueue_fill_super);
 }
 
 static void init_once(void *foo)
@@ -771,16 +744,13 @@ static int prepare_open(struct dentry *dentry, int oflag, int ro,
 static int do_mq_open(const char __user *u_name, int oflag, umode_t mode,
                      struct mq_attr *attr)
 {
-       struct vfsmount *mnt = mq_internal_mount();
-       struct dentry *root;
+       struct vfsmount *mnt = current->nsproxy->ipc_ns->mq_mnt;
+       struct dentry *root = mnt->mnt_root;
        struct filename *name;
        struct path path;
        int fd, error;
        int ro;
 
-       if (IS_ERR(mnt))
-               return PTR_ERR(mnt);
-
        audit_mq_open(oflag, mode, attr);
 
        if (IS_ERR(name = getname(u_name)))
@@ -791,7 +761,6 @@ static int do_mq_open(const char __user *u_name, int oflag, umode_t mode,
                goto out_putname;
 
        ro = mnt_want_write(mnt);       /* we'll drop it in any case */
-       root = mnt->mnt_root;
        inode_lock(d_inode(root));
        path.dentry = lookup_one_len(name->name, root, strlen(name->name));
        if (IS_ERR(path.dentry)) {
@@ -840,9 +809,6 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
        struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
        struct vfsmount *mnt = ipc_ns->mq_mnt;
 
-       if (!mnt)
-               return -ENOENT;
-
        name = getname(u_name);
        if (IS_ERR(name))
                return PTR_ERR(name);
@@ -1569,26 +1535,28 @@ int mq_init_ns(struct ipc_namespace *ns)
        ns->mq_msgsize_max   = DFLT_MSGSIZEMAX;
        ns->mq_msg_default   = DFLT_MSG;
        ns->mq_msgsize_default  = DFLT_MSGSIZE;
-       ns->mq_mnt = NULL;
 
+       ns->mq_mnt = kern_mount_data(&mqueue_fs_type, ns);
+       if (IS_ERR(ns->mq_mnt)) {
+               int err = PTR_ERR(ns->mq_mnt);
+               ns->mq_mnt = NULL;
+               return err;
+       }
        return 0;
 }
 
 void mq_clear_sbinfo(struct ipc_namespace *ns)
 {
-       if (ns->mq_mnt)
-               ns->mq_mnt->mnt_sb->s_fs_info = NULL;
+       ns->mq_mnt->mnt_sb->s_fs_info = NULL;
 }
 
 void mq_put_mnt(struct ipc_namespace *ns)
 {
-       if (ns->mq_mnt)
-               kern_unmount(ns->mq_mnt);
+       kern_unmount(ns->mq_mnt);
 }
 
 static int __init init_mqueue_fs(void)
 {
-       struct vfsmount *m;
        int error;
 
        mqueue_inode_cachep = kmem_cache_create("mqueue_inode_cache",
@@ -1610,10 +1578,6 @@ static int __init init_mqueue_fs(void)
        if (error)
                goto out_filesystem;
 
-       m = kern_mount_data(&mqueue_fs_type, &init_ipc_ns);
-       if (IS_ERR(m))
-               goto out_filesystem;
-       init_ipc_ns.mq_mnt = m;
        return 0;
 
 out_filesystem:
index 4643865..93e0e3a 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 4b83847..709a55b 100644 (file)
@@ -724,9 +724,15 @@ static inline void __update_cgrp_time(struct perf_cgroup *cgrp)
 
 static inline void update_cgrp_time_from_cpuctx(struct perf_cpu_context *cpuctx)
 {
-       struct perf_cgroup *cgrp_out = cpuctx->cgrp;
-       if (cgrp_out)
-               __update_cgrp_time(cgrp_out);
+       struct perf_cgroup *cgrp = cpuctx->cgrp;
+       struct cgroup_subsys_state *css;
+
+       if (cgrp) {
+               for (css = &cgrp->css; css; css = css->parent) {
+                       cgrp = container_of(css, struct perf_cgroup, css);
+                       __update_cgrp_time(cgrp);
+               }
+       }
 }
 
 static inline void update_cgrp_time_from_event(struct perf_event *event)
@@ -754,6 +760,7 @@ perf_cgroup_set_timestamp(struct task_struct *task,
 {
        struct perf_cgroup *cgrp;
        struct perf_cgroup_info *info;
+       struct cgroup_subsys_state *css;
 
        /*
         * ctx->lock held by caller
@@ -764,8 +771,12 @@ perf_cgroup_set_timestamp(struct task_struct *task,
                return;
 
        cgrp = perf_cgroup_from_task(task, ctx);
-       info = this_cpu_ptr(cgrp->info);
-       info->timestamp = ctx->timestamp;
+
+       for (css = &cgrp->css; css; css = css->parent) {
+               cgrp = container_of(css, struct perf_cgroup, css);
+               info = this_cpu_ptr(cgrp->info);
+               info->timestamp = ctx->timestamp;
+       }
 }
 
 static DEFINE_PER_CPU(struct list_head, cgrp_cpuctx_list);
index e721409..01ebdf1 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/jump_label_ratelimit.h>
 #include <linux/bug.h>
 #include <linux/cpu.h>
+#include <asm/sections.h>
 
 #ifdef HAVE_JUMP_LABEL
 
@@ -421,15 +422,15 @@ void __init jump_label_init(void)
        cpus_read_unlock();
 }
 
-/* Disable any jump label entries in __init code */
-void __init jump_label_invalidate_init(void)
+/* Disable any jump label entries in __init/__exit code */
+void __init jump_label_invalidate_initmem(void)
 {
        struct jump_entry *iter_start = __start___jump_table;
        struct jump_entry *iter_stop = __stop___jump_table;
        struct jump_entry *iter;
 
        for (iter = iter_start; iter < iter_stop; iter++) {
-               if (init_kernel_text(iter->code))
+               if (init_section_contains((void *)(unsigned long)iter->code, 1))
                        iter->code = 0;
        }
 }
index 858a075..2048359 100644 (file)
@@ -1082,15 +1082,16 @@ static noinline int __sched
 __mutex_lock_interruptible_slowpath(struct mutex *lock);
 
 /**
- * mutex_lock_interruptible - acquire the mutex, interruptible
- * @lock: the mutex to be acquired
+ * mutex_lock_interruptible() - Acquire the mutex, interruptible by signals.
+ * @lock: The mutex to be acquired.
  *
- * Lock the mutex like mutex_lock(), and return 0 if the mutex has
- * been acquired or sleep until the mutex becomes available. If a
- * signal arrives while waiting for the lock then this function
- * returns -EINTR.
+ * Lock the mutex like mutex_lock().  If a signal is delivered while the
+ * process is sleeping, this function will return without acquiring the
+ * mutex.
  *
- * This function is similar to (but not equivalent to) down_interruptible().
+ * Context: Process context.
+ * Return: 0 if the lock was successfully acquired or %-EINTR if a
+ * signal arrived.
  */
 int __sched mutex_lock_interruptible(struct mutex *lock)
 {
@@ -1104,6 +1105,18 @@ int __sched mutex_lock_interruptible(struct mutex *lock)
 
 EXPORT_SYMBOL(mutex_lock_interruptible);
 
+/**
+ * mutex_lock_killable() - Acquire the mutex, interruptible by fatal signals.
+ * @lock: The mutex to be acquired.
+ *
+ * Lock the mutex like mutex_lock().  If a signal which will be fatal to
+ * the current process is delivered while the process is sleeping, this
+ * function will return without acquiring the mutex.
+ *
+ * Context: Process context.
+ * Return: 0 if the lock was successfully acquired or %-EINTR if a
+ * fatal signal arrived.
+ */
 int __sched mutex_lock_killable(struct mutex *lock)
 {
        might_sleep();
@@ -1115,6 +1128,16 @@ int __sched mutex_lock_killable(struct mutex *lock)
 }
 EXPORT_SYMBOL(mutex_lock_killable);
 
+/**
+ * mutex_lock_io() - Acquire the mutex and mark the process as waiting for I/O
+ * @lock: The mutex to be acquired.
+ *
+ * Lock the mutex like mutex_lock().  While the task is waiting for this
+ * mutex, it will be accounted as being in the IO wait state by the
+ * scheduler.
+ *
+ * Context: Process context.
+ */
 void __sched mutex_lock_io(struct mutex *lock)
 {
        int token;
index 1ca0130..72c401b 100644 (file)
@@ -32,7 +32,7 @@ static DEFINE_SPINLOCK(sched_debug_lock);
        if (m)                                  \
                seq_printf(m, x);               \
        else                                    \
-               printk(x);                      \
+               pr_cont(x);                     \
  } while (0)
 
 /*
@@ -501,12 +501,12 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
 {
        struct task_struct *g, *p;
 
-       SEQ_printf(m,
-       "\nrunnable tasks:\n"
-       " S           task   PID         tree-key  switches  prio"
-       "     wait-time             sum-exec        sum-sleep\n"
-       "-------------------------------------------------------"
-       "----------------------------------------------------\n");
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "runnable tasks:\n");
+       SEQ_printf(m, " S           task   PID         tree-key  switches  prio"
+                  "     wait-time             sum-exec        sum-sleep\n");
+       SEQ_printf(m, "-------------------------------------------------------"
+                  "----------------------------------------------------\n");
 
        rcu_read_lock();
        for_each_process_thread(g, p) {
@@ -527,9 +527,11 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
        unsigned long flags;
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-       SEQ_printf(m, "\ncfs_rq[%d]:%s\n", cpu, task_group_path(cfs_rq->tg));
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "cfs_rq[%d]:%s\n", cpu, task_group_path(cfs_rq->tg));
 #else
-       SEQ_printf(m, "\ncfs_rq[%d]:\n", cpu);
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "cfs_rq[%d]:\n", cpu);
 #endif
        SEQ_printf(m, "  .%-30s: %Ld.%06ld\n", "exec_clock",
                        SPLIT_NS(cfs_rq->exec_clock));
@@ -595,9 +597,11 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
 void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq)
 {
 #ifdef CONFIG_RT_GROUP_SCHED
-       SEQ_printf(m, "\nrt_rq[%d]:%s\n", cpu, task_group_path(rt_rq->tg));
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "rt_rq[%d]:%s\n", cpu, task_group_path(rt_rq->tg));
 #else
-       SEQ_printf(m, "\nrt_rq[%d]:\n", cpu);
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "rt_rq[%d]:\n", cpu);
 #endif
 
 #define P(x) \
@@ -624,7 +628,8 @@ void print_dl_rq(struct seq_file *m, int cpu, struct dl_rq *dl_rq)
 {
        struct dl_bw *dl_bw;
 
-       SEQ_printf(m, "\ndl_rq[%d]:\n", cpu);
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "dl_rq[%d]:\n", cpu);
 
 #define PU(x) \
        SEQ_printf(m, "  .%-30s: %lu\n", #x, (unsigned long)(dl_rq->x))
index 7504304..10b7186 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/export.h>
 #include <linux/hashtable.h>
 #include <linux/compat.h>
+#include <linux/nospec.h>
 
 #include "timekeeping.h"
 #include "posix-timers.h"
@@ -1346,11 +1347,15 @@ static const struct k_clock * const posix_clocks[] = {
 
 static const struct k_clock *clockid_to_kclock(const clockid_t id)
 {
-       if (id < 0)
+       clockid_t idx = id;
+
+       if (id < 0) {
                return (id & CLOCKFD_MASK) == CLOCKFD ?
                        &clock_posix_dynamic : &clock_posix_cpu;
+       }
 
-       if (id >= ARRAY_SIZE(posix_clocks) || !posix_clocks[id])
+       if (id >= ARRAY_SIZE(posix_clocks))
                return NULL;
-       return posix_clocks[id];
+
+       return posix_clocks[array_index_nospec(idx, ARRAY_SIZE(posix_clocks))];
 }
index e83987c..46c2290 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 670e99b..9ec024b 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 9886c60..7172e0a 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 3244466..9095c39 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 40b2db6..33581be 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 37fe9a6..808d2dd 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 d706401..ee56af5 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 12be205..ef0cc6e 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 1e7acdc..857e4e6 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 6d21068..a7fd1c5 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 51b1669..3f091cc 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 2dad20e..9bd19cd 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 b50721d..9db988f 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 e9293bd..4824b1e 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 fda37f2..c3387df 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 9a1b3c1..ff6cd98 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 a8a9195..5cb18c8 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 fa3ae1c..ce18cd2 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 ebb2bf8..f14de4b 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 b0d5c64..fc74352 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 7a78dcf..f343e6f 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 e7a3a6b..e997141 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 f596480..1631211 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 9177dbb..110e32b 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 c4acc73..530e12a 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;
+               const struct nft_chain *pending;
+
+               if (trans->msg_type != NFT_MSG_NEWCHAIN &&
+                   trans->msg_type != NFT_MSG_DELCHAIN)
+                       continue;
+
+               pending = trans->ctx.chain;
+               if (!nft_is_base_chain(pending))
+                       continue;
+
+               pending_ops = &nft_base_chain(pending)->ops;
+               if (pending_ops->nat_hook &&
+                   pending_ops->pf == ops->pf &&
+                   pending_ops->hooknum == ops->hooknum) {
+                       /* other hook registration already pending? */
+                       if (trans->msg_type == NFT_MSG_NEWCHAIN)
+                               return false;
+
+                       ret = true;
+               }
+       }
+
+       return ret;
+}
+
 static int nf_tables_register_hook(struct net *net,
                                   const struct nft_table *table,
                                   struct nft_chain *chain)
 {
+       struct nf_hook_ops *ops;
+       int ret;
+
        if (table->flags & NFT_TABLE_F_DORMANT ||
            !nft_is_base_chain(chain))
                return 0;
 
-       return nf_register_net_hook(net, &nft_base_chain(chain)->ops);
+       ops = &nft_base_chain(chain)->ops;
+       ret = nf_register_net_hook(net, ops);
+       if (ret == -EBUSY && nf_tables_allow_nat_conflict(net, ops)) {
+               ops->nat_hook = false;
+               ret = nf_register_net_hook(net, ops);
+               ops->nat_hook = true;
+       }
+
+       return ret;
 }
 
 static void nf_tables_unregister_hook(struct net *net,
@@ -1226,8 +1288,6 @@ static void nf_tables_chain_destroy(struct nft_chain *chain)
                free_percpu(basechain->stats);
                if (basechain->stats)
                        static_branch_dec(&nft_counters_enabled);
-               if (basechain->ops.dev != NULL)
-                       dev_put(basechain->ops.dev);
                kfree(chain->name);
                kfree(basechain);
        } else {
@@ -1294,7 +1354,7 @@ static int nft_chain_parse_hook(struct net *net,
                }
 
                nla_strlcpy(ifname, ha[NFTA_HOOK_DEV], IFNAMSIZ);
-               dev = dev_get_by_name(net, ifname);
+               dev = __dev_get_by_name(net, ifname);
                if (!dev) {
                        module_put(type->owner);
                        return -ENOENT;
@@ -1311,8 +1371,6 @@ static int nft_chain_parse_hook(struct net *net,
 static void nft_chain_release_hook(struct nft_chain_hook *hook)
 {
        module_put(hook->type->owner);
-       if (hook->dev != NULL)
-               dev_put(hook->dev);
 }
 
 static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
@@ -1911,6 +1969,7 @@ static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
        [NFTA_RULE_POSITION]    = { .type = NLA_U64 },
        [NFTA_RULE_USERDATA]    = { .type = NLA_BINARY,
                                    .len = NFT_USERDATA_MAXLEN },
+       [NFTA_RULE_ID]          = { .type = NLA_U32 },
 };
 
 static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
@@ -2446,6 +2505,9 @@ EXPORT_SYMBOL_GPL(nft_unregister_set);
 
 static bool nft_set_ops_candidate(const struct nft_set_ops *ops, u32 flags)
 {
+       if ((flags & NFT_SET_EVAL) && !ops->update)
+               return false;
+
        return (flags & ops->features) == (flags & NFT_SET_FEATURES);
 }
 
@@ -2510,7 +2572,7 @@ nft_select_set_ops(const struct nft_ctx *ctx,
                                if (est.space == best.space &&
                                    est.lookup < best.lookup)
                                        break;
-                       } else if (est.size < best.size) {
+                       } else if (est.size < best.size || !bops) {
                                break;
                        }
                        continue;
@@ -3315,6 +3377,8 @@ static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
        [NFTA_SET_ELEM_TIMEOUT]         = { .type = NLA_U64 },
        [NFTA_SET_ELEM_USERDATA]        = { .type = NLA_BINARY,
                                            .len = NFT_USERDATA_MAXLEN },
+       [NFTA_SET_ELEM_EXPR]            = { .type = NLA_NESTED },
+       [NFTA_SET_ELEM_OBJREF]          = { .type = NLA_STRING },
 };
 
 static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
@@ -4864,8 +4928,6 @@ nf_tables_flowtable_lookup_byhandle(const struct nft_table *table,
        return ERR_PTR(-ENOENT);
 }
 
-#define NFT_FLOWTABLE_DEVICE_MAX       8
-
 static int nf_tables_parse_devices(const struct nft_ctx *ctx,
                                   const struct nlattr *attr,
                                   struct net_device *dev_array[], int *len)
@@ -4882,7 +4944,7 @@ static int nf_tables_parse_devices(const struct nft_ctx *ctx,
                }
 
                nla_strlcpy(ifname, tmp, IFNAMSIZ);
-               dev = dev_get_by_name(ctx->net, ifname);
+               dev = __dev_get_by_name(ctx->net, ifname);
                if (!dev) {
                        err = -ENOENT;
                        goto err1;
@@ -4938,13 +5000,11 @@ static int nf_tables_flowtable_parse_hook(const struct nft_ctx *ctx,
        err = nf_tables_parse_devices(ctx, tb[NFTA_FLOWTABLE_HOOK_DEVS],
                                      dev_array, &n);
        if (err < 0)
-               goto err1;
+               return err;
 
        ops = kzalloc(sizeof(struct nf_hook_ops) * n, GFP_KERNEL);
-       if (!ops) {
-               err = -ENOMEM;
-               goto err1;
-       }
+       if (!ops)
+               return -ENOMEM;
 
        flowtable->hooknum      = hooknum;
        flowtable->priority     = priority;
@@ -4958,13 +5018,10 @@ static int nf_tables_flowtable_parse_hook(const struct nft_ctx *ctx,
                flowtable->ops[i].priv          = &flowtable->data.rhashtable;
                flowtable->ops[i].hook          = flowtable->data.type->hook;
                flowtable->ops[i].dev           = dev_array[i];
+               flowtable->dev_name[i]          = kstrdup(dev_array[i]->name,
+                                                         GFP_KERNEL);
        }
 
-       err = 0;
-err1:
-       for (i = 0; i < n; i++)
-               dev_put(dev_array[i]);
-
        return err;
 }
 
@@ -5135,8 +5192,10 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
 err5:
        i = flowtable->ops_len;
 err4:
-       for (k = i - 1; k >= 0; k--)
+       for (k = i - 1; k >= 0; k--) {
+               kfree(flowtable->dev_name[k]);
                nf_unregister_net_hook(net, &flowtable->ops[k]);
+       }
 
        kfree(flowtable->ops);
 err3:
@@ -5226,9 +5285,9 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
                goto nla_put_failure;
 
        for (i = 0; i < flowtable->ops_len; i++) {
-               if (flowtable->ops[i].dev &&
+               if (flowtable->dev_name[i][0] &&
                    nla_put_string(skb, NFTA_DEVICE_NAME,
-                                  flowtable->ops[i].dev->name))
+                                  flowtable->dev_name[i]))
                        goto nla_put_failure;
        }
        nla_nest_end(skb, nest_devs);
@@ -5470,6 +5529,7 @@ static void nft_flowtable_event(unsigned long event, struct net_device *dev,
                        continue;
 
                nf_unregister_net_hook(dev_net(dev), &flowtable->ops[i]);
+               flowtable->dev_name[i][0] = '\0';
                flowtable->ops[i].dev = NULL;
                break;
        }
index d40591f..fc9c6d5 100644 (file)
@@ -674,7 +674,7 @@ static const struct nft_set_ops *
 nft_hash_select_ops(const struct nft_ctx *ctx, const struct nft_set_desc *desc,
                    u32 flags)
 {
-       if (desc->size && !(flags & NFT_SET_TIMEOUT)) {
+       if (desc->size && !(flags & (NFT_SET_EVAL | NFT_SET_TIMEOUT))) {
                switch (desc->klen) {
                case 4:
                        return &nft_hash_fast_ops;
index 07e8478..70c4553 100644 (file)
@@ -1085,6 +1085,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
        if (addr->sa_family != AF_NETLINK)
                return -EINVAL;
 
+       if (alen < sizeof(struct sockaddr_nl))
+               return -EINVAL;
+
        if ((nladdr->nl_groups || nladdr->nl_pid) &&
            !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
                return -EPERM;
index eba6682..efc6bfb 100644 (file)
@@ -135,8 +135,10 @@ static int tcf_dump_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
                        continue;
 
                nest = nla_nest_start(skb, n_i);
-               if (!nest)
+               if (!nest) {
+                       index--;
                        goto nla_put_failure;
+               }
                err = tcf_action_dump_1(skb, p, 0, 0);
                if (err < 0) {
                        index--;
index 7e3fbe9..39c144b 100644 (file)
@@ -373,24 +373,33 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
  */
 static inline bool qdisc_restart(struct Qdisc *q, int *packets)
 {
+       bool more, validate, nolock = q->flags & TCQ_F_NOLOCK;
        spinlock_t *root_lock = NULL;
        struct netdev_queue *txq;
        struct net_device *dev;
        struct sk_buff *skb;
-       bool validate;
 
        /* Dequeue packet */
+       if (nolock && test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
+               return false;
+
        skb = dequeue_skb(q, &validate, packets);
-       if (unlikely(!skb))
+       if (unlikely(!skb)) {
+               if (nolock)
+                       clear_bit(__QDISC_STATE_RUNNING, &q->state);
                return false;
+       }
 
-       if (!(q->flags & TCQ_F_NOLOCK))
+       if (!nolock)
                root_lock = qdisc_lock(q);
 
        dev = qdisc_dev(q);
        txq = skb_get_tx_queue(dev, skb);
 
-       return sch_direct_xmit(skb, q, dev, txq, root_lock, validate);
+       more = sch_direct_xmit(skb, q, dev, txq, root_lock, validate);
+       if (nolock)
+               clear_bit(__QDISC_STATE_RUNNING, &q->state);
+       return more;
 }
 
 void __qdisc_run(struct Qdisc *q)
index 8ac5158..15c2132 100644 (file)
@@ -133,7 +133,7 @@ int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
 
        /* receive the complete CLC message */
        memset(&msg, 0, sizeof(struct msghdr));
-       iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &vec, 1, buflen);
+       iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &vec, 1, datlen);
        krflags = MSG_WAITALL;
        smc->clcsock->sk->sk_rcvtimeo = CLC_WAIT_TIME;
        len = sock_recvmsg(smc->clcsock, &msg, krflags);
index 1fdab5c..b9283ce 100644 (file)
@@ -60,7 +60,7 @@ static void strp_abort_strp(struct strparser *strp, int err)
                struct sock *sk = strp->sk;
 
                /* Report an error on the lower socket */
-               sk->sk_err = err;
+               sk->sk_err = -err;
                sk->sk_error_report(sk);
        }
 }
@@ -458,7 +458,7 @@ static void strp_msg_timeout(struct work_struct *w)
        /* Message assembly timed out */
        STRP_STATS_INCR(strp->stats.msg_timeouts);
        strp->cb.lock(strp);
-       strp->cb.abort_parser(strp, ETIMEDOUT);
+       strp->cb.abort_parser(strp, -ETIMEDOUT);
        strp->cb.unlock(strp);
 }
 
index 1472c08..8178810 100644 (file)
@@ -26,6 +26,12 @@ struct xfrm_trans_tasklet {
 };
 
 struct xfrm_trans_cb {
+       union {
+               struct inet_skb_parm    h4;
+#if IS_ENABLED(CONFIG_IPV6)
+               struct inet6_skb_parm   h6;
+#endif
+       } header;
        int (*finish)(struct net *net, struct sock *sk, struct sk_buff *skb);
 };
 
index 2346867..89b178a 100644 (file)
@@ -285,8 +285,9 @@ void xfrm_local_error(struct sk_buff *skb, int mtu)
                return;
 
        afinfo = xfrm_state_get_afinfo(proto);
-       if (afinfo)
+       if (afinfo) {
                afinfo->local_error(skb, mtu);
-       rcu_read_unlock();
+               rcu_read_unlock();
+       }
 }
 EXPORT_SYMBOL_GPL(xfrm_local_error);
index 513da1a..d67830e 100755 (executable)
@@ -84,6 +84,13 @@ while read sympath; do
        depfile="include/config/ksym/${sympath}.h"
        mkdir -p "$(dirname "$depfile")"
        touch "$depfile"
+       # Filesystems with coarse time precision may create timestamps
+       # equal to the one from a file that was very recently built and that
+       # needs to be rebuild. Let's guard against that by making sure our
+       # dep files are always newer than the first file we created here.
+       while [ ! "$depfile" -nt "$new_ksyms_file" ]; do
+               touch "$depfile"
+       done
        echo $((count += 1))
 done | tail -1 )
 changed=${changed:-0}
index b4f0f2b..13fabb1 100755 (executable)
@@ -313,7 +313,7 @@ fi
 
 # Build kernel header package
 (cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles"
-(cd $srctree; find arch/*/include include scripts -type f) >> "$objtree/debian/hdrsrcfiles"
+(cd $srctree; find arch/*/include include scripts -type f -o -type l) >> "$objtree/debian/hdrsrcfiles"
 (cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles"
 (cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles"
 if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then
index 280027f..61427c6 100755 (executable)
@@ -98,7 +98,7 @@ $M    make %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} KBUILD_SRC= modules_instal
 $S$M   rm -f %{buildroot}/lib/modules/$KERNELRELEASE/build
 $S$M   rm -f %{buildroot}/lib/modules/$KERNELRELEASE/source
 $S$M   mkdir -p %{buildroot}/usr/src/kernels/$KERNELRELEASE
-$S$M   tar cf - . $EXCLUDES | tar xf - -C %{buildroot}/usr/src/kernels/$KERNELRELEASE
+$S$M   tar cf - $EXCLUDES . | tar xf - -C %{buildroot}/usr/src/kernels/$KERNELRELEASE
 $S$M   cd %{buildroot}/lib/modules/$KERNELRELEASE
 $S$M   ln -sf /usr/src/kernels/$KERNELRELEASE build
 $S$M   ln -sf /usr/src/kernels/$KERNELRELEASE source
index 02298c9..4414050 100644 (file)
@@ -1326,7 +1326,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha
 static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const char __user *buf, size_t bytes)
 {
        size_t xfer = 0;
-       ssize_t tmp;
+       ssize_t tmp = 0;
        struct snd_pcm_runtime *runtime = substream->runtime;
 
        if (atomic_read(&substream->mmap_count))
@@ -1433,7 +1433,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf,
 static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __user *buf, size_t bytes)
 {
        size_t xfer = 0;
-       ssize_t tmp;
+       ssize_t tmp = 0;
        struct snd_pcm_runtime *runtime = substream->runtime;
 
        if (atomic_read(&substream->mmap_count))
index 77ba50d..d18b398 100644 (file)
@@ -3422,7 +3422,7 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
                                         area,
                                         substream->runtime->dma_area,
                                         substream->runtime->dma_addr,
-                                        area->vm_end - area->vm_start);
+                                        substream->runtime->dma_bytes);
 #endif /* CONFIG_X86 */
        /* mmap with fault handler */
        area->vm_ops = &snd_pcm_vm_ops_data_fault;
index ea8f3de..794224e 100644 (file)
@@ -1171,6 +1171,7 @@ static bool is_teac_dsd_dac(unsigned int id)
        switch (id) {
        case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */
        case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */
+       case USB_ID(0x0644, 0x804a): /* TEAC UD-301 */
                return true;
        }
        return false;
index f95fa67..f509c86 100644 (file)
@@ -428,7 +428,7 @@ static int show_map_close_json(int fd, struct bpf_map_info *info)
                jsonw_string_field(json_wtr, "name", info->name);
 
        jsonw_name(json_wtr, "flags");
-       jsonw_printf(json_wtr, "%#x", info->map_flags);
+       jsonw_printf(json_wtr, "%d", info->map_flags);
 
        print_dev_json(info->ifindex, info->netns_dev, info->netns_ino);
 
index 92b6a2c..5409f6f 100644 (file)
@@ -1386,6 +1386,17 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state)
                                state->vals[op->dest.reg].offset = -state->stack_size;
                        }
 
+                       else if (op->src.reg == CFI_BP && op->dest.reg == CFI_SP &&
+                                cfa->base == CFI_BP) {
+
+                               /*
+                                * mov %rbp, %rsp
+                                *
+                                * Restore the original stack pointer (Clang).
+                                */
+                               state->stack_size = -state->regs[CFI_BP].offset;
+                       }
+
                        else if (op->dest.reg == cfa->base) {
 
                                /* mov %reg, %rsp */
index 1ae1c5a..6f22238 100644 (file)
@@ -183,8 +183,10 @@ static void test_ptrace_syscall_restart(void)
                if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0)
                        err(1, "PTRACE_TRACEME");
 
+               pid_t pid = getpid(), tid = syscall(SYS_gettid);
+
                printf("\tChild will make one syscall\n");
-               raise(SIGSTOP);
+               syscall(SYS_tgkill, pid, tid, SIGSTOP);
 
                syscall(SYS_gettid, 10, 11, 12, 13, 14, 15);
                _exit(0);
@@ -301,9 +303,11 @@ static void test_restart_under_ptrace(void)
                if (ptrace(PTRACE_TRACEME, 0, 0, 0) != 0)
                        err(1, "PTRACE_TRACEME");
 
+               pid_t pid = getpid(), tid = syscall(SYS_gettid);
+
                printf("\tChild will take a nap until signaled\n");
                setsigign(SIGUSR1, SA_RESTART);
-               raise(SIGSTOP);
+               syscall(SYS_tgkill, pid, tid, SIGSTOP);
 
                syscall(SYS_pause, 0, 0, 0, 0, 0, 0);
                _exit(0);