From 1516616c2d55e31273ef14cca0258b1129659579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Pe=C4=8Dovnik?= Date: Mon, 23 Mar 2020 00:41:45 +0100 Subject: [PATCH] Rockchip and Odroid XU4 upstream fixes (#1855) --- config/kernel/linux-odroidxu4-current.config | 3 +- config/kernel/linux-rockchip64-current.config | 14 +- config/kernel/linux-rockchip64-dev.config | 39 +- .../03-patch-5.4.23-24.patch | 8611 +++++++++++++++++ .../03-patch-5.4.24-25.patch | 6231 ++++++++++++ .../03-patch-5.4.25-26.patch | 4156 ++++++++ .../03-patch-5.4.26-27.patch | 1989 ++++ patch/kernel/odroidxu4-current/overlay.patch | 4 +- ...ease_CPU_frequency_during_early_boot.patch | 113 + ...ease_CPU_frequency_during_early_boot.patch | 113 + 10 files changed, 21256 insertions(+), 17 deletions(-) create mode 100644 patch/kernel/odroidxu4-current/03-patch-5.4.23-24.patch create mode 100644 patch/kernel/odroidxu4-current/03-patch-5.4.24-25.patch create mode 100644 patch/kernel/odroidxu4-current/03-patch-5.4.25-26.patch create mode 100644 patch/kernel/odroidxu4-current/03-patch-5.4.26-27.patch create mode 100644 patch/kernel/rockchip64-current/board-rk3399-increase_CPU_frequency_during_early_boot.patch create mode 100644 patch/kernel/rockchip64-dev/board-rk3399-increase_CPU_frequency_during_early_boot.patch diff --git a/config/kernel/linux-odroidxu4-current.config b/config/kernel/linux-odroidxu4-current.config index 7b38a38164..a54a9413ac 100644 --- a/config/kernel/linux-odroidxu4-current.config +++ b/config/kernel/linux-odroidxu4-current.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 5.4.23 Kernel Configuration +# Linux/arm 5.4.27 Kernel Configuration # # @@ -21,7 +21,6 @@ CONFIG_BUILDTIME_EXTABLE_SORT=y # CONFIG_INIT_ENV_ARG_LIMIT=32 # CONFIG_COMPILE_TEST is not set -# CONFIG_HEADER_TEST is not set CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_BUILD_SALT="" diff --git a/config/kernel/linux-rockchip64-current.config b/config/kernel/linux-rockchip64-current.config index 7823093912..c9b60bb19f 100644 --- a/config/kernel/linux-rockchip64-current.config +++ b/config/kernel/linux-rockchip64-current.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.4.24 Kernel Configuration +# Linux/arm64 5.4.27 Kernel Configuration # # @@ -2678,7 +2678,6 @@ CONFIG_WLCORE=m # CONFIG_WLCORE_SPI is not set CONFIG_WLCORE_SDIO=m CONFIG_WILINK_PLATFORM_DATA=y -CONFIG_RTL8723DS=m CONFIG_RTL8822BU=m CONFIG_RTL8188EU=m CONFIG_RTL8821CU=m @@ -4693,7 +4692,8 @@ CONFIG_SND_PCM_ELD=y CONFIG_SND_PCM_IEC958=y CONFIG_SND_DMAENGINE_PCM=y CONFIG_SND_HWDEP=m -CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQ_DEVICE=y +CONFIG_SND_RAWMIDI=y CONFIG_SND_JACK=y CONFIG_SND_JACK_INPUT_DEV=y # CONFIG_SND_OSSEMUL is not set @@ -4707,9 +4707,15 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_DEBUG is not set CONFIG_SND_VMASTER=y CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_MIDI_EVENT=y +CONFIG_SND_SEQ_MIDI=y +CONFIG_SND_SEQ_VIRMIDI=m +CONFIG_SND_MPU401_UART=y CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=y CONFIG_SND_ALOOP=y +CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=y CONFIG_SND_SERIAL_U16550=y CONFIG_SND_MPU401=y @@ -6702,7 +6708,7 @@ CONFIG_QUOTA=y # CONFIG_QUOTA_NETLINK_INTERFACE is not set CONFIG_PRINT_QUOTA_WARNING=y # CONFIG_QUOTA_DEBUG is not set -CONFIG_QUOTA_TREE=y +CONFIG_QUOTA_TREE=m CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m CONFIG_QUOTACTL=y diff --git a/config/kernel/linux-rockchip64-dev.config b/config/kernel/linux-rockchip64-dev.config index b52e830955..c5c0c631ee 100644 --- a/config/kernel/linux-rockchip64-dev.config +++ b/config/kernel/linux-rockchip64-dev.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.5.2 Kernel Configuration +# Linux/arm64 5.5.11 Kernel Configuration # # @@ -853,8 +853,6 @@ CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=m CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y -CONFIG_WIREGUARD=m -# CONFIG_WIREGUARD_DEBUG is not set CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_FIB_TRIE_STATS=y @@ -1470,20 +1468,30 @@ CONFIG_BT_LEDS=y # # Bluetooth device drivers # +CONFIG_BT_BCM=m +CONFIG_BT_QCA=m # CONFIG_BT_HCIBTUSB is not set # CONFIG_BT_HCIBTSDIO is not set CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_SERDEV=y CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_NOKIA=m # CONFIG_BT_HCIUART_BCSP is not set # CONFIG_BT_HCIUART_ATH3K is not set +# CONFIG_BT_HCIUART_LL is not set +CONFIG_BT_HCIUART_3WIRE=y # CONFIG_BT_HCIUART_INTEL is not set +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_QCA=y # CONFIG_BT_HCIUART_AG6XX is not set +CONFIG_BT_HCIUART_MRVL=y # CONFIG_BT_HCIBCM203X is not set # CONFIG_BT_HCIBPA10X is not set # CONFIG_BT_HCIBFUSB is not set # CONFIG_BT_HCIVHCI is not set # CONFIG_BT_MRVL is not set CONFIG_BT_MTKSDIO=m +CONFIG_BT_MTKUART=m # end of Bluetooth device drivers # CONFIG_AF_RXRPC is not set @@ -1505,10 +1513,6 @@ CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set CONFIG_CFG80211_CRDA_SUPPORT=y # CONFIG_CFG80211_WEXT is not set -CONFIG_LIB80211=m -CONFIG_LIB80211_CRYPT_WEP=m -CONFIG_LIB80211_CRYPT_CCMP=m -# CONFIG_LIB80211_DEBUG is not set CONFIG_MAC80211=m CONFIG_MAC80211_HAS_RC=y CONFIG_MAC80211_RC_MINSTREL=y @@ -2338,7 +2342,9 @@ CONFIG_NET_VENDOR_QLOGIC=y # CONFIG_NETXEN_NIC is not set # CONFIG_QED is not set CONFIG_NET_VENDOR_QUALCOMM=y +CONFIG_QCA7000=m # CONFIG_QCA7000_SPI is not set +CONFIG_QCA7000_UART=m CONFIG_QCOM_EMAC=m # CONFIG_RMNET is not set CONFIG_NET_VENDOR_RDC=y @@ -2626,6 +2632,7 @@ CONFIG_RT2X00_LIB_USB=m CONFIG_RT2X00_LIB=m CONFIG_RT2X00_LIB_FIRMWARE=y CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y # CONFIG_RT2X00_DEBUG is not set CONFIG_WLAN_VENDOR_REALTEK=y # CONFIG_RTL8180 is not set @@ -2662,10 +2669,11 @@ CONFIG_WLCORE=m # CONFIG_WLCORE_SPI is not set CONFIG_WLCORE_SDIO=m CONFIG_WILINK_PLATFORM_DATA=y +# CONFIG_RTL8723DS is not set CONFIG_RTL8822BU=m CONFIG_RTL8188EU=m CONFIG_RTL8821CU=m -CONFIG_RTL8812AU=m +CONFIG_88XXAU=m CONFIG_WLAN_VENDOR_ZYDAS=y # CONFIG_USB_ZD1201 is not set # CONFIG_ZD1211RW is not set @@ -2888,6 +2896,7 @@ CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set +CONFIG_INPUT_RAVE_SP_PWRBUTTON=m # CONFIG_RMI4_CORE is not set # @@ -3534,6 +3543,7 @@ CONFIG_BD70528_WATCHDOG=m # CONFIG_GPIO_WATCHDOG is not set # CONFIG_XILINX_WATCHDOG is not set # CONFIG_ZIIRAVE_WATCHDOG is not set +CONFIG_RAVE_SP_WATCHDOG=m # CONFIG_ARM_SP805_WATCHDOG is not set # CONFIG_ARM_SBSA_WATCHDOG is not set # CONFIG_CADENCE_WATCHDOG is not set @@ -3665,6 +3675,7 @@ CONFIG_MFD_ROHM_BD70528=m # CONFIG_MFD_STPMIC1 is not set CONFIG_MFD_STMFX=m CONFIG_MFD_VEXPRESS_SYSREG=y +CONFIG_RAVE_SP_CORE=m # end of Multifunction device drivers CONFIG_REGULATOR=y @@ -4648,6 +4659,7 @@ CONFIG_BACKLIGHT_LP855X=y # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_BD6107 is not set # CONFIG_BACKLIGHT_ARCXCNN is not set +CONFIG_BACKLIGHT_RAVE_SP=m # end of Backlight & LCD device support CONFIG_VIDEOMODE_HELPERS=y @@ -4679,7 +4691,8 @@ CONFIG_SND_PCM_ELD=y CONFIG_SND_PCM_IEC958=y CONFIG_SND_DMAENGINE_PCM=y CONFIG_SND_HWDEP=m -CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQ_DEVICE=y +CONFIG_SND_RAWMIDI=y CONFIG_SND_JACK=y CONFIG_SND_JACK_INPUT_DEV=y # CONFIG_SND_OSSEMUL is not set @@ -4693,9 +4706,15 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_DEBUG is not set CONFIG_SND_VMASTER=y CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQ_MIDI_EVENT=y +CONFIG_SND_SEQ_MIDI=y +CONFIG_SND_SEQ_VIRMIDI=m +CONFIG_SND_MPU401_UART=y CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=y CONFIG_SND_ALOOP=y +CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=y CONFIG_SND_SERIAL_U16550=y CONFIG_SND_MPU401=y @@ -6206,6 +6225,7 @@ CONFIG_XILINX_XADC=m # CONFIG_BME680 is not set # CONFIG_CCS811 is not set # CONFIG_IAQCORE is not set +CONFIG_PMS7003=m CONFIG_SENSIRION_SGP30=m CONFIG_SPS30=m # CONFIG_VZ89X is not set @@ -6595,6 +6615,7 @@ CONFIG_NVMEM=y CONFIG_NVMEM_SYSFS=y CONFIG_ROCKCHIP_EFUSE=y CONFIG_ROCKCHIP_OTP=y +CONFIG_RAVE_SP_EEPROM=m # # HW tracing support diff --git a/patch/kernel/odroidxu4-current/03-patch-5.4.23-24.patch b/patch/kernel/odroidxu4-current/03-patch-5.4.23-24.patch new file mode 100644 index 0000000000..6757dd3487 --- /dev/null +++ b/patch/kernel/odroidxu4-current/03-patch-5.4.23-24.patch @@ -0,0 +1,8611 @@ +diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst +index b89c88168d6a..b9b50553bfc5 100644 +--- a/Documentation/kbuild/makefiles.rst ++++ b/Documentation/kbuild/makefiles.rst +@@ -1115,23 +1115,6 @@ When kbuild executes, the following steps are followed (roughly): + In this example, extra-y is used to list object files that + shall be built, but shall not be linked as part of built-in.a. + +- header-test-y +- +- header-test-y specifies headers (`*.h`) in the current directory that +- should be compile tested to ensure they are self-contained, +- i.e. compilable as standalone units. If CONFIG_HEADER_TEST is enabled, +- this builds them as part of extra-y. +- +- header-test-pattern-y +- +- This works as a weaker version of header-test-y, and accepts wildcard +- patterns. The typical usage is:: +- +- header-test-pattern-y += *.h +- +- This specifies all the files that matches to `*.h` in the current +- directory, but the files in 'header-test-' are excluded. +- + 6.7 Commands useful for building a boot image + --------------------------------------------- + +diff --git a/Documentation/networking/nf_flowtable.txt b/Documentation/networking/nf_flowtable.txt +index ca2136c76042..0bf32d1121be 100644 +--- a/Documentation/networking/nf_flowtable.txt ++++ b/Documentation/networking/nf_flowtable.txt +@@ -76,7 +76,7 @@ flowtable and add one rule to your forward chain. + + table inet x { + flowtable f { +- hook ingress priority 0 devices = { eth0, eth1 }; ++ hook ingress priority 0; devices = { eth0, eth1 }; + } + chain y { + type filter hook forward priority 0; policy accept; +diff --git a/Makefile b/Makefile +index af5e90075514..c32c78cf2fe5 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 23 ++SUBLEVEL = 24 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +@@ -618,7 +618,6 @@ ifeq ($(KBUILD_EXTMOD),) + init-y := init/ + drivers-y := drivers/ sound/ + drivers-$(CONFIG_SAMPLES) += samples/ +-drivers-$(CONFIG_KERNEL_HEADER_TEST) += include/ + net-y := net/ + libs-y := lib/ + core-y := usr/ +@@ -1196,19 +1195,15 @@ headers: $(version_h) scripts_unifdef uapi-asm-generic archheaders archscripts + $(Q)$(MAKE) $(hdr-inst)=include/uapi + $(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi + ++# Deprecated. It is no-op now. + PHONY += headers_check +-headers_check: headers +- $(Q)$(MAKE) $(hdr-inst)=include/uapi HDRCHECK=1 +- $(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi HDRCHECK=1 ++headers_check: ++ @: + + ifdef CONFIG_HEADERS_INSTALL + prepare: headers + endif + +-ifdef CONFIG_HEADERS_CHECK +-all: headers_check +-endif +- + PHONY += scripts_unifdef + scripts_unifdef: scripts_basic + $(Q)$(MAKE) $(build)=scripts scripts/unifdef +@@ -1476,7 +1471,6 @@ help: + @echo ' versioncheck - Sanity check on version.h usage' + @echo ' includecheck - Check for duplicate included header files' + @echo ' export_report - List the usages of all exported symbols' +- @echo ' headers_check - Sanity check on exported headers' + @echo ' headerdep - Detect inclusion cycles in headers' + @echo ' coccicheck - Check with Coccinelle' + @echo '' +@@ -1641,6 +1635,50 @@ help: + PHONY += prepare + endif # KBUILD_EXTMOD + ++# Single targets ++# --------------------------------------------------------------------------- ++# To build individual files in subdirectories, you can do like this: ++# ++# make foo/bar/baz.s ++# ++# The supported suffixes for single-target are listed in 'single-targets' ++# ++# To build only under specific subdirectories, you can do like this: ++# ++# make foo/bar/baz/ ++ ++ifdef single-build ++ ++# .ko is special because modpost is needed ++single-ko := $(sort $(filter %.ko, $(MAKECMDGOALS))) ++single-no-ko := $(sort $(patsubst %.ko,%.mod, $(MAKECMDGOALS))) ++ ++$(single-ko): single_modpost ++ @: ++$(single-no-ko): descend ++ @: ++ ++ifeq ($(KBUILD_EXTMOD),) ++# For the single build of in-tree modules, use a temporary file to avoid ++# the situation of modules_install installing an invalid modules.order. ++MODORDER := .modules.tmp ++endif ++ ++PHONY += single_modpost ++single_modpost: $(single-no-ko) ++ $(Q){ $(foreach m, $(single-ko), echo $(extmod-prefix)$m;) } > $(MODORDER) ++ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost ++ ++KBUILD_MODULES := 1 ++ ++export KBUILD_SINGLE_TARGETS := $(addprefix $(extmod-prefix), $(single-no-ko)) ++ ++# trim unrelated directories ++build-dirs := $(foreach d, $(build-dirs), \ ++ $(if $(filter $(d)/%, $(KBUILD_SINGLE_TARGETS)), $(d))) ++ ++endif ++ + # Handle descending into subdirectories listed in $(build-dirs) + # Preset locale variables to speed up the build process. Limit locale + # tweaks to this spot to avoid wrong language settings when running +@@ -1649,7 +1687,9 @@ endif # KBUILD_EXTMOD + PHONY += descend $(build-dirs) + descend: $(build-dirs) + $(build-dirs): prepare +- $(Q)$(MAKE) $(build)=$@ single-build=$(single-build) need-builtin=1 need-modorder=1 ++ $(Q)$(MAKE) $(build)=$@ \ ++ single-build=$(if $(filter-out $@/, $(single-no-ko)),1) \ ++ need-builtin=1 need-modorder=1 + + clean-dirs := $(addprefix _clean_, $(clean-dirs)) + PHONY += $(clean-dirs) clean +@@ -1753,50 +1793,6 @@ tools/%: FORCE + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ $* + +-# Single targets +-# --------------------------------------------------------------------------- +-# To build individual files in subdirectories, you can do like this: +-# +-# make foo/bar/baz.s +-# +-# The supported suffixes for single-target are listed in 'single-targets' +-# +-# To build only under specific subdirectories, you can do like this: +-# +-# make foo/bar/baz/ +- +-ifdef single-build +- +-single-all := $(filter $(single-targets), $(MAKECMDGOALS)) +- +-# .ko is special because modpost is needed +-single-ko := $(sort $(filter %.ko, $(single-all))) +-single-no-ko := $(sort $(patsubst %.ko,%.mod, $(single-all))) +- +-$(single-ko): single_modpost +- @: +-$(single-no-ko): descend +- @: +- +-ifeq ($(KBUILD_EXTMOD),) +-# For the single build of in-tree modules, use a temporary file to avoid +-# the situation of modules_install installing an invalid modules.order. +-MODORDER := .modules.tmp +-endif +- +-PHONY += single_modpost +-single_modpost: $(single-no-ko) +- $(Q){ $(foreach m, $(single-ko), echo $(extmod-prefix)$m;) } > $(MODORDER) +- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost +- +-KBUILD_MODULES := 1 +- +-export KBUILD_SINGLE_TARGETS := $(addprefix $(extmod-prefix), $(single-no-ko)) +- +-single-build = $(if $(filter-out $@/, $(single-no-ko)),1) +- +-endif +- + # FIXME Should go into a make.lib or something + # =========================================================================== + +diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi +index 60e11045ad76..d051f080e52e 100644 +--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi ++++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi +@@ -46,7 +46,7 @@ + /* DAC */ + format = "i2s"; + mclk-fs = <256>; +- frame-inversion = <1>; ++ frame-inversion; + cpu { + sound-dai = <&sti_uni_player2>; + }; +diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c +index 6176b9acba95..d0d832ab3d3b 100644 +--- a/arch/mips/kernel/vpe.c ++++ b/arch/mips/kernel/vpe.c +@@ -134,7 +134,7 @@ void release_vpe(struct vpe *v) + { + list_del(&v->list); + if (v->load_addr) +- release_progmem(v); ++ release_progmem(v->load_addr); + kfree(v); + } + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index fcef678c3423..c531e3f3269e 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4746,6 +4746,7 @@ __init int intel_pmu_init(void) + break; + + case INTEL_FAM6_ATOM_TREMONT_D: ++ case INTEL_FAM6_ATOM_TREMONT: + x86_pmu.late_ack = true; + memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, + sizeof(hw_cache_event_ids)); +diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c +index e1daf4151e11..4814c964692c 100644 +--- a/arch/x86/events/intel/cstate.c ++++ b/arch/x86/events/intel/cstate.c +@@ -40,17 +40,18 @@ + * Model specific counters: + * MSR_CORE_C1_RES: CORE C1 Residency Counter + * perf code: 0x00 +- * Available model: SLM,AMT,GLM,CNL ++ * Available model: SLM,AMT,GLM,CNL,TNT + * Scope: Core (each processor core has a MSR) + * MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter + * perf code: 0x01 + * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,GLM, +- * CNL,KBL,CML ++ * CNL,KBL,CML,TNT + * Scope: Core + * MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter + * perf code: 0x02 + * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW, +- * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL ++ * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL, ++ * TNT + * Scope: Core + * MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter + * perf code: 0x03 +@@ -60,17 +61,18 @@ + * MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter. + * perf code: 0x00 + * Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL, +- * KBL,CML,ICL,TGL ++ * KBL,CML,ICL,TGL,TNT + * Scope: Package (physical package) + * MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter. + * perf code: 0x01 + * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL, +- * GLM,CNL,KBL,CML,ICL,TGL ++ * GLM,CNL,KBL,CML,ICL,TGL,TNT + * Scope: Package (physical package) + * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter. + * perf code: 0x02 +- * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW +- * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL ++ * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW, ++ * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL, ++ * TNT + * Scope: Package (physical package) + * MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter. + * perf code: 0x03 +@@ -87,7 +89,8 @@ + * Scope: Package (physical package) + * MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter. + * perf code: 0x06 +- * Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL ++ * Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL, ++ * TNT + * Scope: Package (physical package) + * + */ +@@ -640,8 +643,9 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { + + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_D, glm_cstates), +- + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates), ++ X86_CSTATES_MODEL(INTEL_FAM6_ATOM_TREMONT_D, glm_cstates), ++ X86_CSTATES_MODEL(INTEL_FAM6_ATOM_TREMONT, glm_cstates), + + X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_L, icl_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE, icl_cstates), +diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c +index 6f86650b3f77..a949f6f55991 100644 +--- a/arch/x86/events/msr.c ++++ b/arch/x86/events/msr.c +@@ -75,8 +75,9 @@ static bool test_intel(int idx, void *data) + + case INTEL_FAM6_ATOM_GOLDMONT: + case INTEL_FAM6_ATOM_GOLDMONT_D: +- + case INTEL_FAM6_ATOM_GOLDMONT_PLUS: ++ case INTEL_FAM6_ATOM_TREMONT_D: ++ case INTEL_FAM6_ATOM_TREMONT: + + case INTEL_FAM6_XEON_PHI_KNL: + case INTEL_FAM6_XEON_PHI_KNM: +diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h +index e49b77283924..181c992f448c 100644 +--- a/arch/x86/kernel/cpu/resctrl/internal.h ++++ b/arch/x86/kernel/cpu/resctrl/internal.h +@@ -57,6 +57,7 @@ static inline struct rdt_fs_context *rdt_fc2context(struct fs_context *fc) + } + + DECLARE_STATIC_KEY_FALSE(rdt_enable_key); ++DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key); + + /** + * struct mon_evt - Entry in the event list of a resource +diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c +index 397206f23d14..773124b0e18a 100644 +--- a/arch/x86/kernel/cpu/resctrl/monitor.c ++++ b/arch/x86/kernel/cpu/resctrl/monitor.c +@@ -514,7 +514,7 @@ void mbm_handle_overflow(struct work_struct *work) + + mutex_lock(&rdtgroup_mutex); + +- if (!static_branch_likely(&rdt_enable_key)) ++ if (!static_branch_likely(&rdt_mon_enable_key)) + goto out_unlock; + + d = get_domain_from_cpu(cpu, &rdt_resources_all[RDT_RESOURCE_L3]); +@@ -543,7 +543,7 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom, unsigned long delay_ms) + unsigned long delay = msecs_to_jiffies(delay_ms); + int cpu; + +- if (!static_branch_likely(&rdt_enable_key)) ++ if (!static_branch_likely(&rdt_mon_enable_key)) + return; + cpu = cpumask_any(&dom->cpu_mask); + dom->mbm_work_cpu = cpu; +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index 207030db3481..07459120a222 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -1298,6 +1298,47 @@ static void shrink_ple_window(struct kvm_vcpu *vcpu) + } + } + ++/* ++ * The default MMIO mask is a single bit (excluding the present bit), ++ * which could conflict with the memory encryption bit. Check for ++ * memory encryption support and override the default MMIO mask if ++ * memory encryption is enabled. ++ */ ++static __init void svm_adjust_mmio_mask(void) ++{ ++ unsigned int enc_bit, mask_bit; ++ u64 msr, mask; ++ ++ /* If there is no memory encryption support, use existing mask */ ++ if (cpuid_eax(0x80000000) < 0x8000001f) ++ return; ++ ++ /* If memory encryption is not enabled, use existing mask */ ++ rdmsrl(MSR_K8_SYSCFG, msr); ++ if (!(msr & MSR_K8_SYSCFG_MEM_ENCRYPT)) ++ return; ++ ++ enc_bit = cpuid_ebx(0x8000001f) & 0x3f; ++ mask_bit = boot_cpu_data.x86_phys_bits; ++ ++ /* Increment the mask bit if it is the same as the encryption bit */ ++ if (enc_bit == mask_bit) ++ mask_bit++; ++ ++ /* ++ * If the mask bit location is below 52, then some bits above the ++ * physical addressing limit will always be reserved, so use the ++ * rsvd_bits() function to generate the mask. This mask, along with ++ * the present bit, will be used to generate a page fault with ++ * PFER.RSV = 1. ++ * ++ * If the mask bit location is 52 (or above), then clear the mask. ++ */ ++ mask = (mask_bit < 52) ? rsvd_bits(mask_bit, 51) | PT_PRESENT_MASK : 0; ++ ++ kvm_mmu_set_mmio_spte_mask(mask, mask, PT_WRITABLE_MASK | PT_USER_MASK); ++} ++ + static __init int svm_hardware_setup(void) + { + int cpu; +@@ -1352,6 +1393,8 @@ static __init int svm_hardware_setup(void) + } + } + ++ svm_adjust_mmio_mask(); ++ + for_each_possible_cpu(cpu) { + r = svm_cpu_init(cpu); + if (r) +diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c +index 802ef7177d53..e1d8062ef12e 100644 +--- a/arch/x86/kvm/vmx/nested.c ++++ b/arch/x86/kvm/vmx/nested.c +@@ -4609,32 +4609,28 @@ static int handle_vmread(struct kvm_vcpu *vcpu) + { + unsigned long field; + u64 field_value; ++ struct vcpu_vmx *vmx = to_vmx(vcpu); + unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); + int len; + gva_t gva = 0; +- struct vmcs12 *vmcs12; ++ struct vmcs12 *vmcs12 = is_guest_mode(vcpu) ? get_shadow_vmcs12(vcpu) ++ : get_vmcs12(vcpu); + struct x86_exception e; + short offset; + + if (!nested_vmx_check_permission(vcpu)) + return 1; + +- if (to_vmx(vcpu)->nested.current_vmptr == -1ull) ++ /* ++ * In VMX non-root operation, when the VMCS-link pointer is -1ull, ++ * any VMREAD sets the ALU flags for VMfailInvalid. ++ */ ++ if (vmx->nested.current_vmptr == -1ull || ++ (is_guest_mode(vcpu) && ++ get_vmcs12(vcpu)->vmcs_link_pointer == -1ull)) + return nested_vmx_failInvalid(vcpu); + +- if (!is_guest_mode(vcpu)) +- vmcs12 = get_vmcs12(vcpu); +- else { +- /* +- * When vmcs->vmcs_link_pointer is -1ull, any VMREAD +- * to shadowed-field sets the ALU flags for VMfailInvalid. +- */ +- if (get_vmcs12(vcpu)->vmcs_link_pointer == -1ull) +- return nested_vmx_failInvalid(vcpu); +- vmcs12 = get_shadow_vmcs12(vcpu); +- } +- + /* Decode instruction info and find the field to read */ + field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf)); + +@@ -4713,13 +4709,20 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) + */ + u64 field_value = 0; + struct x86_exception e; +- struct vmcs12 *vmcs12; ++ struct vmcs12 *vmcs12 = is_guest_mode(vcpu) ? get_shadow_vmcs12(vcpu) ++ : get_vmcs12(vcpu); + short offset; + + if (!nested_vmx_check_permission(vcpu)) + return 1; + +- if (vmx->nested.current_vmptr == -1ull) ++ /* ++ * In VMX non-root operation, when the VMCS-link pointer is -1ull, ++ * any VMWRITE sets the ALU flags for VMfailInvalid. ++ */ ++ if (vmx->nested.current_vmptr == -1ull || ++ (is_guest_mode(vcpu) && ++ get_vmcs12(vcpu)->vmcs_link_pointer == -1ull)) + return nested_vmx_failInvalid(vcpu); + + if (vmx_instruction_info & (1u << 10)) +@@ -4738,6 +4741,12 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) + + + field = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 28) & 0xf)); ++ ++ offset = vmcs_field_to_offset(field); ++ if (offset < 0) ++ return nested_vmx_failValid(vcpu, ++ VMXERR_UNSUPPORTED_VMCS_COMPONENT); ++ + /* + * If the vCPU supports "VMWRITE to any supported field in the + * VMCS," then the "read-only" fields are actually read/write. +@@ -4747,29 +4756,12 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) + return nested_vmx_failValid(vcpu, + VMXERR_VMWRITE_READ_ONLY_VMCS_COMPONENT); + +- if (!is_guest_mode(vcpu)) { +- vmcs12 = get_vmcs12(vcpu); +- +- /* +- * Ensure vmcs12 is up-to-date before any VMWRITE that dirties +- * vmcs12, else we may crush a field or consume a stale value. +- */ +- if (!is_shadow_field_rw(field)) +- copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12); +- } else { +- /* +- * When vmcs->vmcs_link_pointer is -1ull, any VMWRITE +- * to shadowed-field sets the ALU flags for VMfailInvalid. +- */ +- if (get_vmcs12(vcpu)->vmcs_link_pointer == -1ull) +- return nested_vmx_failInvalid(vcpu); +- vmcs12 = get_shadow_vmcs12(vcpu); +- } +- +- offset = vmcs_field_to_offset(field); +- if (offset < 0) +- return nested_vmx_failValid(vcpu, +- VMXERR_UNSUPPORTED_VMCS_COMPONENT); ++ /* ++ * Ensure vmcs12 is up-to-date before any VMWRITE that dirties ++ * vmcs12, else we may crush a field or consume a stale value. ++ */ ++ if (!is_guest_mode(vcpu) && !is_shadow_field_rw(field)) ++ copy_vmcs02_to_vmcs12_rare(vcpu, vmcs12); + + /* + * Some Intel CPUs intentionally drop the reserved bits of the AR byte +diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c +index 8ebcd9de87a2..8129b6b27c93 100644 +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -7165,6 +7165,7 @@ static int vmx_check_intercept_io(struct kvm_vcpu *vcpu, + else + intercept = nested_vmx_check_io_bitmaps(vcpu, port, size); + ++ /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ + return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE; + } + +@@ -7194,6 +7195,20 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, + case x86_intercept_outs: + return vmx_check_intercept_io(vcpu, info); + ++ case x86_intercept_lgdt: ++ case x86_intercept_lidt: ++ case x86_intercept_lldt: ++ case x86_intercept_ltr: ++ case x86_intercept_sgdt: ++ case x86_intercept_sidt: ++ case x86_intercept_sldt: ++ case x86_intercept_str: ++ if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_DESC)) ++ return X86EMUL_CONTINUE; ++ ++ /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ ++ break; ++ + /* TODO: check more intercepts... */ + default: + break; +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 95180d67d570..c5e15eba8052 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -9192,12 +9192,6 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) + + void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) + { +- vcpu->arch.apf.msr_val = 0; +- +- vcpu_load(vcpu); +- kvm_mmu_unload(vcpu); +- vcpu_put(vcpu); +- + kvm_arch_vcpu_free(vcpu); + } + +diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c +index b5516b04ffc0..d827a4a3e946 100644 +--- a/drivers/acpi/acpi_watchdog.c ++++ b/drivers/acpi/acpi_watchdog.c +@@ -126,12 +126,11 @@ void __init acpi_watchdog_init(void) + gas = &entries[i].register_region; + + res.start = gas->address; ++ res.end = res.start + ACPI_ACCESS_BYTE_WIDTH(gas->access_width) - 1; + if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + res.flags = IORESOURCE_MEM; +- res.end = res.start + ALIGN(gas->access_width, 4) - 1; + } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { + res.flags = IORESOURCE_IO; +- res.end = res.start + gas->access_width - 1; + } else { + pr_warn("Unsupported address space: %u\n", + gas->space_id); +diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig +index 6b331061d34b..47c2bb444ab4 100644 +--- a/drivers/bus/Kconfig ++++ b/drivers/bus/Kconfig +@@ -138,7 +138,6 @@ config TEGRA_ACONNECT + tristate "Tegra ACONNECT Bus Driver" + depends on ARCH_TEGRA_210_SOC + depends on OF && PM +- select PM_CLK + help + Driver for the Tegra ACONNECT bus which is used to interface with + the devices inside the Audio Processing Engine (APE) for Tegra210. +diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c +index 22c6a2e61236..8ac390c2b514 100644 +--- a/drivers/char/ipmi/ipmi_ssif.c ++++ b/drivers/char/ipmi/ipmi_ssif.c +@@ -775,10 +775,14 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, + flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + msg = ssif_info->curr_msg; + if (msg) { ++ if (data) { ++ if (len > IPMI_MAX_MSG_LENGTH) ++ len = IPMI_MAX_MSG_LENGTH; ++ memcpy(msg->rsp, data, len); ++ } else { ++ len = 0; ++ } + msg->rsp_size = len; +- if (msg->rsp_size > IPMI_MAX_MSG_LENGTH) +- msg->rsp_size = IPMI_MAX_MSG_LENGTH; +- memcpy(msg->rsp, data, msg->rsp_size); + ssif_info->curr_msg = NULL; + } + +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index 7679f8a91745..35f8e098e9fa 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -1071,9 +1071,17 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) + pol = policy->last_policy; + } else if (def_gov) { + pol = cpufreq_parse_policy(def_gov->name); +- } else { +- return -ENODATA; ++ /* ++ * In case the default governor is neiter "performance" ++ * nor "powersave", fall back to the initial policy ++ * value set by the driver. ++ */ ++ if (pol == CPUFREQ_POLICY_UNKNOWN) ++ pol = policy->policy; + } ++ if (pol != CPUFREQ_POLICY_PERFORMANCE && ++ pol != CPUFREQ_POLICY_POWERSAVE) ++ return -ENODATA; + } + + return cpufreq_set_policy(policy, gov, pol); +diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c +index 174795ecbd3b..ff81b7cdab71 100644 +--- a/drivers/devfreq/devfreq.c ++++ b/drivers/devfreq/devfreq.c +@@ -613,7 +613,6 @@ struct devfreq *devfreq_add_device(struct device *dev, + { + struct devfreq *devfreq; + struct devfreq_governor *governor; +- static atomic_t devfreq_no = ATOMIC_INIT(-1); + int err = 0; + + if (!dev || !profile || !governor_name) { +@@ -677,8 +676,7 @@ struct devfreq *devfreq_add_device(struct device *dev, + devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev); + atomic_set(&devfreq->suspend_count, 0); + +- dev_set_name(&devfreq->dev, "devfreq%d", +- atomic_inc_return(&devfreq_no)); ++ dev_set_name(&devfreq->dev, "%s", dev_name(dev)); + err = device_register(&devfreq->dev); + if (err) { + mutex_unlock(&devfreq->lock); +diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c +index d8ff63d91b86..a04349c6d17e 100644 +--- a/drivers/edac/skx_common.c ++++ b/drivers/edac/skx_common.c +@@ -235,7 +235,7 @@ int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) + + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, NULL); + if (!pdev) { +- skx_printk(KERN_ERR, "Can't get tolm/tohm\n"); ++ edac_dbg(2, "Can't get tolm/tohm\n"); + return -ENODEV; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index bb9a2771a0f9..05d114a72ca1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -1421,7 +1421,7 @@ amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + + static struct drm_driver kms_driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_ATOMIC | ++ DRIVER_ATOMIC | + DRIVER_GEM | + DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ, + .load = amdgpu_driver_load_kms, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +index aef6c396bd58..8c0ac66d31d0 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +@@ -157,6 +157,7 @@ struct amdgpu_gmc { + uint32_t srbm_soft_reset; + bool prt_warning; + uint64_t stolen_size; ++ uint32_t sdpif_register; + /* apertures */ + u64 shared_aperture_start; + u64 shared_aperture_end; +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +index d7caca042173..da53a55bf955 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +@@ -1382,6 +1382,19 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) + } + } + ++/** ++ * gmc_v9_0_restore_registers - restores regs ++ * ++ * @adev: amdgpu_device pointer ++ * ++ * This restores register values, saved at suspend. ++ */ ++static void gmc_v9_0_restore_registers(struct amdgpu_device *adev) ++{ ++ if (adev->asic_type == CHIP_RAVEN) ++ WREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); ++} ++ + /** + * gmc_v9_0_gart_enable - gart enable + * +@@ -1478,6 +1491,20 @@ static int gmc_v9_0_hw_init(void *handle) + return r; + } + ++/** ++ * gmc_v9_0_save_registers - saves regs ++ * ++ * @adev: amdgpu_device pointer ++ * ++ * This saves potential register values that should be ++ * restored upon resume ++ */ ++static void gmc_v9_0_save_registers(struct amdgpu_device *adev) ++{ ++ if (adev->asic_type == CHIP_RAVEN) ++ adev->gmc.sdpif_register = RREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); ++} ++ + /** + * gmc_v9_0_gart_disable - gart disable + * +@@ -1514,9 +1541,16 @@ static int gmc_v9_0_hw_fini(void *handle) + + static int gmc_v9_0_suspend(void *handle) + { ++ int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +- return gmc_v9_0_hw_fini(adev); ++ r = gmc_v9_0_hw_fini(adev); ++ if (r) ++ return r; ++ ++ gmc_v9_0_save_registers(adev); ++ ++ return 0; + } + + static int gmc_v9_0_resume(void *handle) +@@ -1524,6 +1558,7 @@ static int gmc_v9_0_resume(void *handle) + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + ++ gmc_v9_0_restore_registers(adev); + r = gmc_v9_0_hw_init(adev); + if (r) + return r; +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +index b864869cc7e3..6fa7422c51da 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +@@ -91,6 +91,12 @@ ifdef CONFIG_DRM_AMD_DC_DCN2_1 + ############################################################################### + CLK_MGR_DCN21 = rn_clk_mgr.o rn_clk_mgr_vbios_smu.o + ++# prevent build errors regarding soft-float vs hard-float FP ABI tags ++# this code is currently unused on ppc64, as it applies to Renoir APUs only ++ifdef CONFIG_PPC64 ++CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) ++endif ++ + AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) + + AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) +diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +index 787f94d815f4..dd92f9c295b4 100644 +--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c ++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +@@ -91,6 +91,12 @@ void rn_update_clocks(struct clk_mgr *clk_mgr_base, + rn_vbios_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz); + } + ++ // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow. ++ if (!IS_DIAG_DC(dc->ctx->dce_environment)) { ++ if (new_clocks->dppclk_khz < 100000) ++ new_clocks->dppclk_khz = 100000; ++ } ++ + if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) { + if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz) + dpp_clock_lowered = true; +diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +index c3f9f4185ce8..cf877238fff9 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c ++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +@@ -386,7 +386,7 @@ static bool acquire( + { + enum gpio_result result; + +- if (!is_engine_available(engine)) ++ if ((engine == NULL) || !is_engine_available(engine)) + return false; + + result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +index 937a8ba81160..e933f6a369f9 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +@@ -493,7 +493,6 @@ static void dcn20_plane_atomic_disable(struct dc *dc, struct pipe_ctx *pipe_ctx) + dpp->funcs->dpp_dppclk_control(dpp, false, false); + + hubp->power_gated = true; +- dc->optimized_required = false; /* We're powering off, no need to optimize */ + + dc->hwss.plane_atomic_power_down(dc, + pipe_ctx->plane_res.dpp, +diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +index b0e5e64df212..161bf7caf3ae 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +@@ -57,6 +57,7 @@ + #include "dcn20/dcn20_dccg.h" + #include "dcn21_hubbub.h" + #include "dcn10/dcn10_resource.h" ++#include "dce110/dce110_resource.h" + + #include "dcn20/dcn20_dwb.h" + #include "dcn20/dcn20_mmhubbub.h" +@@ -824,6 +825,7 @@ static const struct dc_debug_options debug_defaults_diags = { + enum dcn20_clk_src_array_id { + DCN20_CLK_SRC_PLL0, + DCN20_CLK_SRC_PLL1, ++ DCN20_CLK_SRC_PLL2, + DCN20_CLK_SRC_TOTAL_DCN21 + }; + +@@ -1492,6 +1494,10 @@ static bool construct( + dcn21_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL1, + &clk_src_regs[1], false); ++ pool->base.clock_sources[DCN20_CLK_SRC_PLL2] = ++ dcn21_clock_source_create(ctx, ctx->dc_bios, ++ CLOCK_SOURCE_COMBO_PHY_PLL2, ++ &clk_src_regs[2], false); + + pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21; + +diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h +index b6f74bf4af02..27bb8c1ab858 100644 +--- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h ++++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h +@@ -7376,6 +7376,8 @@ + #define mmCRTC4_CRTC_DRR_CONTROL 0x0f3e + #define mmCRTC4_CRTC_DRR_CONTROL_BASE_IDX 2 + ++#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0 0x395d ++#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0_BASE_IDX 2 + + // addressBlock: dce_dc_fmt4_dispdec + // base address: 0x2000 +diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug +index 00786a142ff0..41c8e39a73ba 100644 +--- a/drivers/gpu/drm/i915/Kconfig.debug ++++ b/drivers/gpu/drm/i915/Kconfig.debug +@@ -7,7 +7,6 @@ config DRM_I915_WERROR + # We use the dependency on !COMPILE_TEST to not be enabled in + # allmodconfig or allyesconfig configurations + depends on !COMPILE_TEST +- select HEADER_TEST + default n + help + Add -Werror to the build flags for (and only for) i915.ko. +diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c +index 4bfaefdf548d..c0347956f7cf 100644 +--- a/drivers/gpu/drm/i915/gvt/dmabuf.c ++++ b/drivers/gpu/drm/i915/gvt/dmabuf.c +@@ -96,12 +96,12 @@ static void dmabuf_gem_object_free(struct kref *kref) + dmabuf_obj = container_of(pos, + struct intel_vgpu_dmabuf_obj, list); + if (dmabuf_obj == obj) { ++ list_del(pos); + intel_gvt_hypervisor_put_vfio_device(vgpu); + idr_remove(&vgpu->object_idr, + dmabuf_obj->dmabuf_id); + kfree(dmabuf_obj->info); + kfree(dmabuf_obj); +- list_del(pos); + break; + } + } +diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c +index d5a6e4e3d0fd..b232965b45b5 100644 +--- a/drivers/gpu/drm/i915/gvt/vgpu.c ++++ b/drivers/gpu/drm/i915/gvt/vgpu.c +@@ -560,9 +560,9 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, + + intel_vgpu_reset_mmio(vgpu, dmlr); + populate_pvinfo_page(vgpu); +- intel_vgpu_reset_display(vgpu); + + if (dmlr) { ++ intel_vgpu_reset_display(vgpu); + intel_vgpu_reset_cfg_space(vgpu); + /* only reset the failsafe mode when dmlr reset */ + vgpu->failsafe = false; +diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c +index c84f0a8b3f2c..b73fbb65e14b 100644 +--- a/drivers/gpu/drm/msm/msm_drv.c ++++ b/drivers/gpu/drm/msm/msm_drv.c +@@ -441,6 +441,14 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) + if (ret) + goto err_msm_uninit; + ++ if (!dev->dma_parms) { ++ dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), ++ GFP_KERNEL); ++ if (!dev->dma_parms) ++ return -ENOMEM; ++ } ++ dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); ++ + msm_gem_shrinker_init(ddev); + + switch (get_mdp_ver(pdev)) { +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index 4528f4dc0b2d..6128792ab883 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -37,6 +37,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -325,6 +326,7 @@ static int radeon_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { + unsigned long flags = 0; ++ struct drm_device *dev; + int ret; + + if (!ent) +@@ -365,7 +367,44 @@ static int radeon_pci_probe(struct pci_dev *pdev, + if (ret) + return ret; + +- return drm_get_pci_dev(pdev, ent, &kms_driver); ++ dev = drm_dev_alloc(&kms_driver, &pdev->dev); ++ if (IS_ERR(dev)) ++ return PTR_ERR(dev); ++ ++ ret = pci_enable_device(pdev); ++ if (ret) ++ goto err_free; ++ ++ dev->pdev = pdev; ++#ifdef __alpha__ ++ dev->hose = pdev->sysdata; ++#endif ++ ++ pci_set_drvdata(pdev, dev); ++ ++ if (pci_find_capability(dev->pdev, PCI_CAP_ID_AGP)) ++ dev->agp = drm_agp_init(dev); ++ if (dev->agp) { ++ dev->agp->agp_mtrr = arch_phys_wc_add( ++ dev->agp->agp_info.aper_base, ++ dev->agp->agp_info.aper_size * ++ 1024 * 1024); ++ } ++ ++ ret = drm_dev_register(dev, ent->driver_data); ++ if (ret) ++ goto err_agp; ++ ++ return 0; ++ ++err_agp: ++ if (dev->agp) ++ arch_phys_wc_del(dev->agp->agp_mtrr); ++ kfree(dev->agp); ++ pci_disable_device(pdev); ++err_free: ++ drm_dev_put(dev); ++ return ret; + } + + static void +@@ -578,7 +617,7 @@ radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, + + static struct drm_driver kms_driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_GEM | DRIVER_RENDER, ++ DRIVER_GEM | DRIVER_RENDER, + .load = radeon_driver_load_kms, + .open = radeon_driver_open_kms, + .postclose = radeon_driver_postclose_kms, +diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +index e85c554eeaa9..2bb0187c5bc7 100644 +--- a/drivers/gpu/drm/radeon/radeon_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_kms.c +@@ -31,6 +31,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -77,6 +78,11 @@ void radeon_driver_unload_kms(struct drm_device *dev) + radeon_modeset_fini(rdev); + radeon_device_fini(rdev); + ++ if (dev->agp) ++ arch_phys_wc_del(dev->agp->agp_mtrr); ++ kfree(dev->agp); ++ dev->agp = NULL; ++ + done_free: + kfree(rdev); + dev->dev_private = NULL; +diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c +index ae79a7c66737..fa704153cb00 100644 +--- a/drivers/hid/hid-alps.c ++++ b/drivers/hid/hid-alps.c +@@ -730,7 +730,7 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) + if (data->has_sp) { + input2 = input_allocate_device(); + if (!input2) { +- input_free_device(input2); ++ ret = -ENOMEM; + goto exit; + } + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 851fe54ea59e..359616e3efbb 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1741,7 +1741,9 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, + + rsize = ((report->size - 1) >> 3) + 1; + +- if (rsize > HID_MAX_BUFFER_SIZE) ++ if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) ++ rsize = HID_MAX_BUFFER_SIZE - 1; ++ else if (rsize > HID_MAX_BUFFER_SIZE) + rsize = HID_MAX_BUFFER_SIZE; + + if (csize < rsize) { +diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c +index c436e12feb23..6c55682c5974 100644 +--- a/drivers/hid/hid-ite.c ++++ b/drivers/hid/hid-ite.c +@@ -41,8 +41,9 @@ static const struct hid_device_id ite_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, + { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, + /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */ +- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, +- USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, ++ { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, ++ USB_VENDOR_ID_SYNAPTICS, ++ USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, + { } + }; + MODULE_DEVICE_TABLE(hid, ite_devices); +diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c +index c879b214a479..35b1fa6d962e 100644 +--- a/drivers/hid/usbhid/hiddev.c ++++ b/drivers/hid/usbhid/hiddev.c +@@ -941,9 +941,9 @@ void hiddev_disconnect(struct hid_device *hid) + hiddev->exist = 0; + + if (hiddev->open) { +- mutex_unlock(&hiddev->existancelock); + hid_hw_close(hiddev->hid); + wake_up_interruptible(&hiddev->wait); ++ mutex_unlock(&hiddev->existancelock); + } else { + mutex_unlock(&hiddev->existancelock); + kfree(hiddev); +diff --git a/drivers/i2c/busses/i2c-altera.c b/drivers/i2c/busses/i2c-altera.c +index 5255d3755411..1de23b4f3809 100644 +--- a/drivers/i2c/busses/i2c-altera.c ++++ b/drivers/i2c/busses/i2c-altera.c +@@ -171,7 +171,7 @@ static void altr_i2c_init(struct altr_i2c_dev *idev) + /* SCL Low Time */ + writel(t_low, idev->base + ALTR_I2C_SCL_LOW); + /* SDA Hold Time, 300ns */ +- writel(div_u64(300 * clk_mhz, 1000), idev->base + ALTR_I2C_SDA_HOLD); ++ writel(3 * clk_mhz / 10, idev->base + ALTR_I2C_SDA_HOLD); + + /* Mask all master interrupt bits */ + altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false); +diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c +index 25dcd73acd63..8f0e1f802f2d 100644 +--- a/drivers/i2c/busses/i2c-jz4780.c ++++ b/drivers/i2c/busses/i2c-jz4780.c +@@ -73,25 +73,6 @@ + #define JZ4780_I2C_STA_TFNF BIT(1) + #define JZ4780_I2C_STA_ACT BIT(0) + +-static const char * const jz4780_i2c_abrt_src[] = { +- "ABRT_7B_ADDR_NOACK", +- "ABRT_10ADDR1_NOACK", +- "ABRT_10ADDR2_NOACK", +- "ABRT_XDATA_NOACK", +- "ABRT_GCALL_NOACK", +- "ABRT_GCALL_READ", +- "ABRT_HS_ACKD", +- "SBYTE_ACKDET", +- "ABRT_HS_NORSTRT", +- "SBYTE_NORSTRT", +- "ABRT_10B_RD_NORSTRT", +- "ABRT_MASTER_DIS", +- "ARB_LOST", +- "SLVFLUSH_TXFIFO", +- "SLV_ARBLOST", +- "SLVRD_INTX", +-}; +- + #define JZ4780_I2C_INTST_IGC BIT(11) + #define JZ4780_I2C_INTST_ISTT BIT(10) + #define JZ4780_I2C_INTST_ISTP BIT(9) +@@ -529,21 +510,8 @@ done: + + static void jz4780_i2c_txabrt(struct jz4780_i2c *i2c, int src) + { +- int i; +- +- dev_err(&i2c->adap.dev, "txabrt: 0x%08x\n", src); +- dev_err(&i2c->adap.dev, "device addr=%x\n", +- jz4780_i2c_readw(i2c, JZ4780_I2C_TAR)); +- dev_err(&i2c->adap.dev, "send cmd count:%d %d\n", +- i2c->cmd, i2c->cmd_buf[i2c->cmd]); +- dev_err(&i2c->adap.dev, "receive data count:%d %d\n", +- i2c->cmd, i2c->data_buf[i2c->cmd]); +- +- for (i = 0; i < 16; i++) { +- if (src & BIT(i)) +- dev_dbg(&i2c->adap.dev, "I2C TXABRT[%d]=%s\n", +- i, jz4780_i2c_abrt_src[i]); +- } ++ dev_dbg(&i2c->adap.dev, "txabrt: 0x%08x, cmd: %d, send: %d, recv: %d\n", ++ src, i2c->cmd, i2c->cmd_buf[i2c->cmd], i2c->data_buf[i2c->cmd]); + } + + static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c, +diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h +index 96d1302abde1..e36d31569081 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_device.h ++++ b/drivers/infiniband/hw/hns/hns_roce_device.h +@@ -425,7 +425,7 @@ struct hns_roce_mr_table { + struct hns_roce_wq { + u64 *wrid; /* Work request ID */ + spinlock_t lock; +- int wqe_cnt; /* WQE num */ ++ u32 wqe_cnt; /* WQE num */ + u32 max_post; + int max_gs; + int offset; +@@ -658,7 +658,6 @@ struct hns_roce_qp { + u8 sdb_en; + u32 doorbell_qpn; + u32 sq_signal_bits; +- u32 sq_next_wqe; + struct hns_roce_wq sq; + + struct ib_umem *umem; +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +index 5f74bf55f471..a79fa67df871 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +@@ -74,8 +74,8 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + unsigned long flags = 0; + void *wqe = NULL; + __le32 doorbell[2]; ++ u32 wqe_idx = 0; + int nreq = 0; +- u32 ind = 0; + int ret = 0; + u8 *smac; + int loopback; +@@ -88,7 +88,7 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + } + + spin_lock_irqsave(&qp->sq.lock, flags); +- ind = qp->sq_next_wqe; ++ + for (nreq = 0; wr; ++nreq, wr = wr->next) { + if (hns_roce_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) { + ret = -ENOMEM; +@@ -96,6 +96,8 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + goto out; + } + ++ wqe_idx = (qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1); ++ + if (unlikely(wr->num_sge > qp->sq.max_gs)) { + dev_err(dev, "num_sge=%d > qp->sq.max_gs=%d\n", + wr->num_sge, qp->sq.max_gs); +@@ -104,9 +106,8 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + goto out; + } + +- wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1)); +- qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = +- wr->wr_id; ++ wqe = get_send_wqe(qp, wqe_idx); ++ qp->sq.wrid[wqe_idx] = wr->wr_id; + + /* Corresponding to the RC and RD type wqe process separately */ + if (ibqp->qp_type == IB_QPT_GSI) { +@@ -210,7 +211,6 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + cpu_to_le32((wr->sg_list[1].addr) >> 32); + ud_sq_wqe->l_key1 = + cpu_to_le32(wr->sg_list[1].lkey); +- ind++; + } else if (ibqp->qp_type == IB_QPT_RC) { + u32 tmp_len = 0; + +@@ -308,7 +308,6 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, + ctrl->flag |= cpu_to_le32(wr->num_sge << + HNS_ROCE_WQE_SGE_NUM_BIT); + } +- ind++; + } + } + +@@ -336,7 +335,6 @@ out: + doorbell[1] = sq_db.u32_8; + + hns_roce_write64_k(doorbell, qp->sq.db_reg_l); +- qp->sq_next_wqe = ind; + } + + spin_unlock_irqrestore(&qp->sq.lock, flags); +@@ -348,12 +346,6 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + const struct ib_recv_wr *wr, + const struct ib_recv_wr **bad_wr) + { +- int ret = 0; +- int nreq = 0; +- int ind = 0; +- int i = 0; +- u32 reg_val; +- unsigned long flags = 0; + struct hns_roce_rq_wqe_ctrl *ctrl = NULL; + struct hns_roce_wqe_data_seg *scat = NULL; + struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); +@@ -361,9 +353,14 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + struct device *dev = &hr_dev->pdev->dev; + struct hns_roce_rq_db rq_db; + __le32 doorbell[2] = {0}; ++ unsigned long flags = 0; ++ unsigned int wqe_idx; ++ int ret = 0; ++ int nreq = 0; ++ int i = 0; ++ u32 reg_val; + + spin_lock_irqsave(&hr_qp->rq.lock, flags); +- ind = hr_qp->rq.head & (hr_qp->rq.wqe_cnt - 1); + + for (nreq = 0; wr; ++nreq, wr = wr->next) { + if (hns_roce_wq_overflow(&hr_qp->rq, nreq, +@@ -373,6 +370,8 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + goto out; + } + ++ wqe_idx = (hr_qp->rq.head + nreq) & (hr_qp->rq.wqe_cnt - 1); ++ + if (unlikely(wr->num_sge > hr_qp->rq.max_gs)) { + dev_err(dev, "rq:num_sge=%d > qp->sq.max_gs=%d\n", + wr->num_sge, hr_qp->rq.max_gs); +@@ -381,7 +380,7 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + goto out; + } + +- ctrl = get_recv_wqe(hr_qp, ind); ++ ctrl = get_recv_wqe(hr_qp, wqe_idx); + + roce_set_field(ctrl->rwqe_byte_12, + RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_M, +@@ -393,9 +392,7 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, + for (i = 0; i < wr->num_sge; i++) + set_data_seg(scat + i, wr->sg_list + i); + +- hr_qp->rq.wrid[ind] = wr->wr_id; +- +- ind = (ind + 1) & (hr_qp->rq.wqe_cnt - 1); ++ hr_qp->rq.wrid[wqe_idx] = wr->wr_id; + } + + out: +@@ -2702,7 +2699,6 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, + hr_qp->rq.tail = 0; + hr_qp->sq.head = 0; + hr_qp->sq.tail = 0; +- hr_qp->sq_next_wqe = 0; + } + + kfree(context); +@@ -3316,7 +3312,6 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, + hr_qp->rq.tail = 0; + hr_qp->sq.head = 0; + hr_qp->sq.tail = 0; +- hr_qp->sq_next_wqe = 0; + } + out: + kfree(context); +diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +index 79294f278b26..4540b00ccee9 100644 +--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -110,7 +110,7 @@ static void set_atomic_seg(struct hns_roce_wqe_atomic_seg *aseg, + } + + static void set_extend_sge(struct hns_roce_qp *qp, const struct ib_send_wr *wr, +- unsigned int *sge_ind) ++ unsigned int *sge_ind, int valid_num_sge) + { + struct hns_roce_v2_wqe_data_seg *dseg; + struct ib_sge *sg; +@@ -123,7 +123,7 @@ static void set_extend_sge(struct hns_roce_qp *qp, const struct ib_send_wr *wr, + + if (qp->ibqp.qp_type == IB_QPT_RC || qp->ibqp.qp_type == IB_QPT_UC) + num_in_wqe = HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE; +- extend_sge_num = wr->num_sge - num_in_wqe; ++ extend_sge_num = valid_num_sge - num_in_wqe; + sg = wr->sg_list + num_in_wqe; + shift = qp->hr_buf.page_shift; + +@@ -159,14 +159,16 @@ static void set_extend_sge(struct hns_roce_qp *qp, const struct ib_send_wr *wr, + static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, + struct hns_roce_v2_rc_send_wqe *rc_sq_wqe, + void *wqe, unsigned int *sge_ind, ++ int valid_num_sge, + const struct ib_send_wr **bad_wr) + { + struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); + struct hns_roce_v2_wqe_data_seg *dseg = wqe; + struct hns_roce_qp *qp = to_hr_qp(ibqp); ++ int j = 0; + int i; + +- if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) { ++ if (wr->send_flags & IB_SEND_INLINE && valid_num_sge) { + if (le32_to_cpu(rc_sq_wqe->msg_len) > + hr_dev->caps.max_sq_inline) { + *bad_wr = wr; +@@ -190,7 +192,7 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, + roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_INLINE_S, + 1); + } else { +- if (wr->num_sge <= HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) { ++ if (valid_num_sge <= HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) { + for (i = 0; i < wr->num_sge; i++) { + if (likely(wr->sg_list[i].length)) { + set_data_seg_v2(dseg, wr->sg_list + i); +@@ -203,19 +205,21 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, + V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S, + (*sge_ind) & (qp->sge.sge_cnt - 1)); + +- for (i = 0; i < HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE; i++) { ++ for (i = 0; i < wr->num_sge && ++ j < HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE; i++) { + if (likely(wr->sg_list[i].length)) { + set_data_seg_v2(dseg, wr->sg_list + i); + dseg++; ++ j++; + } + } + +- set_extend_sge(qp, wr, sge_ind); ++ set_extend_sge(qp, wr, sge_ind, valid_num_sge); + } + + roce_set_field(rc_sq_wqe->byte_16, + V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M, +- V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, wr->num_sge); ++ V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, valid_num_sge); + } + + return 0; +@@ -239,10 +243,11 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + struct device *dev = hr_dev->dev; + struct hns_roce_v2_db sq_db; + struct ib_qp_attr attr; +- unsigned int sge_ind; + unsigned int owner_bit; ++ unsigned int sge_idx; ++ unsigned int wqe_idx; + unsigned long flags; +- unsigned int ind; ++ int valid_num_sge; + void *wqe = NULL; + bool loopback; + int attr_mask; +@@ -269,8 +274,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + } + + spin_lock_irqsave(&qp->sq.lock, flags); +- ind = qp->sq_next_wqe; +- sge_ind = qp->next_sge; ++ sge_idx = qp->next_sge; + + for (nreq = 0; wr; ++nreq, wr = wr->next) { + if (hns_roce_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) { +@@ -279,6 +283,8 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + goto out; + } + ++ wqe_idx = (qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1); ++ + if (unlikely(wr->num_sge > qp->sq.max_gs)) { + dev_err(dev, "num_sge=%d > qp->sq.max_gs=%d\n", + wr->num_sge, qp->sq.max_gs); +@@ -287,14 +293,20 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + goto out; + } + +- wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1)); +- qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = +- wr->wr_id; +- ++ wqe = get_send_wqe(qp, wqe_idx); ++ qp->sq.wrid[wqe_idx] = wr->wr_id; + owner_bit = + ~(((qp->sq.head + nreq) >> ilog2(qp->sq.wqe_cnt)) & 0x1); ++ valid_num_sge = 0; + tmp_len = 0; + ++ for (i = 0; i < wr->num_sge; i++) { ++ if (likely(wr->sg_list[i].length)) { ++ tmp_len += wr->sg_list[i].length; ++ valid_num_sge++; ++ } ++ } ++ + /* Corresponding to the QP type, wqe process separately */ + if (ibqp->qp_type == IB_QPT_GSI) { + ud_sq_wqe = wqe; +@@ -330,9 +342,6 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + V2_UD_SEND_WQE_BYTE_4_OPCODE_S, + HNS_ROCE_V2_WQE_OP_SEND); + +- for (i = 0; i < wr->num_sge; i++) +- tmp_len += wr->sg_list[i].length; +- + ud_sq_wqe->msg_len = + cpu_to_le32(le32_to_cpu(ud_sq_wqe->msg_len) + tmp_len); + +@@ -368,12 +377,12 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + roce_set_field(ud_sq_wqe->byte_16, + V2_UD_SEND_WQE_BYTE_16_SGE_NUM_M, + V2_UD_SEND_WQE_BYTE_16_SGE_NUM_S, +- wr->num_sge); ++ valid_num_sge); + + roce_set_field(ud_sq_wqe->byte_20, + V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M, + V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S, +- sge_ind & (qp->sge.sge_cnt - 1)); ++ sge_idx & (qp->sge.sge_cnt - 1)); + + roce_set_field(ud_sq_wqe->byte_24, + V2_UD_SEND_WQE_BYTE_24_UDPSPN_M, +@@ -423,13 +432,10 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + memcpy(&ud_sq_wqe->dgid[0], &ah->av.dgid[0], + GID_LEN_V2); + +- set_extend_sge(qp, wr, &sge_ind); +- ind++; ++ set_extend_sge(qp, wr, &sge_idx, valid_num_sge); + } else if (ibqp->qp_type == IB_QPT_RC) { + rc_sq_wqe = wqe; + memset(rc_sq_wqe, 0, sizeof(*rc_sq_wqe)); +- for (i = 0; i < wr->num_sge; i++) +- tmp_len += wr->sg_list[i].length; + + rc_sq_wqe->msg_len = + cpu_to_le32(le32_to_cpu(rc_sq_wqe->msg_len) + tmp_len); +@@ -550,15 +556,14 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, + roce_set_field(rc_sq_wqe->byte_16, + V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M, + V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, +- wr->num_sge); ++ valid_num_sge); + } else if (wr->opcode != IB_WR_REG_MR) { + ret = set_rwqe_data_seg(ibqp, wr, rc_sq_wqe, +- wqe, &sge_ind, bad_wr); ++ wqe, &sge_idx, ++ valid_num_sge, bad_wr); + if (ret) + goto out; + } +- +- ind++; + } else { + dev_err(dev, "Illegal qp_type(0x%x)\n", ibqp->qp_type); + spin_unlock_irqrestore(&qp->sq.lock, flags); +@@ -588,8 +593,7 @@ out: + + hns_roce_write64(hr_dev, (__le32 *)&sq_db, qp->sq.db_reg_l); + +- qp->sq_next_wqe = ind; +- qp->next_sge = sge_ind; ++ qp->next_sge = sge_idx; + + if (qp->state == IB_QPS_ERR) { + attr_mask = IB_QP_STATE; +@@ -623,13 +627,12 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + unsigned long flags; + void *wqe = NULL; + int attr_mask; ++ u32 wqe_idx; + int ret = 0; + int nreq; +- int ind; + int i; + + spin_lock_irqsave(&hr_qp->rq.lock, flags); +- ind = hr_qp->rq.head & (hr_qp->rq.wqe_cnt - 1); + + if (hr_qp->state == IB_QPS_RESET) { + spin_unlock_irqrestore(&hr_qp->rq.lock, flags); +@@ -645,6 +648,8 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + goto out; + } + ++ wqe_idx = (hr_qp->rq.head + nreq) & (hr_qp->rq.wqe_cnt - 1); ++ + if (unlikely(wr->num_sge > hr_qp->rq.max_gs)) { + dev_err(dev, "rq:num_sge=%d > qp->sq.max_gs=%d\n", + wr->num_sge, hr_qp->rq.max_gs); +@@ -653,7 +658,7 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + goto out; + } + +- wqe = get_recv_wqe(hr_qp, ind); ++ wqe = get_recv_wqe(hr_qp, wqe_idx); + dseg = (struct hns_roce_v2_wqe_data_seg *)wqe; + for (i = 0; i < wr->num_sge; i++) { + if (!wr->sg_list[i].length) +@@ -669,8 +674,8 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + + /* rq support inline data */ + if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) { +- sge_list = hr_qp->rq_inl_buf.wqe_list[ind].sg_list; +- hr_qp->rq_inl_buf.wqe_list[ind].sge_cnt = ++ sge_list = hr_qp->rq_inl_buf.wqe_list[wqe_idx].sg_list; ++ hr_qp->rq_inl_buf.wqe_list[wqe_idx].sge_cnt = + (u32)wr->num_sge; + for (i = 0; i < wr->num_sge; i++) { + sge_list[i].addr = +@@ -679,9 +684,7 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, + } + } + +- hr_qp->rq.wrid[ind] = wr->wr_id; +- +- ind = (ind + 1) & (hr_qp->rq.wqe_cnt - 1); ++ hr_qp->rq.wrid[wqe_idx] = wr->wr_id; + } + + out: +@@ -4465,7 +4468,6 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp, + hr_qp->rq.tail = 0; + hr_qp->sq.head = 0; + hr_qp->sq.tail = 0; +- hr_qp->sq_next_wqe = 0; + hr_qp->next_sge = 0; + if (hr_qp->rq.wqe_cnt) + *hr_qp->rdb.db_record = 0; +diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c +index 0454561718d9..31aa41d85ccf 100644 +--- a/drivers/infiniband/sw/siw/siw_cm.c ++++ b/drivers/infiniband/sw/siw/siw_cm.c +@@ -1225,10 +1225,9 @@ static void siw_cm_llp_data_ready(struct sock *sk) + read_lock(&sk->sk_callback_lock); + + cep = sk_to_cep(sk); +- if (!cep) { +- WARN_ON(1); ++ if (!cep) + goto out; +- } ++ + siw_dbg_cep(cep, "state: %d\n", cep->state); + + switch (cep->state) { +diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c +index 8c744578122a..a0d87ed9da69 100644 +--- a/drivers/macintosh/therm_windtunnel.c ++++ b/drivers/macintosh/therm_windtunnel.c +@@ -300,9 +300,11 @@ static int control_loop(void *dummy) + /* i2c probing and setup */ + /************************************************************************/ + +-static int +-do_attach( struct i2c_adapter *adapter ) ++static void do_attach(struct i2c_adapter *adapter) + { ++ struct i2c_board_info info = { }; ++ struct device_node *np; ++ + /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ + static const unsigned short scan_ds1775[] = { + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, +@@ -313,25 +315,24 @@ do_attach( struct i2c_adapter *adapter ) + I2C_CLIENT_END + }; + +- if( strncmp(adapter->name, "uni-n", 5) ) +- return 0; +- +- if( !x.running ) { +- struct i2c_board_info info; ++ if (x.running || strncmp(adapter->name, "uni-n", 5)) ++ return; + +- memset(&info, 0, sizeof(struct i2c_board_info)); +- strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE); ++ np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,ds1775"); ++ if (np) { ++ of_node_put(np); ++ } else { ++ strlcpy(info.type, "MAC,ds1775", I2C_NAME_SIZE); + i2c_new_probed_device(adapter, &info, scan_ds1775, NULL); ++ } + +- strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE); ++ np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,adm1030"); ++ if (np) { ++ of_node_put(np); ++ } else { ++ strlcpy(info.type, "MAC,adm1030", I2C_NAME_SIZE); + i2c_new_probed_device(adapter, &info, scan_adm1030, NULL); +- +- if( x.thermostat && x.fan ) { +- x.running = 1; +- x.poll_task = kthread_run(control_loop, NULL, "g4fand"); +- } + } +- return 0; + } + + static int +@@ -404,8 +405,8 @@ out: + enum chip { ds1775, adm1030 }; + + static const struct i2c_device_id therm_windtunnel_id[] = { +- { "therm_ds1775", ds1775 }, +- { "therm_adm1030", adm1030 }, ++ { "MAC,ds1775", ds1775 }, ++ { "MAC,adm1030", adm1030 }, + { } + }; + MODULE_DEVICE_TABLE(i2c, therm_windtunnel_id); +@@ -414,6 +415,7 @@ static int + do_probe(struct i2c_client *cl, const struct i2c_device_id *id) + { + struct i2c_adapter *adapter = cl->adapter; ++ int ret = 0; + + if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA + | I2C_FUNC_SMBUS_WRITE_BYTE) ) +@@ -421,11 +423,19 @@ do_probe(struct i2c_client *cl, const struct i2c_device_id *id) + + switch (id->driver_data) { + case adm1030: +- return attach_fan( cl ); ++ ret = attach_fan(cl); ++ break; + case ds1775: +- return attach_thermostat(cl); ++ ret = attach_thermostat(cl); ++ break; + } +- return 0; ++ ++ if (!x.running && x.thermostat && x.fan) { ++ x.running = 1; ++ x.poll_task = kthread_run(control_loop, NULL, "g4fand"); ++ } ++ ++ return ret; + } + + static struct i2c_driver g4fan_driver = { +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 7dcd709f4ac3..703c5c2c80e5 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3436,6 +3436,47 @@ static void bond_fold_stats(struct rtnl_link_stats64 *_res, + } + } + ++#ifdef CONFIG_LOCKDEP ++static int bond_get_lowest_level_rcu(struct net_device *dev) ++{ ++ struct net_device *ldev, *next, *now, *dev_stack[MAX_NEST_DEV + 1]; ++ struct list_head *niter, *iter, *iter_stack[MAX_NEST_DEV + 1]; ++ int cur = 0, max = 0; ++ ++ now = dev; ++ iter = &dev->adj_list.lower; ++ ++ while (1) { ++ next = NULL; ++ while (1) { ++ ldev = netdev_next_lower_dev_rcu(now, &iter); ++ if (!ldev) ++ break; ++ ++ next = ldev; ++ niter = &ldev->adj_list.lower; ++ dev_stack[cur] = now; ++ iter_stack[cur++] = iter; ++ if (max <= cur) ++ max = cur; ++ break; ++ } ++ ++ if (!next) { ++ if (!cur) ++ return max; ++ next = dev_stack[--cur]; ++ niter = iter_stack[cur]; ++ } ++ ++ now = next; ++ iter = niter; ++ } ++ ++ return max; ++} ++#endif ++ + static void bond_get_stats(struct net_device *bond_dev, + struct rtnl_link_stats64 *stats) + { +@@ -3443,11 +3484,17 @@ static void bond_get_stats(struct net_device *bond_dev, + struct rtnl_link_stats64 temp; + struct list_head *iter; + struct slave *slave; ++ int nest_level = 0; + +- spin_lock(&bond->stats_lock); +- memcpy(stats, &bond->bond_stats, sizeof(*stats)); + + rcu_read_lock(); ++#ifdef CONFIG_LOCKDEP ++ nest_level = bond_get_lowest_level_rcu(bond_dev); ++#endif ++ ++ spin_lock_nested(&bond->stats_lock, nest_level); ++ memcpy(stats, &bond->bond_stats, sizeof(*stats)); ++ + bond_for_each_slave_rcu(bond, slave, iter) { + const struct rtnl_link_stats64 *new = + dev_get_stats(slave->dev, &temp); +@@ -3457,10 +3504,10 @@ static void bond_get_stats(struct net_device *bond_dev, + /* save off the slave stats for the next run */ + memcpy(&slave->slave_stats, new, sizeof(*new)); + } +- rcu_read_unlock(); + + memcpy(&bond->bond_stats, stats, sizeof(*stats)); + spin_unlock(&bond->stats_lock); ++ rcu_read_unlock(); + } + + static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd) +@@ -3550,6 +3597,8 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd + case BOND_RELEASE_OLD: + case SIOCBONDRELEASE: + res = bond_release(bond_dev, slave_dev); ++ if (!res) ++ netdev_update_lockdep_key(slave_dev); + break; + case BOND_SETHWADDR_OLD: + case SIOCBONDSETHWADDR: +diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c +index ddb3916d3506..215c10923289 100644 +--- a/drivers/net/bonding/bond_options.c ++++ b/drivers/net/bonding/bond_options.c +@@ -1398,6 +1398,8 @@ static int bond_option_slaves_set(struct bonding *bond, + case '-': + slave_dbg(bond->dev, dev, "Releasing interface\n"); + ret = bond_release(bond->dev, dev); ++ if (!ret) ++ netdev_update_lockdep_key(dev); + break; + + default: +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 7ed667b304d1..d618650533b6 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1353,6 +1353,9 @@ void b53_vlan_add(struct dsa_switch *ds, int port, + + b53_get_vlan_entry(dev, vid, vl); + ++ if (vid == 0 && vid == b53_default_pvid(dev)) ++ untagged = true; ++ + vl->members |= BIT(port); + if (untagged && !dsa_is_cpu_port(ds, port)) + vl->untag |= BIT(port); +diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c +index ea62604fdf8c..48de4bee209e 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_com.c ++++ b/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -200,6 +200,11 @@ static void comp_ctxt_release(struct ena_com_admin_queue *queue, + static struct ena_comp_ctx *get_comp_ctxt(struct ena_com_admin_queue *queue, + u16 command_id, bool capture) + { ++ if (unlikely(!queue->comp_ctx)) { ++ pr_err("Completion context is NULL\n"); ++ return NULL; ++ } ++ + if (unlikely(command_id >= queue->q_depth)) { + pr_err("command id is larger than the queue size. cmd_id: %u queue size %d\n", + command_id, queue->q_depth); +@@ -1041,9 +1046,41 @@ static int ena_com_get_feature(struct ena_com_dev *ena_dev, + feature_ver); + } + ++static void ena_com_hash_key_fill_default_key(struct ena_com_dev *ena_dev) ++{ ++ struct ena_admin_feature_rss_flow_hash_control *hash_key = ++ (ena_dev->rss).hash_key; ++ ++ netdev_rss_key_fill(&hash_key->key, sizeof(hash_key->key)); ++ /* The key is stored in the device in u32 array ++ * as well as the API requires the key to be passed in this ++ * format. Thus the size of our array should be divided by 4 ++ */ ++ hash_key->keys_num = sizeof(hash_key->key) / sizeof(u32); ++} ++ ++int ena_com_get_current_hash_function(struct ena_com_dev *ena_dev) ++{ ++ return ena_dev->rss.hash_func; ++} ++ + static int ena_com_hash_key_allocate(struct ena_com_dev *ena_dev) + { + struct ena_rss *rss = &ena_dev->rss; ++ struct ena_admin_feature_rss_flow_hash_control *hash_key; ++ struct ena_admin_get_feat_resp get_resp; ++ int rc; ++ ++ hash_key = (ena_dev->rss).hash_key; ++ ++ rc = ena_com_get_feature_ex(ena_dev, &get_resp, ++ ENA_ADMIN_RSS_HASH_FUNCTION, ++ ena_dev->rss.hash_key_dma_addr, ++ sizeof(ena_dev->rss.hash_key), 0); ++ if (unlikely(rc)) { ++ hash_key = NULL; ++ return -EOPNOTSUPP; ++ } + + rss->hash_key = + dma_alloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_key), +@@ -1254,30 +1291,6 @@ static int ena_com_ind_tbl_convert_to_device(struct ena_com_dev *ena_dev) + return 0; + } + +-static int ena_com_ind_tbl_convert_from_device(struct ena_com_dev *ena_dev) +-{ +- u16 dev_idx_to_host_tbl[ENA_TOTAL_NUM_QUEUES] = { (u16)-1 }; +- struct ena_rss *rss = &ena_dev->rss; +- u8 idx; +- u16 i; +- +- for (i = 0; i < ENA_TOTAL_NUM_QUEUES; i++) +- dev_idx_to_host_tbl[ena_dev->io_sq_queues[i].idx] = i; +- +- for (i = 0; i < 1 << rss->tbl_log_size; i++) { +- if (rss->rss_ind_tbl[i].cq_idx > ENA_TOTAL_NUM_QUEUES) +- return -EINVAL; +- idx = (u8)rss->rss_ind_tbl[i].cq_idx; +- +- if (dev_idx_to_host_tbl[idx] > ENA_TOTAL_NUM_QUEUES) +- return -EINVAL; +- +- rss->host_rss_ind_tbl[i] = dev_idx_to_host_tbl[idx]; +- } +- +- return 0; +-} +- + static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev, + u16 intr_delay_resolution) + { +@@ -2297,15 +2310,16 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev, + + switch (func) { + case ENA_ADMIN_TOEPLITZ: +- if (key_len > sizeof(hash_key->key)) { +- pr_err("key len (%hu) is bigger than the max supported (%zu)\n", +- key_len, sizeof(hash_key->key)); +- return -EINVAL; ++ if (key) { ++ if (key_len != sizeof(hash_key->key)) { ++ pr_err("key len (%hu) doesn't equal the supported size (%zu)\n", ++ key_len, sizeof(hash_key->key)); ++ return -EINVAL; ++ } ++ memcpy(hash_key->key, key, key_len); ++ rss->hash_init_val = init_val; ++ hash_key->keys_num = key_len >> 2; + } +- +- memcpy(hash_key->key, key, key_len); +- rss->hash_init_val = init_val; +- hash_key->keys_num = key_len >> 2; + break; + case ENA_ADMIN_CRC32: + rss->hash_init_val = init_val; +@@ -2342,7 +2356,11 @@ int ena_com_get_hash_function(struct ena_com_dev *ena_dev, + if (unlikely(rc)) + return rc; + +- rss->hash_func = get_resp.u.flow_hash_func.selected_func; ++ /* ffs() returns 1 in case the lsb is set */ ++ rss->hash_func = ffs(get_resp.u.flow_hash_func.selected_func); ++ if (rss->hash_func) ++ rss->hash_func--; ++ + if (func) + *func = rss->hash_func; + +@@ -2606,10 +2624,6 @@ int ena_com_indirect_table_get(struct ena_com_dev *ena_dev, u32 *ind_tbl) + if (!ind_tbl) + return 0; + +- rc = ena_com_ind_tbl_convert_from_device(ena_dev); +- if (unlikely(rc)) +- return rc; +- + for (i = 0; i < (1 << rss->tbl_log_size); i++) + ind_tbl[i] = rss->host_rss_ind_tbl[i]; + +@@ -2626,9 +2640,15 @@ int ena_com_rss_init(struct ena_com_dev *ena_dev, u16 indr_tbl_log_size) + if (unlikely(rc)) + goto err_indr_tbl; + ++ /* The following function might return unsupported in case the ++ * device doesn't support setting the key / hash function. We can safely ++ * ignore this error and have indirection table support only. ++ */ + rc = ena_com_hash_key_allocate(ena_dev); +- if (unlikely(rc)) ++ if (unlikely(rc) && rc != -EOPNOTSUPP) + goto err_hash_key; ++ else if (rc != -EOPNOTSUPP) ++ ena_com_hash_key_fill_default_key(ena_dev); + + rc = ena_com_hash_ctrl_init(ena_dev); + if (unlikely(rc)) +diff --git a/drivers/net/ethernet/amazon/ena/ena_com.h b/drivers/net/ethernet/amazon/ena/ena_com.h +index 0ce37d54ed10..469f298199a7 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_com.h ++++ b/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + #include "ena_common_defs.h" + #include "ena_admin_defs.h" +@@ -655,6 +656,14 @@ int ena_com_rss_init(struct ena_com_dev *ena_dev, u16 log_size); + */ + void ena_com_rss_destroy(struct ena_com_dev *ena_dev); + ++/* ena_com_get_current_hash_function - Get RSS hash function ++ * @ena_dev: ENA communication layer struct ++ * ++ * Return the current hash function. ++ * @return: 0 or one of the ena_admin_hash_functions values. ++ */ ++int ena_com_get_current_hash_function(struct ena_com_dev *ena_dev); ++ + /* ena_com_fill_hash_function - Fill RSS hash function + * @ena_dev: ENA communication layer struct + * @func: The hash function (Toeplitz or crc) +diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +index 8c1c73b0ced7..ae631b8770fc 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -636,6 +636,28 @@ static u32 ena_get_rxfh_key_size(struct net_device *netdev) + return ENA_HASH_KEY_SIZE; + } + ++static int ena_indirection_table_get(struct ena_adapter *adapter, u32 *indir) ++{ ++ struct ena_com_dev *ena_dev = adapter->ena_dev; ++ int i, rc; ++ ++ if (!indir) ++ return 0; ++ ++ rc = ena_com_indirect_table_get(ena_dev, indir); ++ if (rc) ++ return rc; ++ ++ /* Our internal representation of the indices is: even indices ++ * for Tx and uneven indices for Rx. We need to convert the Rx ++ * indices to be consecutive ++ */ ++ for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) ++ indir[i] = ENA_IO_RXQ_IDX_TO_COMBINED_IDX(indir[i]); ++ ++ return rc; ++} ++ + static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + u8 *hfunc) + { +@@ -644,11 +666,25 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + u8 func; + int rc; + +- rc = ena_com_indirect_table_get(adapter->ena_dev, indir); ++ rc = ena_indirection_table_get(adapter, indir); + if (rc) + return rc; + ++ /* We call this function in order to check if the device ++ * supports getting/setting the hash function. ++ */ + rc = ena_com_get_hash_function(adapter->ena_dev, &ena_func, key); ++ ++ if (rc) { ++ if (rc == -EOPNOTSUPP) { ++ key = NULL; ++ hfunc = NULL; ++ rc = 0; ++ } ++ ++ return rc; ++ } ++ + if (rc) + return rc; + +@@ -657,7 +693,7 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + func = ETH_RSS_HASH_TOP; + break; + case ENA_ADMIN_CRC32: +- func = ETH_RSS_HASH_XOR; ++ func = ETH_RSS_HASH_CRC32; + break; + default: + netif_err(adapter, drv, netdev, +@@ -700,10 +736,13 @@ static int ena_set_rxfh(struct net_device *netdev, const u32 *indir, + } + + switch (hfunc) { ++ case ETH_RSS_HASH_NO_CHANGE: ++ func = ena_com_get_current_hash_function(ena_dev); ++ break; + case ETH_RSS_HASH_TOP: + func = ENA_ADMIN_TOEPLITZ; + break; +- case ETH_RSS_HASH_XOR: ++ case ETH_RSS_HASH_CRC32: + func = ENA_ADMIN_CRC32; + break; + default: +@@ -805,6 +844,7 @@ static const struct ethtool_ops ena_ethtool_ops = { + .get_channels = ena_get_channels, + .get_tunable = ena_get_tunable, + .set_tunable = ena_set_tunable, ++ .get_ts_info = ethtool_op_get_ts_info, + }; + + void ena_set_ethtool_ops(struct net_device *netdev) +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c +index b4a145220aba..f0cddf250cfd 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3035,8 +3035,8 @@ static void check_for_missing_keep_alive(struct ena_adapter *adapter) + if (adapter->keep_alive_timeout == ENA_HW_HINTS_NO_TIMEOUT) + return; + +- keep_alive_expired = round_jiffies(adapter->last_keep_alive_jiffies + +- adapter->keep_alive_timeout); ++ keep_alive_expired = adapter->last_keep_alive_jiffies + ++ adapter->keep_alive_timeout; + if (unlikely(time_is_before_jiffies(keep_alive_expired))) { + netif_err(adapter, drv, adapter->netdev, + "Keep alive watchdog timeout.\n"); +@@ -3138,7 +3138,7 @@ static void ena_timer_service(struct timer_list *t) + } + + /* Reset the timer */ +- mod_timer(&adapter->timer_service, jiffies + HZ); ++ mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); + } + + static int ena_calc_io_queue_num(struct pci_dev *pdev, +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h +index 72ee51a82ec7..dc02950a96b8 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -127,6 +127,8 @@ + + #define ENA_IO_TXQ_IDX(q) (2 * (q)) + #define ENA_IO_RXQ_IDX(q) (2 * (q) + 1) ++#define ENA_IO_TXQ_IDX_TO_COMBINED_IDX(q) ((q) / 2) ++#define ENA_IO_RXQ_IDX_TO_COMBINED_IDX(q) (((q) - 1) / 2) + + #define ENA_MGMNT_IRQ_IDX 0 + #define ENA_IO_IRQ_FIRST_IDX 1 +diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +index d8612131c55e..cc8031ae9aa3 100644 +--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c ++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +@@ -2020,7 +2020,7 @@ static int xgene_enet_probe(struct platform_device *pdev) + int ret; + + ndev = alloc_etherdev_mqs(sizeof(struct xgene_enet_pdata), +- XGENE_NUM_RX_RING, XGENE_NUM_TX_RING); ++ XGENE_NUM_TX_RING, XGENE_NUM_RX_RING); + if (!ndev) + return -ENOMEM; + +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +index aee827f07c16..01af0f028693 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +@@ -158,7 +158,7 @@ aq_check_approve_fvlan(struct aq_nic_s *aq_nic, + } + + if ((aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) && +- (!test_bit(be16_to_cpu(fsp->h_ext.vlan_tci), ++ (!test_bit(be16_to_cpu(fsp->h_ext.vlan_tci) & VLAN_VID_MASK, + aq_nic->active_vlans))) { + netdev_err(aq_nic->ndev, + "ethtool: unknown vlan-id specified"); +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +index 137c1de4c6ec..12949f1ec1ea 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +@@ -467,8 +467,10 @@ static unsigned int aq_nic_map_skb(struct aq_nic_s *self, + dx_buff->len, + DMA_TO_DEVICE); + +- if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) ++ if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) { ++ ret = 0; + goto exit; ++ } + + first = dx_buff; + dx_buff->len_pkt = skb->len; +@@ -598,10 +600,6 @@ int aq_nic_xmit(struct aq_nic_s *self, struct sk_buff *skb) + if (likely(frags)) { + err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw, + ring, frags); +- if (err >= 0) { +- ++ring->stats.tx.packets; +- ring->stats.tx.bytes += skb->len; +- } + } else { + err = NETDEV_TX_BUSY; + } +diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +index 76bdbe1596d6..03821b46a8cb 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c ++++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +@@ -243,9 +243,12 @@ bool aq_ring_tx_clean(struct aq_ring_s *self) + } + } + +- if (unlikely(buff->is_eop)) +- dev_kfree_skb_any(buff->skb); ++ if (unlikely(buff->is_eop)) { ++ ++self->stats.rx.packets; ++ self->stats.tx.bytes += buff->skb->len; + ++ dev_kfree_skb_any(buff->skb); ++ } + buff->pa = 0U; + buff->eop_index = 0xffffU; + self->sw_head = aq_ring_next_dx(self, self->sw_head); +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 68618891b0e4..374e11a91790 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -11712,6 +11712,14 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + if (version_printed++ == 0) + pr_info("%s", version); + ++ /* Clear any pending DMA transactions from crash kernel ++ * while loading driver in capture kernel. ++ */ ++ if (is_kdump_kernel()) { ++ pci_clear_master(pdev); ++ pcie_flr(pdev); ++ } ++ + max_irqs = bnxt_get_max_irq(pdev); + dev = alloc_etherdev_mq(sizeof(*bp), max_irqs); + if (!dev) +@@ -11908,10 +11916,10 @@ static void bnxt_shutdown(struct pci_dev *pdev) + dev_close(dev); + + bnxt_ulp_shutdown(bp); ++ bnxt_clear_int_mode(bp); ++ pci_disable_device(pdev); + + if (system_state == SYSTEM_POWER_OFF) { +- bnxt_clear_int_mode(bp); +- pci_disable_device(pdev); + pci_wake_from_d3(pdev, bp->wol); + pci_set_power_state(pdev, PCI_D3hot); + } +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 95a94507cec1..234c13ebbc41 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -3690,6 +3690,10 @@ static int at91ether_open(struct net_device *dev) + u32 ctl; + int ret; + ++ ret = pm_runtime_get_sync(&lp->pdev->dev); ++ if (ret < 0) ++ return ret; ++ + /* Clear internal statistics */ + ctl = macb_readl(lp, NCR); + macb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT)); +@@ -3750,7 +3754,7 @@ static int at91ether_close(struct net_device *dev) + q->rx_buffers, q->rx_buffers_dma); + q->rx_buffers = NULL; + +- return 0; ++ return pm_runtime_put(&lp->pdev->dev); + } + + /* Transmit packet */ +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index 162881005a6d..c01cf8ef69df 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -6003,6 +6003,9 @@ static int hclge_get_all_rules(struct hnae3_handle *handle, + static void hclge_fd_get_flow_tuples(const struct flow_keys *fkeys, + struct hclge_fd_rule_tuples *tuples) + { ++#define flow_ip6_src fkeys->addrs.v6addrs.src.in6_u.u6_addr32 ++#define flow_ip6_dst fkeys->addrs.v6addrs.dst.in6_u.u6_addr32 ++ + tuples->ether_proto = be16_to_cpu(fkeys->basic.n_proto); + tuples->ip_proto = fkeys->basic.ip_proto; + tuples->dst_port = be16_to_cpu(fkeys->ports.dst); +@@ -6011,12 +6014,12 @@ static void hclge_fd_get_flow_tuples(const struct flow_keys *fkeys, + tuples->src_ip[3] = be32_to_cpu(fkeys->addrs.v4addrs.src); + tuples->dst_ip[3] = be32_to_cpu(fkeys->addrs.v4addrs.dst); + } else { +- memcpy(tuples->src_ip, +- fkeys->addrs.v6addrs.src.in6_u.u6_addr32, +- sizeof(tuples->src_ip)); +- memcpy(tuples->dst_ip, +- fkeys->addrs.v6addrs.dst.in6_u.u6_addr32, +- sizeof(tuples->dst_ip)); ++ int i; ++ ++ for (i = 0; i < IPV6_SIZE; i++) { ++ tuples->src_ip[i] = be32_to_cpu(flow_ip6_src[i]); ++ tuples->dst_ip[i] = be32_to_cpu(flow_ip6_dst[i]); ++ } + } + } + +@@ -9437,6 +9440,13 @@ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev) + return ret; + } + ++ ret = init_mgr_tbl(hdev); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "failed to reinit manager table, ret = %d\n", ret); ++ return ret; ++ } ++ + ret = hclge_init_fd_config(hdev); + if (ret) { + dev_err(&pdev->dev, "fd table init fail, ret=%d\n", ret); +diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +index 3515ace0f020..38042d610f82 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -2363,7 +2363,7 @@ static int i40e_vc_enable_queues_msg(struct i40e_vf *vf, u8 *msg) + goto error_param; + } + +- if (i40e_vc_validate_vqs_bitmaps(vqs)) { ++ if (!i40e_vc_validate_vqs_bitmaps(vqs)) { + aq_ret = I40E_ERR_PARAM; + goto error_param; + } +@@ -2425,7 +2425,7 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg) + goto error_param; + } + +- if (i40e_vc_validate_vqs_bitmaps(vqs)) { ++ if (!i40e_vc_validate_vqs_bitmaps(vqs)) { + aq_ret = I40E_ERR_PARAM; + goto error_param; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c +index 3a6b3950eb0e..171f0b625407 100644 +--- a/drivers/net/ethernet/intel/ice/ice_common.c ++++ b/drivers/net/ethernet/intel/ice/ice_common.c +@@ -934,7 +934,7 @@ void ice_deinit_hw(struct ice_hw *hw) + */ + enum ice_status ice_check_reset(struct ice_hw *hw) + { +- u32 cnt, reg = 0, grst_delay; ++ u32 cnt, reg = 0, grst_delay, uld_mask; + + /* Poll for Device Active state in case a recent CORER, GLOBR, + * or EMPR has occurred. The grst delay value is in 100ms units. +@@ -956,13 +956,20 @@ enum ice_status ice_check_reset(struct ice_hw *hw) + return ICE_ERR_RESET_FAILED; + } + +-#define ICE_RESET_DONE_MASK (GLNVM_ULD_CORER_DONE_M | \ +- GLNVM_ULD_GLOBR_DONE_M) ++#define ICE_RESET_DONE_MASK (GLNVM_ULD_PCIER_DONE_M |\ ++ GLNVM_ULD_PCIER_DONE_1_M |\ ++ GLNVM_ULD_CORER_DONE_M |\ ++ GLNVM_ULD_GLOBR_DONE_M |\ ++ GLNVM_ULD_POR_DONE_M |\ ++ GLNVM_ULD_POR_DONE_1_M |\ ++ GLNVM_ULD_PCIER_DONE_2_M) ++ ++ uld_mask = ICE_RESET_DONE_MASK; + + /* Device is Active; check Global Reset processes are done */ + for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) { +- reg = rd32(hw, GLNVM_ULD) & ICE_RESET_DONE_MASK; +- if (reg == ICE_RESET_DONE_MASK) { ++ reg = rd32(hw, GLNVM_ULD) & uld_mask; ++ if (reg == uld_mask) { + ice_debug(hw, ICE_DBG_INIT, + "Global reset processes done. %d\n", cnt); + break; +diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +index 152fbd556e9b..9138b19de87e 100644 +--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h ++++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +@@ -273,8 +273,14 @@ + #define GLNVM_GENS_SR_SIZE_S 5 + #define GLNVM_GENS_SR_SIZE_M ICE_M(0x7, 5) + #define GLNVM_ULD 0x000B6008 ++#define GLNVM_ULD_PCIER_DONE_M BIT(0) ++#define GLNVM_ULD_PCIER_DONE_1_M BIT(1) + #define GLNVM_ULD_CORER_DONE_M BIT(3) + #define GLNVM_ULD_GLOBR_DONE_M BIT(4) ++#define GLNVM_ULD_POR_DONE_M BIT(5) ++#define GLNVM_ULD_POR_DONE_1_M BIT(8) ++#define GLNVM_ULD_PCIER_DONE_2_M BIT(9) ++#define GLNVM_ULD_PE_DONE_M BIT(10) + #define GLPCI_CNF2 0x000BE004 + #define GLPCI_CNF2_CACHELINE_SIZE_M BIT(1) + #define PF_FUNC_RID 0x0009E880 +diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c +index aac115136720..337156232501 100644 +--- a/drivers/net/ethernet/mscc/ocelot_board.c ++++ b/drivers/net/ethernet/mscc/ocelot_board.c +@@ -112,6 +112,14 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg) + if (err != 4) + break; + ++ /* At this point the IFH was read correctly, so it is safe to ++ * presume that there is no error. The err needs to be reset ++ * otherwise a frame could come in CPU queue between the while ++ * condition and the check for error later on. And in that case ++ * the new frame is just removed and not processed. ++ */ ++ err = 0; ++ + ocelot_parse_ifh(ifh, &info); + + dev = ocelot->ports[info.port]->dev; +diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h +index c303a92d5b06..1f27f9866b80 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede.h ++++ b/drivers/net/ethernet/qlogic/qede/qede.h +@@ -163,6 +163,8 @@ struct qede_rdma_dev { + struct list_head entry; + struct list_head rdma_event_list; + struct workqueue_struct *rdma_wq; ++ struct kref refcnt; ++ struct completion event_comp; + bool exp_recovery; + }; + +diff --git a/drivers/net/ethernet/qlogic/qede/qede_rdma.c b/drivers/net/ethernet/qlogic/qede/qede_rdma.c +index ffabc2d2f082..2d873ae8a234 100644 +--- a/drivers/net/ethernet/qlogic/qede/qede_rdma.c ++++ b/drivers/net/ethernet/qlogic/qede/qede_rdma.c +@@ -59,6 +59,9 @@ static void _qede_rdma_dev_add(struct qede_dev *edev) + static int qede_rdma_create_wq(struct qede_dev *edev) + { + INIT_LIST_HEAD(&edev->rdma_info.rdma_event_list); ++ kref_init(&edev->rdma_info.refcnt); ++ init_completion(&edev->rdma_info.event_comp); ++ + edev->rdma_info.rdma_wq = create_singlethread_workqueue("rdma_wq"); + if (!edev->rdma_info.rdma_wq) { + DP_NOTICE(edev, "qedr: Could not create workqueue\n"); +@@ -83,8 +86,23 @@ static void qede_rdma_cleanup_event(struct qede_dev *edev) + } + } + ++static void qede_rdma_complete_event(struct kref *ref) ++{ ++ struct qede_rdma_dev *rdma_dev = ++ container_of(ref, struct qede_rdma_dev, refcnt); ++ ++ /* no more events will be added after this */ ++ complete(&rdma_dev->event_comp); ++} ++ + static void qede_rdma_destroy_wq(struct qede_dev *edev) + { ++ /* Avoid race with add_event flow, make sure it finishes before ++ * we start accessing the list and cleaning up the work ++ */ ++ kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); ++ wait_for_completion(&edev->rdma_info.event_comp); ++ + qede_rdma_cleanup_event(edev); + destroy_workqueue(edev->rdma_info.rdma_wq); + } +@@ -310,15 +328,24 @@ static void qede_rdma_add_event(struct qede_dev *edev, + if (!edev->rdma_info.qedr_dev) + return; + ++ /* We don't want the cleanup flow to start while we're allocating and ++ * scheduling the work ++ */ ++ if (!kref_get_unless_zero(&edev->rdma_info.refcnt)) ++ return; /* already being destroyed */ ++ + event_node = qede_rdma_get_free_event_node(edev); + if (!event_node) +- return; ++ goto out; + + event_node->event = event; + event_node->ptr = edev; + + INIT_WORK(&event_node->work, qede_rdma_handle_event); + queue_work(edev->rdma_info.rdma_wq, &event_node->work); ++ ++out: ++ kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); + } + + void qede_rdma_dev_event_open(struct qede_dev *edev) +diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c +index eab83e71567a..6c0732fc8c25 100644 +--- a/drivers/net/hyperv/netvsc.c ++++ b/drivers/net/hyperv/netvsc.c +@@ -99,7 +99,7 @@ static struct netvsc_device *alloc_net_device(void) + + init_waitqueue_head(&net_device->wait_drain); + net_device->destroy = false; +- net_device->tx_disable = false; ++ net_device->tx_disable = true; + + net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT; + net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT; +diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c +index 0dee358864f3..ca16ae8c8332 100644 +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -973,6 +973,7 @@ static int netvsc_attach(struct net_device *ndev, + } + + /* In any case device is now ready */ ++ nvdev->tx_disable = false; + netif_device_attach(ndev); + + /* Note: enable and attach happen when sub-channels setup */ +@@ -2350,6 +2351,8 @@ static int netvsc_probe(struct hv_device *dev, + else + net->max_mtu = ETH_DATA_LEN; + ++ nvdev->tx_disable = false; ++ + ret = register_netdevice(net); + if (ret != 0) { + pr_err("Unable to register netdev.\n"); +diff --git a/drivers/net/phy/mdio-bcm-iproc.c b/drivers/net/phy/mdio-bcm-iproc.c +index 7e9975d25066..f1ded03f0229 100644 +--- a/drivers/net/phy/mdio-bcm-iproc.c ++++ b/drivers/net/phy/mdio-bcm-iproc.c +@@ -178,6 +178,23 @@ static int iproc_mdio_remove(struct platform_device *pdev) + return 0; + } + ++#ifdef CONFIG_PM_SLEEP ++int iproc_mdio_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct iproc_mdio_priv *priv = platform_get_drvdata(pdev); ++ ++ /* restore the mii clock configuration */ ++ iproc_mdio_config_clk(priv->base); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops iproc_mdio_pm_ops = { ++ .resume = iproc_mdio_resume ++}; ++#endif /* CONFIG_PM_SLEEP */ ++ + static const struct of_device_id iproc_mdio_of_match[] = { + { .compatible = "brcm,iproc-mdio", }, + { /* sentinel */ }, +@@ -188,6 +205,9 @@ static struct platform_driver iproc_mdio_driver = { + .driver = { + .name = "iproc-mdio", + .of_match_table = iproc_mdio_of_match, ++#ifdef CONFIG_PM_SLEEP ++ .pm = &iproc_mdio_pm_ops, ++#endif + }, + .probe = iproc_mdio_probe, + .remove = iproc_mdio_remove, +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 9485c8d1de8a..3b7a3b8a5e06 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -61,7 +61,6 @@ enum qmi_wwan_flags { + + enum qmi_wwan_quirks { + QMI_WWAN_QUIRK_DTR = 1 << 0, /* needs "set DTR" request */ +- QMI_WWAN_QUIRK_QUECTEL_DYNCFG = 1 << 1, /* check num. endpoints */ + }; + + struct qmimux_hdr { +@@ -916,16 +915,6 @@ static const struct driver_info qmi_wwan_info_quirk_dtr = { + .data = QMI_WWAN_QUIRK_DTR, + }; + +-static const struct driver_info qmi_wwan_info_quirk_quectel_dyncfg = { +- .description = "WWAN/QMI device", +- .flags = FLAG_WWAN | FLAG_SEND_ZLP, +- .bind = qmi_wwan_bind, +- .unbind = qmi_wwan_unbind, +- .manage_power = qmi_wwan_manage_power, +- .rx_fixup = qmi_wwan_rx_fixup, +- .data = QMI_WWAN_QUIRK_DTR | QMI_WWAN_QUIRK_QUECTEL_DYNCFG, +-}; +- + #define HUAWEI_VENDOR_ID 0x12D1 + + /* map QMI/wwan function by a fixed interface number */ +@@ -946,14 +935,18 @@ static const struct driver_info qmi_wwan_info_quirk_quectel_dyncfg = { + #define QMI_GOBI_DEVICE(vend, prod) \ + QMI_FIXED_INTF(vend, prod, 0) + +-/* Quectel does not use fixed interface numbers on at least some of their +- * devices. We need to check the number of endpoints to ensure that we bind to +- * the correct interface. ++/* Many devices have QMI and DIAG functions which are distinguishable ++ * from other vendor specific functions by class, subclass and ++ * protocol all being 0xff. The DIAG function has exactly 2 endpoints ++ * and is silently rejected when probed. ++ * ++ * This makes it possible to match dynamically numbered QMI functions ++ * as seen on e.g. many Quectel modems. + */ +-#define QMI_QUIRK_QUECTEL_DYNCFG(vend, prod) \ ++#define QMI_MATCH_FF_FF_FF(vend, prod) \ + USB_DEVICE_AND_INTERFACE_INFO(vend, prod, USB_CLASS_VENDOR_SPEC, \ + USB_SUBCLASS_VENDOR_SPEC, 0xff), \ +- .driver_info = (unsigned long)&qmi_wwan_info_quirk_quectel_dyncfg ++ .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr + + static const struct usb_device_id products[] = { + /* 1. CDC ECM like devices match on the control interface */ +@@ -1059,10 +1052,10 @@ static const struct usb_device_id products[] = { + USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), + .driver_info = (unsigned long)&qmi_wwan_info, + }, +- {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ +- {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ +- {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ +- {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ ++ {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ + + /* 3. Combined interface devices matching on interface number */ + {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ +@@ -1363,6 +1356,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(0x413c, 0x81d7, 0)}, /* Dell Wireless 5821e */ ++ {QMI_FIXED_INTF(0x413c, 0x81d7, 1)}, /* Dell Wireless 5821e preproduction config */ + {QMI_FIXED_INTF(0x413c, 0x81e0, 0)}, /* Dell Wireless 5821e with eSIM support*/ + {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 */ +@@ -1454,7 +1448,6 @@ static int qmi_wwan_probe(struct usb_interface *intf, + { + struct usb_device_id *id = (struct usb_device_id *)prod; + struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; +- const struct driver_info *info; + + /* Workaround to enable dynamic IDs. This disables usbnet + * blacklisting functionality. Which, if required, can be +@@ -1490,12 +1483,8 @@ static int qmi_wwan_probe(struct usb_interface *intf, + * different. Ignore the current interface if the number of endpoints + * equals the number for the diag interface (two). + */ +- info = (void *)id->driver_info; +- +- if (info->data & QMI_WWAN_QUIRK_QUECTEL_DYNCFG) { +- if (desc->bNumEndpoints == 2) +- return -ENODEV; +- } ++ if (desc->bNumEndpoints == 2) ++ return -ENODEV; + + return usbnet_probe(intf, id); + } +diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h +index 547ff3c578ee..fa5634af40f7 100644 +--- a/drivers/net/wireless/marvell/mwifiex/main.h ++++ b/drivers/net/wireless/marvell/mwifiex/main.h +@@ -1295,19 +1295,6 @@ mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len) + return pos; + } + +-/* This function return interface number with the same bss_type. +- */ +-static inline u8 +-mwifiex_get_intf_num(struct mwifiex_adapter *adapter, u8 bss_type) +-{ +- u8 i, num = 0; +- +- for (i = 0; i < adapter->priv_num; i++) +- if (adapter->priv[i] && adapter->priv[i]->bss_type == bss_type) +- num++; +- return num; +-} +- + /* + * This function returns the correct private structure pointer based + * upon the BSS type and BSS number. +diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c +index 7caf1d26124a..f8f282ce39bd 100644 +--- a/drivers/net/wireless/marvell/mwifiex/tdls.c ++++ b/drivers/net/wireless/marvell/mwifiex/tdls.c +@@ -894,7 +894,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + u8 *peer, *pos, *end; + u8 i, action, basic; + u16 cap = 0; +- int ie_len = 0; ++ int ies_len = 0; + + if (len < (sizeof(struct ethhdr) + 3)) + return; +@@ -916,7 +916,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + pos = buf + sizeof(struct ethhdr) + 4; + /* payload 1+ category 1 + action 1 + dialog 1 */ + cap = get_unaligned_le16(pos); +- ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; ++ ies_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; + pos += 2; + break; + +@@ -926,7 +926,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/ + pos = buf + sizeof(struct ethhdr) + 6; + cap = get_unaligned_le16(pos); +- ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; ++ ies_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; + pos += 2; + break; + +@@ -934,7 +934,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN)) + return; + pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN; +- ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; ++ ies_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; + break; + default: + mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n"); +@@ -947,33 +947,33 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + + sta_ptr->tdls_cap.capab = cpu_to_le16(cap); + +- for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) { +- if (pos + 2 + pos[1] > end) ++ for (end = pos + ies_len; pos + 1 < end; pos += 2 + pos[1]) { ++ u8 ie_len = pos[1]; ++ ++ if (pos + 2 + ie_len > end) + break; + + switch (*pos) { + case WLAN_EID_SUPP_RATES: +- if (pos[1] > 32) ++ if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) + return; +- sta_ptr->tdls_cap.rates_len = pos[1]; +- for (i = 0; i < pos[1]; i++) ++ sta_ptr->tdls_cap.rates_len = ie_len; ++ for (i = 0; i < ie_len; i++) + sta_ptr->tdls_cap.rates[i] = pos[i + 2]; + break; + + case WLAN_EID_EXT_SUPP_RATES: +- if (pos[1] > 32) ++ if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) + return; + basic = sta_ptr->tdls_cap.rates_len; +- if (pos[1] > 32 - basic) ++ if (ie_len > sizeof(sta_ptr->tdls_cap.rates) - basic) + return; +- for (i = 0; i < pos[1]; i++) ++ for (i = 0; i < ie_len; i++) + sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2]; +- sta_ptr->tdls_cap.rates_len += pos[1]; ++ sta_ptr->tdls_cap.rates_len += ie_len; + break; + case WLAN_EID_HT_CAPABILITY: +- if (pos > end - sizeof(struct ieee80211_ht_cap) - 2) +- return; +- if (pos[1] != sizeof(struct ieee80211_ht_cap)) ++ if (ie_len != sizeof(struct ieee80211_ht_cap)) + return; + /* copy the ie's value into ht_capb*/ + memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2, +@@ -981,59 +981,45 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + sta_ptr->is_11n_enabled = 1; + break; + case WLAN_EID_HT_OPERATION: +- if (pos > end - +- sizeof(struct ieee80211_ht_operation) - 2) +- return; +- if (pos[1] != sizeof(struct ieee80211_ht_operation)) ++ if (ie_len != sizeof(struct ieee80211_ht_operation)) + return; + /* copy the ie's value into ht_oper*/ + memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2, + sizeof(struct ieee80211_ht_operation)); + break; + case WLAN_EID_BSS_COEX_2040: +- if (pos > end - 3) +- return; +- if (pos[1] != 1) ++ if (ie_len != sizeof(pos[2])) + return; + sta_ptr->tdls_cap.coex_2040 = pos[2]; + break; + case WLAN_EID_EXT_CAPABILITY: +- if (pos > end - sizeof(struct ieee_types_header)) +- return; +- if (pos[1] < sizeof(struct ieee_types_header)) ++ if (ie_len < sizeof(struct ieee_types_header)) + return; +- if (pos[1] > 8) ++ if (ie_len > 8) + return; + memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos, + sizeof(struct ieee_types_header) + +- min_t(u8, pos[1], 8)); ++ min_t(u8, ie_len, 8)); + break; + case WLAN_EID_RSN: +- if (pos > end - sizeof(struct ieee_types_header)) ++ if (ie_len < sizeof(struct ieee_types_header)) + return; +- if (pos[1] < sizeof(struct ieee_types_header)) +- return; +- if (pos[1] > IEEE_MAX_IE_SIZE - ++ if (ie_len > IEEE_MAX_IE_SIZE - + sizeof(struct ieee_types_header)) + return; + memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, + sizeof(struct ieee_types_header) + +- min_t(u8, pos[1], IEEE_MAX_IE_SIZE - ++ min_t(u8, ie_len, IEEE_MAX_IE_SIZE - + sizeof(struct ieee_types_header))); + break; + case WLAN_EID_QOS_CAPA: +- if (pos > end - 3) +- return; +- if (pos[1] != 1) ++ if (ie_len != sizeof(pos[2])) + return; + sta_ptr->tdls_cap.qos_info = pos[2]; + break; + case WLAN_EID_VHT_OPERATION: + if (priv->adapter->is_hw_11ac_capable) { +- if (pos > end - +- sizeof(struct ieee80211_vht_operation) - 2) +- return; +- if (pos[1] != ++ if (ie_len != + sizeof(struct ieee80211_vht_operation)) + return; + /* copy the ie's value into vhtoper*/ +@@ -1043,10 +1029,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + break; + case WLAN_EID_VHT_CAPABILITY: + if (priv->adapter->is_hw_11ac_capable) { +- if (pos > end - +- sizeof(struct ieee80211_vht_cap) - 2) +- return; +- if (pos[1] != sizeof(struct ieee80211_vht_cap)) ++ if (ie_len != sizeof(struct ieee80211_vht_cap)) + return; + /* copy the ie's value into vhtcap*/ + memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2, +@@ -1056,9 +1039,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, + break; + case WLAN_EID_AID: + if (priv->adapter->is_hw_11ac_capable) { +- if (pos > end - 4) +- return; +- if (pos[1] != 2) ++ if (ie_len != sizeof(u16)) + return; + sta_ptr->tdls_cap.aid = + get_unaligned_le16((pos + 2)); +diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c +index 720c89d6066e..4ac8cb262559 100644 +--- a/drivers/nfc/pn544/i2c.c ++++ b/drivers/nfc/pn544/i2c.c +@@ -225,6 +225,7 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) + + out: + gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); ++ usleep_range(10000, 15000); + } + + static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode) +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index e703827d27e9..7dacfd102a99 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -66,8 +66,8 @@ MODULE_PARM_DESC(streams, "turn on support for Streams write directives"); + * nvme_reset_wq - hosts nvme reset works + * nvme_delete_wq - hosts nvme delete works + * +- * nvme_wq will host works such are scan, aen handling, fw activation, +- * keep-alive error recovery, periodic reconnects etc. nvme_reset_wq ++ * nvme_wq will host works such as scan, aen handling, fw activation, ++ * keep-alive, periodic reconnects etc. nvme_reset_wq + * runs reset works which also flush works hosted on nvme_wq for + * serialization purposes. nvme_delete_wq host controller deletion + * works which flush reset works for serialization. +@@ -972,7 +972,7 @@ static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status) + startka = true; + spin_unlock_irqrestore(&ctrl->lock, flags); + if (startka) +- schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); ++ queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); + } + + static int nvme_keep_alive(struct nvme_ctrl *ctrl) +@@ -1002,7 +1002,7 @@ static void nvme_keep_alive_work(struct work_struct *work) + dev_dbg(ctrl->device, + "reschedule traffic based keep-alive timer\n"); + ctrl->comp_seen = false; +- schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); ++ queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); + return; + } + +@@ -1019,7 +1019,7 @@ static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) + if (unlikely(ctrl->kato == 0)) + return; + +- schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); ++ queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); + } + + void nvme_stop_keep_alive(struct nvme_ctrl *ctrl) +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index f34a56d588d3..570c75c92e29 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -1084,9 +1084,9 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx) + + spin_lock(&nvmeq->cq_poll_lock); + found = nvme_process_cq(nvmeq, &start, &end, -1); ++ nvme_complete_cqes(nvmeq, start, end); + spin_unlock(&nvmeq->cq_poll_lock); + +- nvme_complete_cqes(nvmeq, start, end); + return found; + } + +@@ -1407,6 +1407,23 @@ static void nvme_disable_admin_queue(struct nvme_dev *dev, bool shutdown) + nvme_poll_irqdisable(nvmeq, -1); + } + ++/* ++ * Called only on a device that has been disabled and after all other threads ++ * that can check this device's completion queues have synced. This is the ++ * last chance for the driver to see a natural completion before ++ * nvme_cancel_request() terminates all incomplete requests. ++ */ ++static void nvme_reap_pending_cqes(struct nvme_dev *dev) ++{ ++ u16 start, end; ++ int i; ++ ++ for (i = dev->ctrl.queue_count - 1; i > 0; i--) { ++ nvme_process_cq(&dev->queues[i], &start, &end, -1); ++ nvme_complete_cqes(&dev->queues[i], start, end); ++ } ++} ++ + static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues, + int entry_size) + { +@@ -2241,11 +2258,6 @@ static bool __nvme_disable_io_queues(struct nvme_dev *dev, u8 opcode) + if (timeout == 0) + return false; + +- /* handle any remaining CQEs */ +- if (opcode == nvme_admin_delete_cq && +- !test_bit(NVMEQ_DELETE_ERROR, &nvmeq->flags)) +- nvme_poll_irqdisable(nvmeq, -1); +- + sent--; + if (nr_queues) + goto retry; +@@ -2434,6 +2446,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) + nvme_suspend_io_queues(dev); + nvme_suspend_queue(&dev->queues[0]); + nvme_pci_disable(dev); ++ nvme_reap_pending_cqes(dev); + + blk_mq_tagset_busy_iter(&dev->tagset, nvme_cancel_request, &dev->ctrl); + blk_mq_tagset_busy_iter(&dev->admin_tagset, nvme_cancel_request, &dev->ctrl); +diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c +index cb4c3000a57e..4ff51da3b13f 100644 +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -1088,7 +1088,7 @@ static void nvme_rdma_error_recovery(struct nvme_rdma_ctrl *ctrl) + if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING)) + return; + +- queue_work(nvme_wq, &ctrl->err_work); ++ queue_work(nvme_reset_wq, &ctrl->err_work); + } + + static void nvme_rdma_wr_error(struct ib_cq *cq, struct ib_wc *wc, +diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c +index 7544be84ab35..244984420b41 100644 +--- a/drivers/nvme/host/tcp.c ++++ b/drivers/nvme/host/tcp.c +@@ -422,7 +422,7 @@ static void nvme_tcp_error_recovery(struct nvme_ctrl *ctrl) + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + return; + +- queue_work(nvme_wq, &to_tcp_ctrl(ctrl)->err_work); ++ queue_work(nvme_reset_wq, &to_tcp_ctrl(ctrl)->err_work); + } + + static int nvme_tcp_process_nvme_cqe(struct nvme_tcp_queue *queue, +@@ -1054,7 +1054,12 @@ static void nvme_tcp_io_work(struct work_struct *w) + } else if (unlikely(result < 0)) { + dev_err(queue->ctrl->ctrl.device, + "failed to send request %d\n", result); +- if (result != -EPIPE) ++ ++ /* ++ * Fail the request unless peer closed the connection, ++ * in which case error recovery flow will complete all. ++ */ ++ if ((result != -EPIPE) && (result != -ECONNRESET)) + nvme_tcp_fail_request(queue->request); + nvme_tcp_done_send_req(queue); + return; +diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c +index 191f410cf35c..2f8787276d9b 100644 +--- a/drivers/perf/arm_smmuv3_pmu.c ++++ b/drivers/perf/arm_smmuv3_pmu.c +@@ -772,7 +772,7 @@ static int smmu_pmu_probe(struct platform_device *pdev) + smmu_pmu->reloc_base = smmu_pmu->reg_base; + } + +- irq = platform_get_irq(pdev, 0); ++ irq = platform_get_irq_optional(pdev, 0); + if (irq > 0) + smmu_pmu->irq = irq; + +diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c +index e36fcad668a6..88a3c5690fea 100644 +--- a/drivers/pwm/pwm-omap-dmtimer.c ++++ b/drivers/pwm/pwm-omap-dmtimer.c +@@ -256,7 +256,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) + if (!timer_pdev) { + dev_err(&pdev->dev, "Unable to find Timer pdev\n"); + ret = -ENODEV; +- goto put; ++ goto err_find_timer_pdev; + } + + timer_pdata = dev_get_platdata(&timer_pdev->dev); +@@ -264,7 +264,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) + dev_dbg(&pdev->dev, + "dmtimer pdata structure NULL, deferring probe\n"); + ret = -EPROBE_DEFER; +- goto put; ++ goto err_platdata; + } + + pdata = timer_pdata->timer_ops; +@@ -283,19 +283,19 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) + !pdata->write_counter) { + dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); + ret = -EINVAL; +- goto put; ++ goto err_platdata; + } + + if (!of_get_property(timer, "ti,timer-pwm", NULL)) { + dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); + ret = -ENODEV; +- goto put; ++ goto err_timer_property; + } + + dm_timer = pdata->request_by_node(timer); + if (!dm_timer) { + ret = -EPROBE_DEFER; +- goto put; ++ goto err_request_timer; + } + + omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); +@@ -352,7 +352,14 @@ err_pwmchip_add: + err_alloc_omap: + + pdata->free(dm_timer); +-put: ++err_request_timer: ++ ++err_timer_property: ++err_platdata: ++ ++ put_device(&timer_pdev->dev); ++err_find_timer_pdev: ++ + of_node_put(timer); + + return ret; +@@ -372,6 +379,8 @@ static int pwm_omap_dmtimer_remove(struct platform_device *pdev) + + omap->pdata->free(omap->dm_timer); + ++ put_device(&omap->dm_timer_pdev->dev); ++ + mutex_destroy(&omap->mutex); + + return 0; +diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h +index bb35ba4a8d24..4348fdff1c61 100644 +--- a/drivers/s390/crypto/ap_bus.h ++++ b/drivers/s390/crypto/ap_bus.h +@@ -162,7 +162,7 @@ struct ap_card { + unsigned int functions; /* AP device function bitfield. */ + int queue_depth; /* AP queue depth.*/ + int id; /* AP card number. */ +- atomic_t total_request_count; /* # requests ever for this AP device.*/ ++ atomic64_t total_request_count; /* # requests ever for this AP device.*/ + }; + + #define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device) +@@ -179,7 +179,7 @@ struct ap_queue { + enum ap_state state; /* State of the AP device. */ + int pendingq_count; /* # requests on pendingq list. */ + int requestq_count; /* # requests on requestq list. */ +- int total_request_count; /* # requests ever for this AP device.*/ ++ u64 total_request_count; /* # requests ever for this AP device.*/ + int request_timeout; /* Request timeout in jiffies. */ + struct timer_list timeout; /* Timer for request timeouts. */ + struct list_head pendingq; /* List of message sent to AP queue. */ +diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c +index 63b4cc6cd7e5..e85bfca1ed16 100644 +--- a/drivers/s390/crypto/ap_card.c ++++ b/drivers/s390/crypto/ap_card.c +@@ -63,13 +63,13 @@ static ssize_t request_count_show(struct device *dev, + char *buf) + { + struct ap_card *ac = to_ap_card(dev); +- unsigned int req_cnt; ++ u64 req_cnt; + + req_cnt = 0; + spin_lock_bh(&ap_list_lock); +- req_cnt = atomic_read(&ac->total_request_count); ++ req_cnt = atomic64_read(&ac->total_request_count); + spin_unlock_bh(&ap_list_lock); +- return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); ++ return snprintf(buf, PAGE_SIZE, "%llu\n", req_cnt); + } + + static ssize_t request_count_store(struct device *dev, +@@ -83,7 +83,7 @@ static ssize_t request_count_store(struct device *dev, + for_each_ap_queue(aq, ac) + aq->total_request_count = 0; + spin_unlock_bh(&ap_list_lock); +- atomic_set(&ac->total_request_count, 0); ++ atomic64_set(&ac->total_request_count, 0); + + return count; + } +diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c +index 37c3bdc3642d..a317ab484932 100644 +--- a/drivers/s390/crypto/ap_queue.c ++++ b/drivers/s390/crypto/ap_queue.c +@@ -479,12 +479,12 @@ static ssize_t request_count_show(struct device *dev, + char *buf) + { + struct ap_queue *aq = to_ap_queue(dev); +- unsigned int req_cnt; ++ u64 req_cnt; + + spin_lock_bh(&aq->lock); + req_cnt = aq->total_request_count; + spin_unlock_bh(&aq->lock); +- return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); ++ return snprintf(buf, PAGE_SIZE, "%llu\n", req_cnt); + } + + static ssize_t request_count_store(struct device *dev, +@@ -676,7 +676,7 @@ void ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg) + list_add_tail(&ap_msg->list, &aq->requestq); + aq->requestq_count++; + aq->total_request_count++; +- atomic_inc(&aq->card->total_request_count); ++ atomic64_inc(&aq->card->total_request_count); + /* Send/receive as many request from the queue as possible. */ + ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL)); + spin_unlock_bh(&aq->lock); +diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c +index 9157e728a362..7fa0262e91af 100644 +--- a/drivers/s390/crypto/zcrypt_api.c ++++ b/drivers/s390/crypto/zcrypt_api.c +@@ -605,8 +605,8 @@ static inline bool zcrypt_card_compare(struct zcrypt_card *zc, + weight += atomic_read(&zc->load); + pref_weight += atomic_read(&pref_zc->load); + if (weight == pref_weight) +- return atomic_read(&zc->card->total_request_count) > +- atomic_read(&pref_zc->card->total_request_count); ++ return atomic64_read(&zc->card->total_request_count) > ++ atomic64_read(&pref_zc->card->total_request_count); + return weight > pref_weight; + } + +@@ -1216,11 +1216,12 @@ static void zcrypt_qdepth_mask(char qdepth[], size_t max_adapters) + spin_unlock(&zcrypt_list_lock); + } + +-static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters) ++static void zcrypt_perdev_reqcnt(u32 reqcnt[], size_t max_adapters) + { + struct zcrypt_card *zc; + struct zcrypt_queue *zq; + int card; ++ u64 cnt; + + memset(reqcnt, 0, sizeof(int) * max_adapters); + spin_lock(&zcrypt_list_lock); +@@ -1232,8 +1233,9 @@ static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters) + || card >= max_adapters) + continue; + spin_lock(&zq->queue->lock); +- reqcnt[card] = zq->queue->total_request_count; ++ cnt = zq->queue->total_request_count; + spin_unlock(&zq->queue->lock); ++ reqcnt[card] = (cnt < UINT_MAX) ? (u32) cnt : UINT_MAX; + } + } + local_bh_enable(); +@@ -1411,9 +1413,9 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, + return 0; + } + case ZCRYPT_PERDEV_REQCNT: { +- int *reqcnt; ++ u32 *reqcnt; + +- reqcnt = kcalloc(AP_DEVICES, sizeof(int), GFP_KERNEL); ++ reqcnt = kcalloc(AP_DEVICES, sizeof(u32), GFP_KERNEL); + if (!reqcnt) + return -ENOMEM; + zcrypt_perdev_reqcnt(reqcnt, AP_DEVICES); +@@ -1470,7 +1472,7 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, + } + case Z90STAT_PERDEV_REQCNT: { + /* the old ioctl supports only 64 adapters */ +- int reqcnt[MAX_ZDEV_CARDIDS]; ++ u32 reqcnt[MAX_ZDEV_CARDIDS]; + + zcrypt_perdev_reqcnt(reqcnt, MAX_ZDEV_CARDIDS); + if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt))) +diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c +index 59e220749ad1..92bace3b28fd 100644 +--- a/drivers/s390/net/qeth_l2_main.c ++++ b/drivers/s390/net/qeth_l2_main.c +@@ -1846,15 +1846,14 @@ int qeth_l2_vnicc_set_state(struct qeth_card *card, u32 vnicc, bool state) + + QETH_CARD_TEXT(card, 2, "vniccsch"); + +- /* do not change anything if BridgePort is enabled */ +- if (qeth_bridgeport_is_in_use(card)) +- return -EBUSY; +- + /* check if characteristic and enable/disable are supported */ + if (!(card->options.vnicc.sup_chars & vnicc) || + !(card->options.vnicc.set_char_sup & vnicc)) + return -EOPNOTSUPP; + ++ if (qeth_bridgeport_is_in_use(card)) ++ return -EBUSY; ++ + /* set enable/disable command and store wanted characteristic */ + if (state) { + cmd = IPA_VNICC_ENABLE; +@@ -1900,14 +1899,13 @@ int qeth_l2_vnicc_get_state(struct qeth_card *card, u32 vnicc, bool *state) + + QETH_CARD_TEXT(card, 2, "vniccgch"); + +- /* do not get anything if BridgePort is enabled */ +- if (qeth_bridgeport_is_in_use(card)) +- return -EBUSY; +- + /* check if characteristic is supported */ + if (!(card->options.vnicc.sup_chars & vnicc)) + return -EOPNOTSUPP; + ++ if (qeth_bridgeport_is_in_use(card)) ++ return -EBUSY; ++ + /* if card is ready, query current VNICC state */ + if (qeth_card_hw_is_reachable(card)) + rc = qeth_l2_vnicc_query_chars(card); +@@ -1925,15 +1923,14 @@ int qeth_l2_vnicc_set_timeout(struct qeth_card *card, u32 timeout) + + QETH_CARD_TEXT(card, 2, "vniccsto"); + +- /* do not change anything if BridgePort is enabled */ +- if (qeth_bridgeport_is_in_use(card)) +- return -EBUSY; +- + /* check if characteristic and set_timeout are supported */ + if (!(card->options.vnicc.sup_chars & QETH_VNICC_LEARNING) || + !(card->options.vnicc.getset_timeout_sup & QETH_VNICC_LEARNING)) + return -EOPNOTSUPP; + ++ if (qeth_bridgeport_is_in_use(card)) ++ return -EBUSY; ++ + /* do we need to do anything? */ + if (card->options.vnicc.learning_timeout == timeout) + return rc; +@@ -1962,14 +1959,14 @@ int qeth_l2_vnicc_get_timeout(struct qeth_card *card, u32 *timeout) + + QETH_CARD_TEXT(card, 2, "vniccgto"); + +- /* do not get anything if BridgePort is enabled */ +- if (qeth_bridgeport_is_in_use(card)) +- return -EBUSY; +- + /* check if characteristic and get_timeout are supported */ + if (!(card->options.vnicc.sup_chars & QETH_VNICC_LEARNING) || + !(card->options.vnicc.getset_timeout_sup & QETH_VNICC_LEARNING)) + return -EOPNOTSUPP; ++ ++ if (qeth_bridgeport_is_in_use(card)) ++ return -EBUSY; ++ + /* if card is ready, get timeout. Otherwise, just return stored value */ + *timeout = card->options.vnicc.learning_timeout; + if (qeth_card_hw_is_reachable(card)) +diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c +index be9424a87173..9c3ef0a02fd4 100644 +--- a/drivers/soc/tegra/fuse/fuse-tegra30.c ++++ b/drivers/soc/tegra/fuse/fuse-tegra30.c +@@ -35,7 +35,8 @@ + defined(CONFIG_ARCH_TEGRA_124_SOC) || \ + defined(CONFIG_ARCH_TEGRA_132_SOC) || \ + defined(CONFIG_ARCH_TEGRA_210_SOC) || \ +- defined(CONFIG_ARCH_TEGRA_186_SOC) ++ defined(CONFIG_ARCH_TEGRA_186_SOC) || \ ++ defined(CONFIG_ARCH_TEGRA_194_SOC) + static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset) + { + if (WARN_ON(!fuse->base)) +diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c +index 5825ac581f56..680f1a070606 100644 +--- a/drivers/thermal/broadcom/brcmstb_thermal.c ++++ b/drivers/thermal/broadcom/brcmstb_thermal.c +@@ -49,7 +49,7 @@ + #define AVS_TMON_TP_TEST_ENABLE 0x20 + + /* Default coefficients */ +-#define AVS_TMON_TEMP_SLOPE -487 ++#define AVS_TMON_TEMP_SLOPE 487 + #define AVS_TMON_TEMP_OFFSET 410040 + + /* HW related temperature constants */ +@@ -108,23 +108,12 @@ struct brcmstb_thermal_priv { + struct thermal_zone_device *thermal; + }; + +-static void avs_tmon_get_coeffs(struct thermal_zone_device *tz, int *slope, +- int *offset) +-{ +- *slope = thermal_zone_get_slope(tz); +- *offset = thermal_zone_get_offset(tz); +-} +- + /* Convert a HW code to a temperature reading (millidegree celsius) */ + static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz, + u32 code) + { +- const int val = code & AVS_TMON_TEMP_MASK; +- int slope, offset; +- +- avs_tmon_get_coeffs(tz, &slope, &offset); +- +- return slope * val + offset; ++ return (AVS_TMON_TEMP_OFFSET - ++ (int)((code & AVS_TMON_TEMP_MAX) * AVS_TMON_TEMP_SLOPE)); + } + + /* +@@ -136,20 +125,18 @@ static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz, + static inline u32 avs_tmon_temp_to_code(struct thermal_zone_device *tz, + int temp, bool low) + { +- int slope, offset; +- + if (temp < AVS_TMON_TEMP_MIN) +- return AVS_TMON_TEMP_MAX; /* Maximum code value */ +- +- avs_tmon_get_coeffs(tz, &slope, &offset); ++ return AVS_TMON_TEMP_MAX; /* Maximum code value */ + +- if (temp >= offset) ++ if (temp >= AVS_TMON_TEMP_OFFSET) + return 0; /* Minimum code value */ + + if (low) +- return (u32)(DIV_ROUND_UP(offset - temp, abs(slope))); ++ return (u32)(DIV_ROUND_UP(AVS_TMON_TEMP_OFFSET - temp, ++ AVS_TMON_TEMP_SLOPE)); + else +- return (u32)((offset - temp) / abs(slope)); ++ return (u32)((AVS_TMON_TEMP_OFFSET - temp) / ++ AVS_TMON_TEMP_SLOPE); + } + + static int brcmstb_get_temp(void *data, int *temp) +diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c +index 372dbbaaafb8..21d4d6e6409a 100644 +--- a/drivers/thermal/db8500_thermal.c ++++ b/drivers/thermal/db8500_thermal.c +@@ -152,8 +152,8 @@ static irqreturn_t prcmu_high_irq_handler(int irq, void *irq_data) + db8500_thermal_update_config(th, idx, THERMAL_TREND_RAISING, + next_low, next_high); + +- dev_info(&th->tz->device, +- "PRCMU set max %ld, min %ld\n", next_high, next_low); ++ dev_dbg(&th->tz->device, ++ "PRCMU set max %ld, min %ld\n", next_high, next_low); + } else if (idx == num_points - 1) + /* So we roof out 1 degree over the max point */ + th->interpolated_temp = db8500_thermal_points[idx] + 1; +diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c +index 1a2dd53caade..b53b6528d6ce 100644 +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -1414,10 +1414,6 @@ static int vhost_net_release(struct inode *inode, struct file *f) + + static struct socket *get_raw_socket(int fd) + { +- struct { +- struct sockaddr_ll sa; +- char buf[MAX_ADDR_LEN]; +- } uaddr; + int r; + struct socket *sock = sockfd_lookup(fd, &r); + +@@ -1430,11 +1426,7 @@ static struct socket *get_raw_socket(int fd) + goto err; + } + +- r = sock->ops->getname(sock, (struct sockaddr *)&uaddr.sa, 0); +- if (r < 0) +- goto err; +- +- if (uaddr.sa.sll_family != AF_PACKET) { ++ if (sock->sk->sk_family != AF_PACKET) { + r = -EPFNOSUPPORT; + goto err; + } +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index e7cf41aa26c3..1ce39de917f0 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -389,7 +389,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + memset(&r, 0, sizeof(r)); + r.start = gas->address; +- r.end = r.start + gas->access_width - 1; ++ r.end = r.start + ACPI_ACCESS_BYTE_WIDTH(gas->access_width) - 1; + if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + r.flags = IORESOURCE_MEM; + } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { +diff --git a/fs/ceph/file.c b/fs/ceph/file.c +index 11929d2bb594..cd09e63d682b 100644 +--- a/fs/ceph/file.c ++++ b/fs/ceph/file.c +@@ -1418,6 +1418,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) + struct ceph_cap_flush *prealloc_cf; + ssize_t count, written = 0; + int err, want, got; ++ bool direct_lock = false; + loff_t pos; + loff_t limit = max(i_size_read(inode), fsc->max_file_size); + +@@ -1428,8 +1429,11 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) + if (!prealloc_cf) + return -ENOMEM; + ++ if ((iocb->ki_flags & (IOCB_DIRECT | IOCB_APPEND)) == IOCB_DIRECT) ++ direct_lock = true; ++ + retry_snap: +- if (iocb->ki_flags & IOCB_DIRECT) ++ if (direct_lock) + ceph_start_io_direct(inode); + else + ceph_start_io_write(inode); +@@ -1519,14 +1523,15 @@ retry_snap: + + /* we might need to revert back to that point */ + data = *from; +- if (iocb->ki_flags & IOCB_DIRECT) { ++ if (iocb->ki_flags & IOCB_DIRECT) + written = ceph_direct_read_write(iocb, &data, snapc, + &prealloc_cf); +- ceph_end_io_direct(inode); +- } else { ++ else + written = ceph_sync_write(iocb, &data, pos, snapc); ++ if (direct_lock) ++ ceph_end_io_direct(inode); ++ else + ceph_end_io_write(inode); +- } + if (written > 0) + iov_iter_advance(from, written); + ceph_put_snap_context(snapc); +@@ -1577,7 +1582,7 @@ retry_snap: + + goto out_unlocked; + out: +- if (iocb->ki_flags & IOCB_DIRECT) ++ if (direct_lock) + ceph_end_io_direct(inode); + else + ceph_end_io_write(inode); +diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c +index f842944a5c76..1619af216677 100644 +--- a/fs/cifs/cifsacl.c ++++ b/fs/cifs/cifsacl.c +@@ -603,7 +603,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, + ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) + *pmode |= (S_IXUGO & (*pbits_to_set)); + +- cifs_dbg(NOISY, "access flags 0x%x mode now 0x%x\n", flags, *pmode); ++ cifs_dbg(NOISY, "access flags 0x%x mode now %04o\n", flags, *pmode); + return; + } + +@@ -632,7 +632,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, + if (mode & S_IXUGO) + *pace_flags |= SET_FILE_EXEC_RIGHTS; + +- cifs_dbg(NOISY, "mode: 0x%x, access flags now 0x%x\n", ++ cifs_dbg(NOISY, "mode: %04o, access flags now 0x%x\n", + mode, *pace_flags); + return; + } +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 5d3c867bdc80..bcda48c03882 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -4094,7 +4094,7 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, + cifs_sb->mnt_gid = pvolume_info->linux_gid; + cifs_sb->mnt_file_mode = pvolume_info->file_mode; + cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; +- cifs_dbg(FYI, "file mode: 0x%hx dir mode: 0x%hx\n", ++ cifs_dbg(FYI, "file mode: %04ho dir mode: %04ho\n", + cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); + + cifs_sb->actimeo = pvolume_info->actimeo; +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index ed59e4a8db59..aafcd79c4772 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -1586,7 +1586,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) + struct TCP_Server_Info *server; + char *full_path; + +- cifs_dbg(FYI, "In cifs_mkdir, mode = 0x%hx inode = 0x%p\n", ++ cifs_dbg(FYI, "In cifs_mkdir, mode = %04ho inode = 0x%p\n", + mode, inode); + + cifs_sb = CIFS_SB(inode->i_sb); +diff --git a/fs/dax.c b/fs/dax.c +index 2cc43cd914eb..cc56313c6b3b 100644 +--- a/fs/dax.c ++++ b/fs/dax.c +@@ -1207,6 +1207,9 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, + lockdep_assert_held(&inode->i_rwsem); + } + ++ if (iocb->ki_flags & IOCB_NOWAIT) ++ flags |= IOMAP_NOWAIT; ++ + while (iov_iter_count(iter)) { + ret = iomap_apply(inode, pos, iov_iter_count(iter), flags, ops, + iter, dax_iomap_actor); +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 3ca604807839..8bd806a03a90 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2343,7 +2343,7 @@ int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct flex_groups **old_groups, **new_groups; +- int size, i; ++ int size, i, j; + + if (!sbi->s_log_groups_per_flex) + return 0; +@@ -2364,8 +2364,8 @@ int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup) + sizeof(struct flex_groups)), + GFP_KERNEL); + if (!new_groups[i]) { +- for (i--; i >= sbi->s_flex_groups_allocated; i--) +- kvfree(new_groups[i]); ++ for (j = sbi->s_flex_groups_allocated; j < i; j++) ++ kvfree(new_groups[j]); + kvfree(new_groups); + ext4_msg(sb, KERN_ERR, + "not enough memory for %d flex groups", size); +diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c +index 5d6fd940aab2..ec9a1f9ce2dd 100644 +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -3030,7 +3030,8 @@ int f2fs_migrate_page(struct address_space *mapping, + + #ifdef CONFIG_SWAP + /* Copied from generic_swapfile_activate() to check any holes */ +-static int check_swap_activate(struct file *swap_file, unsigned int max) ++static int check_swap_activate(struct swap_info_struct *sis, ++ struct file *swap_file, sector_t *span) + { + struct address_space *mapping = swap_file->f_mapping; + struct inode *inode = mapping->host; +@@ -3041,6 +3042,8 @@ static int check_swap_activate(struct file *swap_file, unsigned int max) + sector_t last_block; + sector_t lowest_block = -1; + sector_t highest_block = 0; ++ int nr_extents = 0; ++ int ret; + + blkbits = inode->i_blkbits; + blocks_per_page = PAGE_SIZE >> blkbits; +@@ -3052,7 +3055,8 @@ static int check_swap_activate(struct file *swap_file, unsigned int max) + probe_block = 0; + page_no = 0; + last_block = i_size_read(inode) >> blkbits; +- while ((probe_block + blocks_per_page) <= last_block && page_no < max) { ++ while ((probe_block + blocks_per_page) <= last_block && ++ page_no < sis->max) { + unsigned block_in_page; + sector_t first_block; + +@@ -3092,13 +3096,27 @@ static int check_swap_activate(struct file *swap_file, unsigned int max) + highest_block = first_block; + } + ++ /* ++ * We found a PAGE_SIZE-length, PAGE_SIZE-aligned run of blocks ++ */ ++ ret = add_swap_extent(sis, page_no, 1, first_block); ++ if (ret < 0) ++ goto out; ++ nr_extents += ret; + page_no++; + probe_block += blocks_per_page; + reprobe: + continue; + } +- return 0; +- ++ ret = nr_extents; ++ *span = 1 + highest_block - lowest_block; ++ if (page_no == 0) ++ page_no = 1; /* force Empty message */ ++ sis->max = page_no; ++ sis->pages = page_no - 1; ++ sis->highest_bit = page_no - 1; ++out: ++ return ret; + bad_bmap: + pr_err("swapon: swapfile has holes\n"); + return -EINVAL; +@@ -3120,14 +3138,14 @@ static int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file, + if (ret) + return ret; + +- ret = check_swap_activate(file, sis->max); +- if (ret) ++ ret = check_swap_activate(sis, file, span); ++ if (ret < 0) + return ret; + + set_inode_flag(inode, FI_PIN_FILE); + f2fs_precache_extents(inode); + f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); +- return 0; ++ return ret; + } + + static void f2fs_swap_deactivate(struct file *file) +diff --git a/fs/io_uring.c b/fs/io_uring.c +index ed9a551882cf..e37b84146453 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -71,6 +71,7 @@ + #include + #include + #include ++#include + + #include + +@@ -334,6 +335,8 @@ struct io_kiocb { + u32 result; + u32 sequence; + ++ struct fs_struct *fs; ++ + struct work_struct work; + }; + +@@ -651,6 +654,7 @@ static struct io_kiocb *io_get_req(struct io_ring_ctx *ctx, + /* one is dropped after submission, the other at completion */ + refcount_set(&req->refs, 2); + req->result = 0; ++ req->fs = NULL; + return req; + out: + percpu_ref_put(&ctx->refs); +@@ -1653,6 +1657,11 @@ static int io_send_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe, + else if (force_nonblock) + flags |= MSG_DONTWAIT; + ++#ifdef CONFIG_COMPAT ++ if (req->ctx->compat) ++ flags |= MSG_CMSG_COMPAT; ++#endif ++ + msg = (struct user_msghdr __user *) (unsigned long) + READ_ONCE(sqe->addr); + +@@ -1663,6 +1672,16 @@ static int io_send_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe, + ret = -EINTR; + } + ++ if (req->fs) { ++ struct fs_struct *fs = req->fs; ++ ++ spin_lock(&req->fs->lock); ++ if (--fs->users) ++ fs = NULL; ++ spin_unlock(&req->fs->lock); ++ if (fs) ++ free_fs_struct(fs); ++ } + io_cqring_add_event(req->ctx, sqe->user_data, ret); + io_put_req(req); + return 0; +@@ -2159,6 +2178,7 @@ static inline bool io_sqe_needs_user(const struct io_uring_sqe *sqe) + static void io_sq_wq_submit_work(struct work_struct *work) + { + struct io_kiocb *req = container_of(work, struct io_kiocb, work); ++ struct fs_struct *old_fs_struct = current->fs; + struct io_ring_ctx *ctx = req->ctx; + struct mm_struct *cur_mm = NULL; + struct async_list *async_list; +@@ -2178,6 +2198,15 @@ restart: + /* Ensure we clear previously set non-block flag */ + req->rw.ki_flags &= ~IOCB_NOWAIT; + ++ if (req->fs != current->fs && current->fs != old_fs_struct) { ++ task_lock(current); ++ if (req->fs) ++ current->fs = req->fs; ++ else ++ current->fs = old_fs_struct; ++ task_unlock(current); ++ } ++ + ret = 0; + if (io_sqe_needs_user(sqe) && !cur_mm) { + if (!mmget_not_zero(ctx->sqo_mm)) { +@@ -2276,6 +2305,11 @@ out: + mmput(cur_mm); + } + revert_creds(old_cred); ++ if (old_fs_struct) { ++ task_lock(current); ++ current->fs = old_fs_struct; ++ task_unlock(current); ++ } + } + + /* +@@ -2503,6 +2537,23 @@ err: + + req->user_data = s->sqe->user_data; + ++#if defined(CONFIG_NET) ++ switch (READ_ONCE(s->sqe->opcode)) { ++ case IORING_OP_SENDMSG: ++ case IORING_OP_RECVMSG: ++ spin_lock(¤t->fs->lock); ++ if (!current->fs->in_exec) { ++ req->fs = current->fs; ++ req->fs->users++; ++ } ++ spin_unlock(¤t->fs->lock); ++ if (!req->fs) { ++ ret = -EAGAIN; ++ goto err_req; ++ } ++ } ++#endif ++ + /* + * If we already have a head request, queue this one for async + * submittal once the head completes. If we don't have a head but +diff --git a/fs/namei.c b/fs/namei.c +index bd1c0ca4151c..5b5759d70822 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -1360,7 +1360,7 @@ static int follow_dotdot_rcu(struct nameidata *nd) + nd->path.dentry = parent; + nd->seq = seq; + if (unlikely(!path_connected(&nd->path))) +- return -ENOENT; ++ return -ECHILD; + break; + } else { + struct mount *mnt = real_mount(nd->path.mnt); +diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c +index 339663d04bf8..54f1c1f626fc 100644 +--- a/fs/nfs/nfs4file.c ++++ b/fs/nfs/nfs4file.c +@@ -86,7 +86,6 @@ nfs4_file_open(struct inode *inode, struct file *filp) + if (inode != d_inode(dentry)) + goto out_drop; + +- nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); + nfs_file_set_open_context(filp, ctx); + nfs_fscache_open_file(inode, filp); + err = 0; +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index f808fb34b110..6b29703d2fe1 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -2962,10 +2962,13 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, + struct dentry *dentry; + struct nfs4_state *state; + fmode_t acc_mode = _nfs4_ctx_to_accessmode(ctx); ++ struct inode *dir = d_inode(opendata->dir); ++ unsigned long dir_verifier; + unsigned int seq; + int ret; + + seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); ++ dir_verifier = nfs_save_change_attribute(dir); + + ret = _nfs4_proc_open(opendata, ctx); + if (ret != 0) +@@ -2993,8 +2996,19 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, + dput(ctx->dentry); + ctx->dentry = dentry = alias; + } +- nfs_set_verifier(dentry, +- nfs_save_change_attribute(d_inode(opendata->dir))); ++ } ++ ++ switch(opendata->o_arg.claim) { ++ default: ++ break; ++ case NFS4_OPEN_CLAIM_NULL: ++ case NFS4_OPEN_CLAIM_DELEGATE_CUR: ++ case NFS4_OPEN_CLAIM_DELEGATE_PREV: ++ if (!opendata->rpc_done) ++ break; ++ if (opendata->o_res.delegation_type != 0) ++ dir_verifier = nfs_save_change_attribute(dir); ++ nfs_set_verifier(dentry, dir_verifier); + } + + /* Parse layoutget results before we check for access */ +diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c +index 54d6db61106f..edf43ddd7dce 100644 +--- a/fs/ubifs/orphan.c ++++ b/fs/ubifs/orphan.c +@@ -129,7 +129,7 @@ static void __orphan_drop(struct ubifs_info *c, struct ubifs_orphan *o) + static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph) + { + if (orph->del) { +- dbg_gen("deleted twice ino %lu", orph->inum); ++ dbg_gen("deleted twice ino %lu", (unsigned long)orph->inum); + return; + } + +@@ -137,7 +137,7 @@ static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph) + orph->del = 1; + orph->dnext = c->orph_dnext; + c->orph_dnext = orph; +- dbg_gen("delete later ino %lu", orph->inum); ++ dbg_gen("delete later ino %lu", (unsigned long)orph->inum); + return; + } + +diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h +index 94badfa1743e..91c2cb14276e 100644 +--- a/fs/xfs/libxfs/xfs_attr.h ++++ b/fs/xfs/libxfs/xfs_attr.h +@@ -26,7 +26,7 @@ struct xfs_attr_list_context; + *========================================================================*/ + + +-#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ ++#define ATTR_DONTFOLLOW 0x0001 /* -- ignored, from IRIX -- */ + #define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ + #define ATTR_TRUST 0x0004 /* -- unused, from IRIX -- */ + #define ATTR_SECURE 0x0008 /* use attrs in security namespace */ +@@ -37,7 +37,10 @@ struct xfs_attr_list_context; + #define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */ + + #define ATTR_INCOMPLETE 0x4000 /* [kernel] return INCOMPLETE attr keys */ +-#define ATTR_ALLOC 0x8000 /* allocate xattr buffer on demand */ ++#define ATTR_ALLOC 0x8000 /* [kernel] allocate xattr buffer on demand */ ++ ++#define ATTR_KERNEL_FLAGS \ ++ (ATTR_KERNOTIME | ATTR_KERNOVAL | ATTR_INCOMPLETE | ATTR_ALLOC) + + #define XFS_ATTR_FLAGS \ + { ATTR_DONTFOLLOW, "DONTFOLLOW" }, \ +diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c +index d58f0d6a699e..2a1909397cb4 100644 +--- a/fs/xfs/xfs_ioctl.c ++++ b/fs/xfs/xfs_ioctl.c +@@ -536,6 +536,8 @@ xfs_attrmulti_by_handle( + + error = 0; + for (i = 0; i < am_hreq.opcount; i++) { ++ ops[i].am_flags &= ~ATTR_KERNEL_FLAGS; ++ + ops[i].am_error = strncpy_from_user((char *)attr_name, + ops[i].am_attrname, MAXNAMELEN); + if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) +diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c +index 1e08bf79b478..e61cc41189f8 100644 +--- a/fs/xfs/xfs_ioctl32.c ++++ b/fs/xfs/xfs_ioctl32.c +@@ -450,6 +450,8 @@ xfs_compat_attrmulti_by_handle( + + error = 0; + for (i = 0; i < am_hreq.opcount; i++) { ++ ops[i].am_flags &= ~ATTR_KERNEL_FLAGS; ++ + ops[i].am_error = strncpy_from_user((char *)attr_name, + compat_ptr(ops[i].am_attrname), + MAXNAMELEN); +diff --git a/include/Kbuild b/include/Kbuild +deleted file mode 100644 +index ffba79483cc5..000000000000 +--- a/include/Kbuild ++++ /dev/null +@@ -1,1185 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0-only +- +-# Add header-test-$(CONFIG_...) guard to headers that are only compiled +-# for particular architectures. +-# +-# Headers listed in header-test- are excluded from the test coverage. +-# Many headers are excluded for now because they fail to build. Please +-# consider to fix headers first before adding new ones to the blacklist. +-# +-# Sorted alphabetically. +-header-test- += acpi/acbuffer.h +-header-test- += acpi/acpi.h +-header-test- += acpi/acpi_bus.h +-header-test- += acpi/acpi_drivers.h +-header-test- += acpi/acpi_io.h +-header-test- += acpi/acpi_lpat.h +-header-test- += acpi/acpiosxf.h +-header-test- += acpi/acpixf.h +-header-test- += acpi/acrestyp.h +-header-test- += acpi/actbl.h +-header-test- += acpi/actbl1.h +-header-test- += acpi/actbl2.h +-header-test- += acpi/actbl3.h +-header-test- += acpi/actypes.h +-header-test- += acpi/battery.h +-header-test- += acpi/cppc_acpi.h +-header-test- += acpi/nfit.h +-header-test- += acpi/platform/acenv.h +-header-test- += acpi/platform/acenvex.h +-header-test- += acpi/platform/acintel.h +-header-test- += acpi/platform/aclinux.h +-header-test- += acpi/platform/aclinuxex.h +-header-test- += acpi/processor.h +-header-test-$(CONFIG_X86) += clocksource/hyperv_timer.h +-header-test- += clocksource/timer-sp804.h +-header-test- += crypto/cast_common.h +-header-test- += crypto/internal/cryptouser.h +-header-test- += crypto/pkcs7.h +-header-test- += crypto/poly1305.h +-header-test- += crypto/sha3.h +-header-test- += drm/ati_pcigart.h +-header-test- += drm/bridge/dw_hdmi.h +-header-test- += drm/bridge/dw_mipi_dsi.h +-header-test- += drm/drm_audio_component.h +-header-test- += drm/drm_auth.h +-header-test- += drm/drm_debugfs.h +-header-test- += drm/drm_debugfs_crc.h +-header-test- += drm/drm_displayid.h +-header-test- += drm/drm_encoder_slave.h +-header-test- += drm/drm_fb_cma_helper.h +-header-test- += drm/drm_fb_helper.h +-header-test- += drm/drm_fixed.h +-header-test- += drm/drm_format_helper.h +-header-test- += drm/drm_lease.h +-header-test- += drm/drm_legacy.h +-header-test- += drm/drm_panel.h +-header-test- += drm/drm_plane_helper.h +-header-test- += drm/drm_rect.h +-header-test- += drm/i915_component.h +-header-test- += drm/intel-gtt.h +-header-test- += drm/tinydrm/tinydrm-helpers.h +-header-test- += drm/ttm/ttm_debug.h +-header-test- += keys/asymmetric-parser.h +-header-test- += keys/asymmetric-subtype.h +-header-test- += keys/asymmetric-type.h +-header-test- += keys/big_key-type.h +-header-test- += keys/request_key_auth-type.h +-header-test- += keys/trusted.h +-header-test- += kvm/arm_arch_timer.h +-header-test- += kvm/arm_pmu.h +-header-test-$(CONFIG_ARM) += kvm/arm_psci.h +-header-test-$(CONFIG_ARM64) += kvm/arm_psci.h +-header-test- += kvm/arm_vgic.h +-header-test- += linux/8250_pci.h +-header-test- += linux/a.out.h +-header-test- += linux/adxl.h +-header-test- += linux/agpgart.h +-header-test- += linux/alcor_pci.h +-header-test- += linux/amba/clcd.h +-header-test- += linux/amba/pl080.h +-header-test- += linux/amd-iommu.h +-header-test-$(CONFIG_ARM) += linux/arm-cci.h +-header-test-$(CONFIG_ARM64) += linux/arm-cci.h +-header-test- += linux/arm_sdei.h +-header-test- += linux/asn1_decoder.h +-header-test- += linux/ata_platform.h +-header-test- += linux/ath9k_platform.h +-header-test- += linux/atm_tcp.h +-header-test- += linux/atomic-fallback.h +-header-test- += linux/avf/virtchnl.h +-header-test- += linux/bcm47xx_sprom.h +-header-test- += linux/bcma/bcma_driver_gmac_cmn.h +-header-test- += linux/bcma/bcma_driver_mips.h +-header-test- += linux/bcma/bcma_driver_pci.h +-header-test- += linux/bcma/bcma_driver_pcie2.h +-header-test- += linux/bit_spinlock.h +-header-test- += linux/blk-mq-rdma.h +-header-test- += linux/blk-mq.h +-header-test- += linux/blktrace_api.h +-header-test- += linux/blockgroup_lock.h +-header-test- += linux/bma150.h +-header-test- += linux/bpf_lirc.h +-header-test- += linux/bpf_types.h +-header-test- += linux/bsg-lib.h +-header-test- += linux/bsg.h +-header-test- += linux/btf.h +-header-test- += linux/btree-128.h +-header-test- += linux/btree-type.h +-header-test-$(CONFIG_CPU_BIG_ENDIAN) += linux/byteorder/big_endian.h +-header-test- += linux/byteorder/generic.h +-header-test-$(CONFIG_CPU_LITTLE_ENDIAN) += linux/byteorder/little_endian.h +-header-test- += linux/c2port.h +-header-test- += linux/can/dev/peak_canfd.h +-header-test- += linux/can/platform/cc770.h +-header-test- += linux/can/platform/sja1000.h +-header-test- += linux/ceph/ceph_features.h +-header-test- += linux/ceph/ceph_frag.h +-header-test- += linux/ceph/ceph_fs.h +-header-test- += linux/ceph/debugfs.h +-header-test- += linux/ceph/msgr.h +-header-test- += linux/ceph/rados.h +-header-test- += linux/cgroup_subsys.h +-header-test- += linux/clk/sunxi-ng.h +-header-test- += linux/clk/ti.h +-header-test- += linux/cn_proc.h +-header-test- += linux/coda_psdev.h +-header-test- += linux/compaction.h +-header-test- += linux/console_struct.h +-header-test- += linux/count_zeros.h +-header-test- += linux/cs5535.h +-header-test- += linux/cuda.h +-header-test- += linux/cyclades.h +-header-test- += linux/dcookies.h +-header-test- += linux/delayacct.h +-header-test- += linux/delayed_call.h +-header-test- += linux/device-mapper.h +-header-test- += linux/devpts_fs.h +-header-test- += linux/dio.h +-header-test- += linux/dirent.h +-header-test- += linux/dlm_plock.h +-header-test- += linux/dm-dirty-log.h +-header-test- += linux/dm-region-hash.h +-header-test- += linux/dma-debug.h +-header-test- += linux/dma/mmp-pdma.h +-header-test- += linux/dma/sprd-dma.h +-header-test- += linux/dns_resolver.h +-header-test- += linux/drbd_genl.h +-header-test- += linux/drbd_genl_api.h +-header-test- += linux/dw_apb_timer.h +-header-test- += linux/dynamic_debug.h +-header-test- += linux/dynamic_queue_limits.h +-header-test- += linux/ecryptfs.h +-header-test- += linux/edma.h +-header-test- += linux/eeprom_93cx6.h +-header-test- += linux/efs_vh.h +-header-test- += linux/elevator.h +-header-test- += linux/elfcore-compat.h +-header-test- += linux/error-injection.h +-header-test- += linux/errseq.h +-header-test- += linux/eventpoll.h +-header-test- += linux/ext2_fs.h +-header-test- += linux/f75375s.h +-header-test- += linux/falloc.h +-header-test- += linux/fault-inject.h +-header-test- += linux/fbcon.h +-header-test- += linux/firmware/intel/stratix10-svc-client.h +-header-test- += linux/firmware/meson/meson_sm.h +-header-test- += linux/firmware/trusted_foundations.h +-header-test- += linux/firmware/xlnx-zynqmp.h +-header-test- += linux/fixp-arith.h +-header-test- += linux/flat.h +-header-test- += linux/fs_types.h +-header-test- += linux/fs_uart_pd.h +-header-test- += linux/fsi-occ.h +-header-test- += linux/fsi-sbefifo.h +-header-test- += linux/fsl/bestcomm/ata.h +-header-test- += linux/fsl/bestcomm/bestcomm.h +-header-test- += linux/fsl/bestcomm/bestcomm_priv.h +-header-test- += linux/fsl/bestcomm/fec.h +-header-test- += linux/fsl/bestcomm/gen_bd.h +-header-test- += linux/fsl/bestcomm/sram.h +-header-test- += linux/fsl_hypervisor.h +-header-test- += linux/fsldma.h +-header-test- += linux/ftrace_irq.h +-header-test- += linux/gameport.h +-header-test- += linux/genl_magic_func.h +-header-test- += linux/genl_magic_struct.h +-header-test- += linux/gpio/aspeed.h +-header-test- += linux/gpio/gpio-reg.h +-header-test- += linux/hid-debug.h +-header-test- += linux/hiddev.h +-header-test- += linux/hippidevice.h +-header-test- += linux/hmm.h +-header-test- += linux/hp_sdc.h +-header-test- += linux/huge_mm.h +-header-test- += linux/hugetlb_cgroup.h +-header-test- += linux/hugetlb_inline.h +-header-test- += linux/hwmon-vid.h +-header-test- += linux/hyperv.h +-header-test- += linux/i2c-algo-pca.h +-header-test- += linux/i2c-algo-pcf.h +-header-test- += linux/i3c/ccc.h +-header-test- += linux/i3c/device.h +-header-test- += linux/i3c/master.h +-header-test- += linux/i8042.h +-header-test- += linux/ide.h +-header-test- += linux/idle_inject.h +-header-test- += linux/if_frad.h +-header-test- += linux/if_rmnet.h +-header-test- += linux/if_tap.h +-header-test- += linux/iio/accel/kxcjk_1013.h +-header-test- += linux/iio/adc/ad_sigma_delta.h +-header-test- += linux/iio/buffer-dma.h +-header-test- += linux/iio/buffer_impl.h +-header-test- += linux/iio/common/st_sensors.h +-header-test- += linux/iio/common/st_sensors_i2c.h +-header-test- += linux/iio/common/st_sensors_spi.h +-header-test- += linux/iio/dac/ad5421.h +-header-test- += linux/iio/dac/ad5504.h +-header-test- += linux/iio/dac/ad5791.h +-header-test- += linux/iio/dac/max517.h +-header-test- += linux/iio/dac/mcp4725.h +-header-test- += linux/iio/frequency/ad9523.h +-header-test- += linux/iio/frequency/adf4350.h +-header-test- += linux/iio/hw-consumer.h +-header-test- += linux/iio/imu/adis.h +-header-test- += linux/iio/sysfs.h +-header-test- += linux/iio/timer/stm32-timer-trigger.h +-header-test- += linux/iio/trigger.h +-header-test- += linux/iio/triggered_event.h +-header-test- += linux/imx-media.h +-header-test- += linux/inet_diag.h +-header-test- += linux/init_ohci1394_dma.h +-header-test- += linux/initrd.h +-header-test- += linux/input/adp5589.h +-header-test- += linux/input/bu21013.h +-header-test- += linux/input/cma3000.h +-header-test- += linux/input/kxtj9.h +-header-test- += linux/input/lm8333.h +-header-test- += linux/input/sparse-keymap.h +-header-test- += linux/input/touchscreen.h +-header-test- += linux/input/tps6507x-ts.h +-header-test-$(CONFIG_X86) += linux/intel-iommu.h +-header-test- += linux/intel-ish-client-if.h +-header-test- += linux/intel-pti.h +-header-test- += linux/intel-svm.h +-header-test- += linux/interconnect-provider.h +-header-test- += linux/ioc3.h +-header-test-$(CONFIG_BLOCK) += linux/iomap.h +-header-test- += linux/ipack.h +-header-test- += linux/irq_cpustat.h +-header-test- += linux/irq_poll.h +-header-test- += linux/irqchip/arm-gic-v3.h +-header-test- += linux/irqchip/arm-gic-v4.h +-header-test- += linux/irqchip/irq-madera.h +-header-test- += linux/irqchip/irq-sa11x0.h +-header-test- += linux/irqchip/mxs.h +-header-test- += linux/irqchip/versatile-fpga.h +-header-test- += linux/irqdesc.h +-header-test- += linux/irqflags.h +-header-test- += linux/iscsi_boot_sysfs.h +-header-test- += linux/isdn/capiutil.h +-header-test- += linux/isdn/hdlc.h +-header-test- += linux/isdn_ppp.h +-header-test- += linux/jbd2.h +-header-test- += linux/jump_label.h +-header-test- += linux/jump_label_ratelimit.h +-header-test- += linux/jz4740-adc.h +-header-test- += linux/kasan.h +-header-test- += linux/kcore.h +-header-test- += linux/kdev_t.h +-header-test- += linux/kernelcapi.h +-header-test- += linux/khugepaged.h +-header-test- += linux/kobj_map.h +-header-test- += linux/kobject_ns.h +-header-test- += linux/kvm_host.h +-header-test- += linux/kvm_irqfd.h +-header-test- += linux/kvm_para.h +-header-test- += linux/lantiq.h +-header-test- += linux/lapb.h +-header-test- += linux/latencytop.h +-header-test- += linux/led-lm3530.h +-header-test- += linux/leds-bd2802.h +-header-test- += linux/leds-lp3944.h +-header-test- += linux/leds-lp3952.h +-header-test- += linux/leds_pwm.h +-header-test- += linux/libata.h +-header-test- += linux/license.h +-header-test- += linux/lightnvm.h +-header-test- += linux/lis3lv02d.h +-header-test- += linux/list_bl.h +-header-test- += linux/list_lru.h +-header-test- += linux/list_nulls.h +-header-test- += linux/lockd/share.h +-header-test- += linux/lzo.h +-header-test- += linux/mailbox/zynqmp-ipi-message.h +-header-test- += linux/maple.h +-header-test- += linux/mbcache.h +-header-test- += linux/mbus.h +-header-test- += linux/mc146818rtc.h +-header-test- += linux/mc6821.h +-header-test- += linux/mdev.h +-header-test- += linux/mem_encrypt.h +-header-test- += linux/memfd.h +-header-test- += linux/mfd/88pm80x.h +-header-test- += linux/mfd/88pm860x.h +-header-test- += linux/mfd/abx500/ab8500-bm.h +-header-test- += linux/mfd/abx500/ab8500-gpadc.h +-header-test- += linux/mfd/adp5520.h +-header-test- += linux/mfd/arizona/pdata.h +-header-test- += linux/mfd/as3711.h +-header-test- += linux/mfd/as3722.h +-header-test- += linux/mfd/da903x.h +-header-test- += linux/mfd/da9055/pdata.h +-header-test- += linux/mfd/db8500-prcmu.h +-header-test- += linux/mfd/dbx500-prcmu.h +-header-test- += linux/mfd/dln2.h +-header-test- += linux/mfd/dm355evm_msp.h +-header-test- += linux/mfd/ds1wm.h +-header-test- += linux/mfd/ezx-pcap.h +-header-test- += linux/mfd/intel_msic.h +-header-test- += linux/mfd/janz.h +-header-test- += linux/mfd/kempld.h +-header-test- += linux/mfd/lm3533.h +-header-test- += linux/mfd/lp8788-isink.h +-header-test- += linux/mfd/lpc_ich.h +-header-test- += linux/mfd/max77693.h +-header-test- += linux/mfd/max8998-private.h +-header-test- += linux/mfd/menelaus.h +-header-test- += linux/mfd/mt6397/core.h +-header-test- += linux/mfd/palmas.h +-header-test- += linux/mfd/pcf50633/backlight.h +-header-test- += linux/mfd/rc5t583.h +-header-test- += linux/mfd/retu.h +-header-test- += linux/mfd/samsung/core.h +-header-test- += linux/mfd/si476x-platform.h +-header-test- += linux/mfd/si476x-reports.h +-header-test- += linux/mfd/sky81452.h +-header-test- += linux/mfd/smsc.h +-header-test- += linux/mfd/sta2x11-mfd.h +-header-test- += linux/mfd/stmfx.h +-header-test- += linux/mfd/tc3589x.h +-header-test- += linux/mfd/tc6387xb.h +-header-test- += linux/mfd/tc6393xb.h +-header-test- += linux/mfd/tps65090.h +-header-test- += linux/mfd/tps6586x.h +-header-test- += linux/mfd/tps65910.h +-header-test- += linux/mfd/tps80031.h +-header-test- += linux/mfd/ucb1x00.h +-header-test- += linux/mfd/viperboard.h +-header-test- += linux/mfd/wm831x/core.h +-header-test- += linux/mfd/wm831x/otp.h +-header-test- += linux/mfd/wm831x/pdata.h +-header-test- += linux/mfd/wm8994/core.h +-header-test- += linux/mfd/wm8994/pdata.h +-header-test- += linux/mlx4/doorbell.h +-header-test- += linux/mlx4/srq.h +-header-test- += linux/mlx5/doorbell.h +-header-test- += linux/mlx5/eq.h +-header-test- += linux/mlx5/fs_helpers.h +-header-test- += linux/mlx5/mlx5_ifc.h +-header-test- += linux/mlx5/mlx5_ifc_fpga.h +-header-test- += linux/mm-arch-hooks.h +-header-test- += linux/mm_inline.h +-header-test- += linux/mmu_context.h +-header-test- += linux/mpage.h +-header-test- += linux/mtd/bbm.h +-header-test- += linux/mtd/cfi.h +-header-test- += linux/mtd/doc2000.h +-header-test- += linux/mtd/flashchip.h +-header-test- += linux/mtd/ftl.h +-header-test- += linux/mtd/gen_probe.h +-header-test- += linux/mtd/jedec.h +-header-test- += linux/mtd/nand_bch.h +-header-test- += linux/mtd/nand_ecc.h +-header-test- += linux/mtd/ndfc.h +-header-test- += linux/mtd/onenand.h +-header-test- += linux/mtd/pismo.h +-header-test- += linux/mtd/plat-ram.h +-header-test- += linux/mtd/spi-nor.h +-header-test- += linux/mv643xx.h +-header-test- += linux/mv643xx_eth.h +-header-test- += linux/mvebu-pmsu.h +-header-test- += linux/mxm-wmi.h +-header-test- += linux/n_r3964.h +-header-test- += linux/ndctl.h +-header-test- += linux/nfs.h +-header-test- += linux/nfs_fs_i.h +-header-test- += linux/nfs_fs_sb.h +-header-test- += linux/nfs_page.h +-header-test- += linux/nfs_xdr.h +-header-test- += linux/nfsacl.h +-header-test- += linux/nl802154.h +-header-test- += linux/ns_common.h +-header-test- += linux/nsc_gpio.h +-header-test- += linux/ntb_transport.h +-header-test- += linux/nubus.h +-header-test- += linux/nvme-fc-driver.h +-header-test- += linux/nvme-fc.h +-header-test- += linux/nvme-rdma.h +-header-test- += linux/nvram.h +-header-test- += linux/objagg.h +-header-test- += linux/of_clk.h +-header-test- += linux/of_net.h +-header-test- += linux/of_pdt.h +-header-test- += linux/olpc-ec.h +-header-test- += linux/omap-dma.h +-header-test- += linux/omap-dmaengine.h +-header-test- += linux/omap-gpmc.h +-header-test- += linux/omap-iommu.h +-header-test- += linux/omap-mailbox.h +-header-test- += linux/once.h +-header-test- += linux/osq_lock.h +-header-test- += linux/overflow.h +-header-test- += linux/page-flags-layout.h +-header-test- += linux/page-isolation.h +-header-test- += linux/page_ext.h +-header-test- += linux/page_owner.h +-header-test- += linux/parport_pc.h +-header-test- += linux/parser.h +-header-test- += linux/pci-acpi.h +-header-test- += linux/pci-dma-compat.h +-header-test- += linux/pci_hotplug.h +-header-test- += linux/pda_power.h +-header-test- += linux/perf/arm_pmu.h +-header-test- += linux/perf_regs.h +-header-test- += linux/phy/omap_control_phy.h +-header-test- += linux/phy/tegra/xusb.h +-header-test- += linux/phy/ulpi_phy.h +-header-test- += linux/phy_fixed.h +-header-test- += linux/pipe_fs_i.h +-header-test- += linux/pktcdvd.h +-header-test- += linux/pl320-ipc.h +-header-test- += linux/pl353-smc.h +-header-test- += linux/platform_data/ad5449.h +-header-test- += linux/platform_data/ad5755.h +-header-test- += linux/platform_data/ad7266.h +-header-test- += linux/platform_data/ad7291.h +-header-test- += linux/platform_data/ad7298.h +-header-test- += linux/platform_data/ad7303.h +-header-test- += linux/platform_data/ad7791.h +-header-test- += linux/platform_data/ad7793.h +-header-test- += linux/platform_data/ad7887.h +-header-test- += linux/platform_data/adau17x1.h +-header-test- += linux/platform_data/adp8870.h +-header-test- += linux/platform_data/ads1015.h +-header-test- += linux/platform_data/ads7828.h +-header-test- += linux/platform_data/apds990x.h +-header-test- += linux/platform_data/arm-ux500-pm.h +-header-test- += linux/platform_data/asoc-s3c.h +-header-test- += linux/platform_data/at91_adc.h +-header-test- += linux/platform_data/ata-pxa.h +-header-test- += linux/platform_data/atmel.h +-header-test- += linux/platform_data/bh1770glc.h +-header-test- += linux/platform_data/brcmfmac.h +-header-test- += linux/platform_data/cros_ec_commands.h +-header-test- += linux/platform_data/clk-u300.h +-header-test- += linux/platform_data/cyttsp4.h +-header-test- += linux/platform_data/dma-coh901318.h +-header-test- += linux/platform_data/dma-imx-sdma.h +-header-test- += linux/platform_data/dma-mcf-edma.h +-header-test- += linux/platform_data/dma-s3c24xx.h +-header-test- += linux/platform_data/dmtimer-omap.h +-header-test- += linux/platform_data/dsa.h +-header-test- += linux/platform_data/edma.h +-header-test- += linux/platform_data/elm.h +-header-test- += linux/platform_data/emif_plat.h +-header-test- += linux/platform_data/fsa9480.h +-header-test- += linux/platform_data/g762.h +-header-test- += linux/platform_data/gpio-ath79.h +-header-test- += linux/platform_data/gpio-davinci.h +-header-test- += linux/platform_data/gpio-dwapb.h +-header-test- += linux/platform_data/gpio-htc-egpio.h +-header-test- += linux/platform_data/gpmc-omap.h +-header-test- += linux/platform_data/hsmmc-omap.h +-header-test- += linux/platform_data/hwmon-s3c.h +-header-test- += linux/platform_data/i2c-davinci.h +-header-test- += linux/platform_data/i2c-imx.h +-header-test- += linux/platform_data/i2c-mux-reg.h +-header-test- += linux/platform_data/i2c-ocores.h +-header-test- += linux/platform_data/i2c-xiic.h +-header-test- += linux/platform_data/intel-spi.h +-header-test- += linux/platform_data/invensense_mpu6050.h +-header-test- += linux/platform_data/irda-pxaficp.h +-header-test- += linux/platform_data/irda-sa11x0.h +-header-test- += linux/platform_data/itco_wdt.h +-header-test- += linux/platform_data/jz4740/jz4740_nand.h +-header-test- += linux/platform_data/keyboard-pxa930_rotary.h +-header-test- += linux/platform_data/keypad-omap.h +-header-test- += linux/platform_data/leds-lp55xx.h +-header-test- += linux/platform_data/leds-omap.h +-header-test- += linux/platform_data/lp855x.h +-header-test- += linux/platform_data/lp8727.h +-header-test- += linux/platform_data/max197.h +-header-test- += linux/platform_data/max3421-hcd.h +-header-test- += linux/platform_data/max732x.h +-header-test- += linux/platform_data/mcs.h +-header-test- += linux/platform_data/mdio-bcm-unimac.h +-header-test- += linux/platform_data/mdio-gpio.h +-header-test- += linux/platform_data/media/si4713.h +-header-test- += linux/platform_data/mlxreg.h +-header-test- += linux/platform_data/mmc-omap.h +-header-test- += linux/platform_data/mmc-sdhci-s3c.h +-header-test- += linux/platform_data/mmp_audio.h +-header-test- += linux/platform_data/mtd-orion_nand.h +-header-test- += linux/platform_data/mv88e6xxx.h +-header-test- += linux/platform_data/net-cw1200.h +-header-test- += linux/platform_data/omap-twl4030.h +-header-test- += linux/platform_data/omapdss.h +-header-test- += linux/platform_data/pcf857x.h +-header-test- += linux/platform_data/pixcir_i2c_ts.h +-header-test- += linux/platform_data/pwm_omap_dmtimer.h +-header-test- += linux/platform_data/pxa2xx_udc.h +-header-test- += linux/platform_data/pxa_sdhci.h +-header-test- += linux/platform_data/remoteproc-omap.h +-header-test- += linux/platform_data/sa11x0-serial.h +-header-test- += linux/platform_data/sc18is602.h +-header-test- += linux/platform_data/sdhci-pic32.h +-header-test- += linux/platform_data/serial-sccnxp.h +-header-test- += linux/platform_data/sht3x.h +-header-test- += linux/platform_data/shtc1.h +-header-test- += linux/platform_data/si5351.h +-header-test- += linux/platform_data/sky81452-backlight.h +-header-test- += linux/platform_data/spi-davinci.h +-header-test- += linux/platform_data/spi-ep93xx.h +-header-test- += linux/platform_data/spi-mt65xx.h +-header-test- += linux/platform_data/st_sensors_pdata.h +-header-test- += linux/platform_data/ti-sysc.h +-header-test- += linux/platform_data/timer-ixp4xx.h +-header-test- += linux/platform_data/touchscreen-s3c2410.h +-header-test- += linux/platform_data/tsc2007.h +-header-test- += linux/platform_data/tsl2772.h +-header-test- += linux/platform_data/uio_pruss.h +-header-test- += linux/platform_data/usb-davinci.h +-header-test- += linux/platform_data/usb-ehci-mxc.h +-header-test- += linux/platform_data/usb-ehci-orion.h +-header-test- += linux/platform_data/usb-mx2.h +-header-test- += linux/platform_data/usb-ohci-s3c2410.h +-header-test- += linux/platform_data/usb-omap.h +-header-test- += linux/platform_data/usb-s3c2410_udc.h +-header-test- += linux/platform_data/usb3503.h +-header-test- += linux/platform_data/ux500_wdt.h +-header-test- += linux/platform_data/video-clcd-versatile.h +-header-test- += linux/platform_data/video-imxfb.h +-header-test- += linux/platform_data/video-pxafb.h +-header-test- += linux/platform_data/video_s3c.h +-header-test- += linux/platform_data/voltage-omap.h +-header-test- += linux/platform_data/x86/apple.h +-header-test- += linux/platform_data/x86/clk-pmc-atom.h +-header-test- += linux/platform_data/x86/pmc_atom.h +-header-test- += linux/platform_data/xtalk-bridge.h +-header-test- += linux/pm2301_charger.h +-header-test- += linux/pm_wakeirq.h +-header-test- += linux/pm_wakeup.h +-header-test- += linux/pmbus.h +-header-test- += linux/pmu.h +-header-test- += linux/posix_acl.h +-header-test- += linux/posix_acl_xattr.h +-header-test- += linux/power/ab8500.h +-header-test- += linux/power/bq27xxx_battery.h +-header-test- += linux/power/generic-adc-battery.h +-header-test- += linux/power/jz4740-battery.h +-header-test- += linux/power/max17042_battery.h +-header-test- += linux/power/max8903_charger.h +-header-test- += linux/ppp-comp.h +-header-test- += linux/pps-gpio.h +-header-test- += linux/pr.h +-header-test- += linux/proc_ns.h +-header-test- += linux/processor.h +-header-test- += linux/psi.h +-header-test- += linux/psp-sev.h +-header-test- += linux/pstore.h +-header-test- += linux/ptr_ring.h +-header-test- += linux/ptrace.h +-header-test- += linux/qcom-geni-se.h +-header-test- += linux/qed/eth_common.h +-header-test- += linux/qed/fcoe_common.h +-header-test- += linux/qed/iscsi_common.h +-header-test- += linux/qed/iwarp_common.h +-header-test- += linux/qed/qed_eth_if.h +-header-test- += linux/qed/qed_fcoe_if.h +-header-test- += linux/qed/rdma_common.h +-header-test- += linux/qed/storage_common.h +-header-test- += linux/qed/tcp_common.h +-header-test- += linux/qnx6_fs.h +-header-test- += linux/quicklist.h +-header-test- += linux/ramfs.h +-header-test- += linux/range.h +-header-test- += linux/rcu_node_tree.h +-header-test- += linux/rculist_bl.h +-header-test- += linux/rculist_nulls.h +-header-test- += linux/rcutiny.h +-header-test- += linux/rcutree.h +-header-test- += linux/reboot-mode.h +-header-test- += linux/regulator/fixed.h +-header-test- += linux/regulator/gpio-regulator.h +-header-test- += linux/regulator/max8973-regulator.h +-header-test- += linux/regulator/of_regulator.h +-header-test- += linux/regulator/tps51632-regulator.h +-header-test- += linux/regulator/tps62360.h +-header-test- += linux/regulator/tps6507x.h +-header-test- += linux/regulator/userspace-consumer.h +-header-test- += linux/remoteproc/st_slim_rproc.h +-header-test- += linux/reset/socfpga.h +-header-test- += linux/reset/sunxi.h +-header-test- += linux/rtc/m48t59.h +-header-test- += linux/rtc/rtc-omap.h +-header-test- += linux/rtc/sirfsoc_rtciobrg.h +-header-test- += linux/rwlock.h +-header-test- += linux/rwlock_types.h +-header-test- += linux/scc.h +-header-test- += linux/sched/deadline.h +-header-test- += linux/sched/smt.h +-header-test- += linux/sched/sysctl.h +-header-test- += linux/sched_clock.h +-header-test- += linux/scpi_protocol.h +-header-test- += linux/scx200_gpio.h +-header-test- += linux/seccomp.h +-header-test- += linux/sed-opal.h +-header-test- += linux/seg6_iptunnel.h +-header-test- += linux/selection.h +-header-test- += linux/set_memory.h +-header-test- += linux/shrinker.h +-header-test- += linux/sirfsoc_dma.h +-header-test- += linux/skb_array.h +-header-test- += linux/slab_def.h +-header-test- += linux/slub_def.h +-header-test- += linux/sm501.h +-header-test- += linux/smc91x.h +-header-test- += linux/static_key.h +-header-test- += linux/soc/actions/owl-sps.h +-header-test- += linux/soc/amlogic/meson-canvas.h +-header-test- += linux/soc/brcmstb/brcmstb.h +-header-test- += linux/soc/ixp4xx/npe.h +-header-test- += linux/soc/mediatek/infracfg.h +-header-test- += linux/soc/qcom/smd-rpm.h +-header-test- += linux/soc/qcom/smem.h +-header-test- += linux/soc/qcom/smem_state.h +-header-test- += linux/soc/qcom/wcnss_ctrl.h +-header-test- += linux/soc/renesas/rcar-rst.h +-header-test- += linux/soc/samsung/exynos-pmu.h +-header-test- += linux/soc/sunxi/sunxi_sram.h +-header-test- += linux/soc/ti/ti-msgmgr.h +-header-test- += linux/soc/ti/ti_sci_inta_msi.h +-header-test- += linux/soc/ti/ti_sci_protocol.h +-header-test- += linux/soundwire/sdw.h +-header-test- += linux/soundwire/sdw_intel.h +-header-test- += linux/soundwire/sdw_type.h +-header-test- += linux/spi/ad7877.h +-header-test- += linux/spi/ads7846.h +-header-test- += linux/spi/at86rf230.h +-header-test- += linux/spi/ds1305.h +-header-test- += linux/spi/libertas_spi.h +-header-test- += linux/spi/lms283gf05.h +-header-test- += linux/spi/max7301.h +-header-test- += linux/spi/mcp23s08.h +-header-test- += linux/spi/rspi.h +-header-test- += linux/spi/s3c24xx.h +-header-test- += linux/spi/sh_msiof.h +-header-test- += linux/spi/spi-fsl-dspi.h +-header-test- += linux/spi/spi_bitbang.h +-header-test- += linux/spi/spi_gpio.h +-header-test- += linux/spi/xilinx_spi.h +-header-test- += linux/spinlock_api_smp.h +-header-test- += linux/spinlock_api_up.h +-header-test- += linux/spinlock_types.h +-header-test- += linux/splice.h +-header-test- += linux/sram.h +-header-test- += linux/srcutiny.h +-header-test- += linux/srcutree.h +-header-test- += linux/ssb/ssb_driver_chipcommon.h +-header-test- += linux/ssb/ssb_driver_extif.h +-header-test- += linux/ssb/ssb_driver_mips.h +-header-test- += linux/ssb/ssb_driver_pci.h +-header-test- += linux/ssbi.h +-header-test- += linux/stackdepot.h +-header-test- += linux/stmp3xxx_rtc_wdt.h +-header-test- += linux/string_helpers.h +-header-test- += linux/sungem_phy.h +-header-test- += linux/sunrpc/msg_prot.h +-header-test- += linux/sunrpc/rpc_pipe_fs.h +-header-test- += linux/sunrpc/xprtmultipath.h +-header-test- += linux/sunrpc/xprtsock.h +-header-test- += linux/sunxi-rsb.h +-header-test- += linux/svga.h +-header-test- += linux/sw842.h +-header-test- += linux/swapfile.h +-header-test- += linux/swapops.h +-header-test- += linux/swiotlb.h +-header-test- += linux/sysv_fs.h +-header-test- += linux/t10-pi.h +-header-test- += linux/task_io_accounting.h +-header-test- += linux/tick.h +-header-test- += linux/timb_dma.h +-header-test- += linux/timekeeping.h +-header-test- += linux/timekeeping32.h +-header-test- += linux/ts-nbus.h +-header-test- += linux/tsacct_kern.h +-header-test- += linux/tty_flip.h +-header-test- += linux/tty_ldisc.h +-header-test- += linux/ucb1400.h +-header-test- += linux/usb/association.h +-header-test- += linux/usb/cdc-wdm.h +-header-test- += linux/usb/cdc_ncm.h +-header-test- += linux/usb/ezusb.h +-header-test- += linux/usb/gadget_configfs.h +-header-test- += linux/usb/gpio_vbus.h +-header-test- += linux/usb/hcd.h +-header-test- += linux/usb/iowarrior.h +-header-test- += linux/usb/irda.h +-header-test- += linux/usb/isp116x.h +-header-test- += linux/usb/isp1362.h +-header-test- += linux/usb/musb.h +-header-test- += linux/usb/net2280.h +-header-test- += linux/usb/ohci_pdriver.h +-header-test- += linux/usb/otg-fsm.h +-header-test- += linux/usb/pd_ado.h +-header-test- += linux/usb/r8a66597.h +-header-test- += linux/usb/rndis_host.h +-header-test- += linux/usb/serial.h +-header-test- += linux/usb/sl811.h +-header-test- += linux/usb/storage.h +-header-test- += linux/usb/uas.h +-header-test- += linux/usb/usb338x.h +-header-test- += linux/usb/usbnet.h +-header-test- += linux/usb/wusb-wa.h +-header-test- += linux/usb/xhci-dbgp.h +-header-test- += linux/usb_usual.h +-header-test- += linux/user-return-notifier.h +-header-test- += linux/userfaultfd_k.h +-header-test- += linux/verification.h +-header-test- += linux/vgaarb.h +-header-test- += linux/via_core.h +-header-test- += linux/via_i2c.h +-header-test- += linux/virtio_byteorder.h +-header-test- += linux/virtio_ring.h +-header-test- += linux/visorbus.h +-header-test- += linux/vme.h +-header-test- += linux/vmstat.h +-header-test- += linux/vmw_vmci_api.h +-header-test- += linux/vmw_vmci_defs.h +-header-test- += linux/vringh.h +-header-test- += linux/vt_buffer.h +-header-test- += linux/zorro.h +-header-test- += linux/zpool.h +-header-test- += math-emu/double.h +-header-test- += math-emu/op-common.h +-header-test- += math-emu/quad.h +-header-test- += math-emu/single.h +-header-test- += math-emu/soft-fp.h +-header-test- += media/davinci/dm355_ccdc.h +-header-test- += media/davinci/dm644x_ccdc.h +-header-test- += media/davinci/isif.h +-header-test- += media/davinci/vpbe_osd.h +-header-test- += media/davinci/vpbe_types.h +-header-test- += media/davinci/vpif_types.h +-header-test- += media/demux.h +-header-test- += media/drv-intf/soc_mediabus.h +-header-test- += media/dvb_net.h +-header-test- += media/fwht-ctrls.h +-header-test- += media/i2c/ad9389b.h +-header-test- += media/i2c/adv7343.h +-header-test- += media/i2c/adv7511.h +-header-test- += media/i2c/adv7842.h +-header-test- += media/i2c/m5mols.h +-header-test- += media/i2c/mt9m032.h +-header-test- += media/i2c/mt9t112.h +-header-test- += media/i2c/mt9v032.h +-header-test- += media/i2c/ov2659.h +-header-test- += media/i2c/ov7670.h +-header-test- += media/i2c/rj54n1cb0c.h +-header-test- += media/i2c/saa6588.h +-header-test- += media/i2c/saa7115.h +-header-test- += media/i2c/sr030pc30.h +-header-test- += media/i2c/tc358743.h +-header-test- += media/i2c/tda1997x.h +-header-test- += media/i2c/ths7303.h +-header-test- += media/i2c/tvaudio.h +-header-test- += media/i2c/tvp514x.h +-header-test- += media/i2c/tvp7002.h +-header-test- += media/i2c/wm8775.h +-header-test- += media/imx.h +-header-test- += media/media-dev-allocator.h +-header-test- += media/mpeg2-ctrls.h +-header-test- += media/rcar-fcp.h +-header-test- += media/tuner-types.h +-header-test- += media/tveeprom.h +-header-test- += media/v4l2-flash-led-class.h +-header-test- += misc/altera.h +-header-test- += misc/cxl-base.h +-header-test- += misc/cxllib.h +-header-test- += net/9p/9p.h +-header-test- += net/9p/client.h +-header-test- += net/9p/transport.h +-header-test- += net/af_vsock.h +-header-test- += net/ax88796.h +-header-test- += net/bluetooth/hci.h +-header-test- += net/bluetooth/hci_core.h +-header-test- += net/bluetooth/hci_mon.h +-header-test- += net/bluetooth/hci_sock.h +-header-test- += net/bluetooth/l2cap.h +-header-test- += net/bluetooth/mgmt.h +-header-test- += net/bluetooth/rfcomm.h +-header-test- += net/bluetooth/sco.h +-header-test- += net/bond_options.h +-header-test- += net/caif/cfsrvl.h +-header-test- += net/codel_impl.h +-header-test- += net/codel_qdisc.h +-header-test- += net/compat.h +-header-test- += net/datalink.h +-header-test- += net/dcbevent.h +-header-test- += net/dcbnl.h +-header-test- += net/dn_dev.h +-header-test- += net/dn_fib.h +-header-test- += net/dn_neigh.h +-header-test- += net/dn_nsp.h +-header-test- += net/dn_route.h +-header-test- += net/erspan.h +-header-test- += net/esp.h +-header-test- += net/ethoc.h +-header-test- += net/firewire.h +-header-test- += net/flow_offload.h +-header-test- += net/fq.h +-header-test- += net/fq_impl.h +-header-test- += net/garp.h +-header-test- += net/gtp.h +-header-test- += net/gue.h +-header-test- += net/hwbm.h +-header-test- += net/ila.h +-header-test- += net/inet6_connection_sock.h +-header-test- += net/inet_common.h +-header-test- += net/inet_frag.h +-header-test- += net/ip6_route.h +-header-test- += net/ip_vs.h +-header-test- += net/ipcomp.h +-header-test- += net/ipconfig.h +-header-test- += net/iucv/af_iucv.h +-header-test- += net/iucv/iucv.h +-header-test- += net/lapb.h +-header-test- += net/llc_c_ac.h +-header-test- += net/llc_c_st.h +-header-test- += net/llc_s_ac.h +-header-test- += net/llc_s_ev.h +-header-test- += net/llc_s_st.h +-header-test- += net/mpls_iptunnel.h +-header-test- += net/mrp.h +-header-test- += net/ncsi.h +-header-test- += net/netevent.h +-header-test- += net/netns/can.h +-header-test- += net/netns/generic.h +-header-test- += net/netns/ieee802154_6lowpan.h +-header-test- += net/netns/ipv4.h +-header-test- += net/netns/ipv6.h +-header-test- += net/netns/mpls.h +-header-test- += net/netns/nftables.h +-header-test- += net/netns/sctp.h +-header-test- += net/netrom.h +-header-test- += net/p8022.h +-header-test- += net/phonet/pep.h +-header-test- += net/phonet/phonet.h +-header-test- += net/phonet/pn_dev.h +-header-test- += net/pptp.h +-header-test- += net/psample.h +-header-test- += net/psnap.h +-header-test- += net/regulatory.h +-header-test- += net/rose.h +-header-test- += net/sctp/auth.h +-header-test- += net/sctp/stream_interleave.h +-header-test- += net/sctp/stream_sched.h +-header-test- += net/sctp/tsnmap.h +-header-test- += net/sctp/ulpevent.h +-header-test- += net/sctp/ulpqueue.h +-header-test- += net/secure_seq.h +-header-test- += net/smc.h +-header-test- += net/stp.h +-header-test- += net/transp_v6.h +-header-test- += net/tun_proto.h +-header-test- += net/udplite.h +-header-test- += net/xdp.h +-header-test- += net/xdp_priv.h +-header-test- += pcmcia/cistpl.h +-header-test- += pcmcia/ds.h +-header-test- += rdma/tid_rdma_defs.h +-header-test- += scsi/fc/fc_encaps.h +-header-test- += scsi/fc/fc_fc2.h +-header-test- += scsi/fc/fc_fcoe.h +-header-test- += scsi/fc/fc_fip.h +-header-test- += scsi/fc_encode.h +-header-test- += scsi/fc_frame.h +-header-test- += scsi/iser.h +-header-test- += scsi/libfc.h +-header-test- += scsi/libfcoe.h +-header-test- += scsi/libsas.h +-header-test- += scsi/sas_ata.h +-header-test- += scsi/scsi_cmnd.h +-header-test- += scsi/scsi_dbg.h +-header-test- += scsi/scsi_device.h +-header-test- += scsi/scsi_dh.h +-header-test- += scsi/scsi_eh.h +-header-test- += scsi/scsi_host.h +-header-test- += scsi/scsi_ioctl.h +-header-test- += scsi/scsi_request.h +-header-test- += scsi/scsi_tcq.h +-header-test- += scsi/scsi_transport.h +-header-test- += scsi/scsi_transport_fc.h +-header-test- += scsi/scsi_transport_sas.h +-header-test- += scsi/scsi_transport_spi.h +-header-test- += scsi/scsi_transport_srp.h +-header-test- += scsi/scsicam.h +-header-test- += scsi/sg.h +-header-test- += soc/arc/aux.h +-header-test- += soc/arc/mcip.h +-header-test- += soc/arc/timers.h +-header-test- += soc/brcmstb/common.h +-header-test- += soc/fsl/bman.h +-header-test- += soc/fsl/qe/qe.h +-header-test- += soc/fsl/qe/qe_ic.h +-header-test- += soc/fsl/qe/qe_tdm.h +-header-test- += soc/fsl/qe/ucc.h +-header-test- += soc/fsl/qe/ucc_fast.h +-header-test- += soc/fsl/qe/ucc_slow.h +-header-test- += soc/fsl/qman.h +-header-test- += soc/nps/common.h +-header-test-$(CONFIG_ARC) += soc/nps/mtm.h +-header-test- += soc/qcom/cmd-db.h +-header-test- += soc/qcom/rpmh.h +-header-test- += soc/qcom/tcs.h +-header-test- += soc/tegra/ahb.h +-header-test- += soc/tegra/bpmp-abi.h +-header-test- += soc/tegra/common.h +-header-test- += soc/tegra/flowctrl.h +-header-test- += soc/tegra/fuse.h +-header-test- += soc/tegra/mc.h +-header-test- += sound/ac97/compat.h +-header-test- += sound/aci.h +-header-test- += sound/ad1843.h +-header-test- += sound/adau1373.h +-header-test- += sound/ak4113.h +-header-test- += sound/ak4114.h +-header-test- += sound/ak4117.h +-header-test- += sound/cs35l33.h +-header-test- += sound/cs35l34.h +-header-test- += sound/cs35l35.h +-header-test- += sound/cs35l36.h +-header-test- += sound/cs4271.h +-header-test- += sound/cs42l52.h +-header-test- += sound/cs8427.h +-header-test- += sound/da7218.h +-header-test- += sound/da7219-aad.h +-header-test- += sound/da7219.h +-header-test- += sound/da9055.h +-header-test- += sound/emu8000.h +-header-test- += sound/emux_synth.h +-header-test- += sound/hda_component.h +-header-test- += sound/hda_hwdep.h +-header-test- += sound/hda_i915.h +-header-test- += sound/hwdep.h +-header-test- += sound/i2c.h +-header-test- += sound/l3.h +-header-test- += sound/max98088.h +-header-test- += sound/max98095.h +-header-test- += sound/mixer_oss.h +-header-test- += sound/omap-hdmi-audio.h +-header-test- += sound/pcm_drm_eld.h +-header-test- += sound/pcm_iec958.h +-header-test- += sound/pcm_oss.h +-header-test- += sound/pxa2xx-lib.h +-header-test- += sound/rt286.h +-header-test- += sound/rt298.h +-header-test- += sound/rt5645.h +-header-test- += sound/rt5659.h +-header-test- += sound/rt5660.h +-header-test- += sound/rt5665.h +-header-test- += sound/rt5670.h +-header-test- += sound/s3c24xx_uda134x.h +-header-test- += sound/seq_device.h +-header-test- += sound/seq_kernel.h +-header-test- += sound/seq_midi_emul.h +-header-test- += sound/seq_oss.h +-header-test- += sound/soc-acpi-intel-match.h +-header-test- += sound/soc-dai.h +-header-test- += sound/soc-dapm.h +-header-test- += sound/soc-dpcm.h +-header-test- += sound/sof/control.h +-header-test- += sound/sof/dai-intel.h +-header-test- += sound/sof/dai.h +-header-test- += sound/sof/header.h +-header-test- += sound/sof/info.h +-header-test- += sound/sof/pm.h +-header-test- += sound/sof/stream.h +-header-test- += sound/sof/topology.h +-header-test- += sound/sof/trace.h +-header-test- += sound/sof/xtensa.h +-header-test- += sound/spear_spdif.h +-header-test- += sound/sta32x.h +-header-test- += sound/sta350.h +-header-test- += sound/tea6330t.h +-header-test- += sound/tlv320aic32x4.h +-header-test- += sound/tlv320dac33-plat.h +-header-test- += sound/uda134x.h +-header-test- += sound/wavefront.h +-header-test- += sound/wm8903.h +-header-test- += sound/wm8904.h +-header-test- += sound/wm8960.h +-header-test- += sound/wm8962.h +-header-test- += sound/wm8993.h +-header-test- += sound/wm8996.h +-header-test- += sound/wm9081.h +-header-test- += sound/wm9090.h +-header-test- += target/iscsi/iscsi_target_stat.h +-header-test- += trace/bpf_probe.h +-header-test- += trace/events/9p.h +-header-test- += trace/events/afs.h +-header-test- += trace/events/asoc.h +-header-test- += trace/events/bcache.h +-header-test- += trace/events/block.h +-header-test- += trace/events/cachefiles.h +-header-test- += trace/events/cgroup.h +-header-test- += trace/events/clk.h +-header-test- += trace/events/cma.h +-header-test- += trace/events/ext4.h +-header-test- += trace/events/f2fs.h +-header-test- += trace/events/fs_dax.h +-header-test- += trace/events/fscache.h +-header-test- += trace/events/fsi.h +-header-test- += trace/events/fsi_master_ast_cf.h +-header-test- += trace/events/fsi_master_gpio.h +-header-test- += trace/events/huge_memory.h +-header-test- += trace/events/ib_mad.h +-header-test- += trace/events/ib_umad.h +-header-test- += trace/events/iscsi.h +-header-test- += trace/events/jbd2.h +-header-test- += trace/events/kvm.h +-header-test- += trace/events/kyber.h +-header-test- += trace/events/libata.h +-header-test- += trace/events/mce.h +-header-test- += trace/events/mdio.h +-header-test- += trace/events/migrate.h +-header-test- += trace/events/mmflags.h +-header-test- += trace/events/nbd.h +-header-test- += trace/events/nilfs2.h +-header-test- += trace/events/pwc.h +-header-test- += trace/events/rdma.h +-header-test- += trace/events/rpcgss.h +-header-test- += trace/events/rpcrdma.h +-header-test- += trace/events/rxrpc.h +-header-test- += trace/events/scsi.h +-header-test- += trace/events/siox.h +-header-test- += trace/events/spi.h +-header-test- += trace/events/swiotlb.h +-header-test- += trace/events/syscalls.h +-header-test- += trace/events/target.h +-header-test- += trace/events/thermal_power_allocator.h +-header-test- += trace/events/timer.h +-header-test- += trace/events/wbt.h +-header-test- += trace/events/xen.h +-header-test- += trace/perf.h +-header-test- += trace/trace_events.h +-header-test- += uapi/drm/vmwgfx_drm.h +-header-test- += uapi/linux/a.out.h +-header-test- += uapi/linux/coda.h +-header-test- += uapi/linux/coda_psdev.h +-header-test- += uapi/linux/errqueue.h +-header-test- += uapi/linux/eventpoll.h +-header-test- += uapi/linux/hdlc/ioctl.h +-header-test- += uapi/linux/input.h +-header-test- += uapi/linux/kvm.h +-header-test- += uapi/linux/kvm_para.h +-header-test- += uapi/linux/lightnvm.h +-header-test- += uapi/linux/mic_common.h +-header-test- += uapi/linux/mman.h +-header-test- += uapi/linux/nilfs2_ondisk.h +-header-test- += uapi/linux/patchkey.h +-header-test- += uapi/linux/ptrace.h +-header-test- += uapi/linux/scc.h +-header-test- += uapi/linux/seg6_iptunnel.h +-header-test- += uapi/linux/smc_diag.h +-header-test- += uapi/linux/timex.h +-header-test- += uapi/linux/videodev2.h +-header-test- += uapi/scsi/scsi_bsg_fc.h +-header-test- += uapi/sound/asound.h +-header-test- += uapi/sound/sof/eq.h +-header-test- += uapi/sound/sof/fw.h +-header-test- += uapi/sound/sof/header.h +-header-test- += uapi/sound/sof/manifest.h +-header-test- += uapi/sound/sof/trace.h +-header-test- += uapi/xen/evtchn.h +-header-test- += uapi/xen/gntdev.h +-header-test- += uapi/xen/privcmd.h +-header-test- += vdso/vsyscall.h +-header-test- += video/broadsheetfb.h +-header-test- += video/cvisionppc.h +-header-test- += video/gbe.h +-header-test- += video/kyro.h +-header-test- += video/maxinefb.h +-header-test- += video/metronomefb.h +-header-test- += video/neomagic.h +-header-test- += video/of_display_timing.h +-header-test- += video/omapvrfb.h +-header-test- += video/s1d13xxxfb.h +-header-test- += video/sstfb.h +-header-test- += video/tgafb.h +-header-test- += video/udlfb.h +-header-test- += video/uvesafb.h +-header-test- += video/vga.h +-header-test- += video/w100fb.h +-header-test- += xen/acpi.h +-header-test- += xen/arm/hypercall.h +-header-test- += xen/arm/page-coherent.h +-header-test- += xen/arm/page.h +-header-test- += xen/balloon.h +-header-test- += xen/events.h +-header-test- += xen/features.h +-header-test- += xen/grant_table.h +-header-test- += xen/hvm.h +-header-test- += xen/interface/callback.h +-header-test- += xen/interface/event_channel.h +-header-test- += xen/interface/grant_table.h +-header-test- += xen/interface/hvm/dm_op.h +-header-test- += xen/interface/hvm/hvm_op.h +-header-test- += xen/interface/hvm/hvm_vcpu.h +-header-test- += xen/interface/hvm/params.h +-header-test- += xen/interface/hvm/start_info.h +-header-test- += xen/interface/io/9pfs.h +-header-test- += xen/interface/io/blkif.h +-header-test- += xen/interface/io/console.h +-header-test- += xen/interface/io/displif.h +-header-test- += xen/interface/io/fbif.h +-header-test- += xen/interface/io/kbdif.h +-header-test- += xen/interface/io/netif.h +-header-test- += xen/interface/io/pciif.h +-header-test- += xen/interface/io/protocols.h +-header-test- += xen/interface/io/pvcalls.h +-header-test- += xen/interface/io/ring.h +-header-test- += xen/interface/io/sndif.h +-header-test- += xen/interface/io/tpmif.h +-header-test- += xen/interface/io/vscsiif.h +-header-test- += xen/interface/io/xs_wire.h +-header-test- += xen/interface/memory.h +-header-test- += xen/interface/nmi.h +-header-test- += xen/interface/physdev.h +-header-test- += xen/interface/platform.h +-header-test- += xen/interface/sched.h +-header-test- += xen/interface/vcpu.h +-header-test- += xen/interface/version.h +-header-test- += xen/interface/xen-mca.h +-header-test- += xen/interface/xen.h +-header-test- += xen/interface/xenpmu.h +-header-test- += xen/mem-reservation.h +-header-test- += xen/page.h +-header-test- += xen/platform_pci.h +-header-test- += xen/swiotlb-xen.h +-header-test- += xen/xen-front-pgdir-shbuf.h +-header-test- += xen/xen-ops.h +-header-test- += xen/xen.h +-header-test- += xen/xenbus.h +- +-# Do not include directly +-header-test- += linux/compiler-clang.h +-header-test- += linux/compiler-gcc.h +-header-test- += linux/patchkey.h +-header-test- += linux/rwlock_api_smp.h +-header-test- += linux/spinlock_types_up.h +-header-test- += linux/spinlock_up.h +-header-test- += linux/wimax/debug.h +-header-test- += rdma/uverbs_named_ioctl.h +- +-# asm-generic/*.h is used by asm/*.h, and should not be included directly +-header-test- += asm-generic/% uapi/asm-generic/% +- +-# Timestamp files touched by Kconfig +-header-test- += config/% +- +-# Timestamp files touched by scripts/adjust_autoksyms.sh +-header-test- += ksym/% +- +-# You could compile-test these, but maybe not so useful... +-header-test- += dt-bindings/% +- +-# Do not test generated headers. Stale headers are often left over when you +-# traverse the git history without cleaning. +-header-test- += generated/% +- +-# The rest are compile-tested +-header-test-pattern-y += */*.h */*/*.h */*/*/*.h */*/*/*/*.h +diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h +index 2f3f28c7cea3..9373662cdb44 100644 +--- a/include/acpi/actypes.h ++++ b/include/acpi/actypes.h +@@ -532,11 +532,12 @@ typedef u64 acpi_integer; + strnlen (a, ACPI_NAMESEG_SIZE) == ACPI_NAMESEG_SIZE) + + /* +- * Algorithm to obtain access bit width. ++ * Algorithm to obtain access bit or byte width. + * Can be used with access_width of struct acpi_generic_address and access_size of + * struct acpi_resource_generic_register. + */ + #define ACPI_ACCESS_BIT_WIDTH(size) (1 << ((size) + 2)) ++#define ACPI_ACCESS_BYTE_WIDTH(size) (1 << ((size) - 1)) + + /******************************************************************************* + * +diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h +index ce4103208619..cec543d9e87b 100644 +--- a/include/asm-generic/vdso/vsyscall.h ++++ b/include/asm-generic/vdso/vsyscall.h +@@ -12,9 +12,9 @@ static __always_inline struct vdso_data *__arch_get_k_vdso_data(void) + #endif /* __arch_get_k_vdso_data */ + + #ifndef __arch_update_vdso_data +-static __always_inline int __arch_update_vdso_data(void) ++static __always_inline bool __arch_update_vdso_data(void) + { +- return 0; ++ return true; + } + #endif /* __arch_update_vdso_data */ + +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 51ccb4b8770a..bff1def62eed 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -531,7 +531,7 @@ struct request_queue { + unsigned int sg_reserved_size; + int node; + #ifdef CONFIG_BLK_DEV_IO_TRACE +- struct blk_trace *blk_trace; ++ struct blk_trace __rcu *blk_trace; + struct mutex blk_trace_mutex; + #endif + /* +diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h +index 7bb2d8de9f30..3b6ff5902edc 100644 +--- a/include/linux/blktrace_api.h ++++ b/include/linux/blktrace_api.h +@@ -51,9 +51,13 @@ void __trace_note_message(struct blk_trace *, struct blkcg *blkcg, const char *f + **/ + #define blk_add_cgroup_trace_msg(q, cg, fmt, ...) \ + do { \ +- struct blk_trace *bt = (q)->blk_trace; \ ++ struct blk_trace *bt; \ ++ \ ++ rcu_read_lock(); \ ++ bt = rcu_dereference((q)->blk_trace); \ + if (unlikely(bt)) \ + __trace_note_message(bt, cg, fmt, ##__VA_ARGS__);\ ++ rcu_read_unlock(); \ + } while (0) + #define blk_add_trace_msg(q, fmt, ...) \ + blk_add_cgroup_trace_msg(q, NULL, fmt, ##__VA_ARGS__) +@@ -61,10 +65,14 @@ void __trace_note_message(struct blk_trace *, struct blkcg *blkcg, const char *f + + static inline bool blk_trace_note_message_enabled(struct request_queue *q) + { +- struct blk_trace *bt = q->blk_trace; +- if (likely(!bt)) +- return false; +- return bt->act_mask & BLK_TC_NOTIFY; ++ struct blk_trace *bt; ++ bool ret; ++ ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ ret = bt && (bt->act_mask & BLK_TC_NOTIFY); ++ rcu_read_unlock(); ++ return ret; + } + + extern void blk_add_driver_data(struct request_queue *q, struct request *rq, +diff --git a/include/linux/hid.h b/include/linux/hid.h +index cd41f209043f..875f71132b14 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -492,7 +492,7 @@ struct hid_report_enum { + }; + + #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ +-#define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ ++#define HID_MAX_BUFFER_SIZE 8192 /* 8kb */ + #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ + #define HID_OUTPUT_FIFO_SIZE 64 + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index f8fde9fa479c..b580a35f50ea 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -72,6 +72,8 @@ void netdev_set_default_ethtool_ops(struct net_device *dev, + #define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ + #define NET_RX_DROP 1 /* packet dropped */ + ++#define MAX_NEST_DEV 8 ++ + /* + * Transmit return codes: transmit return codes originate from three different + * namespaces: +@@ -4294,11 +4296,8 @@ void *netdev_lower_get_next(struct net_device *dev, + ldev; \ + ldev = netdev_lower_get_next(dev, &(iter))) + +-struct net_device *netdev_all_lower_get_next(struct net_device *dev, ++struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, + struct list_head **iter); +-struct net_device *netdev_all_lower_get_next_rcu(struct net_device *dev, +- struct list_head **iter); +- + int netdev_walk_all_lower_dev(struct net_device *dev, + int (*fn)(struct net_device *lower_dev, + void *data), +diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h +index 77336f4c4b1c..32658749e9db 100644 +--- a/include/linux/netfilter/ipset/ip_set.h ++++ b/include/linux/netfilter/ipset/ip_set.h +@@ -121,6 +121,7 @@ struct ip_set_ext { + u32 timeout; + u8 packets_op; + u8 bytes_op; ++ bool target; + }; + + struct ip_set; +@@ -187,6 +188,14 @@ struct ip_set_type_variant { + /* Return true if "b" set is the same as "a" + * according to the create set parameters */ + bool (*same_set)(const struct ip_set *a, const struct ip_set *b); ++ /* Region-locking is used */ ++ bool region_lock; ++}; ++ ++struct ip_set_region { ++ spinlock_t lock; /* Region lock */ ++ size_t ext_size; /* Size of the dynamic extensions */ ++ u32 elements; /* Number of elements vs timeout */ + }; + + /* The core set type structure */ +@@ -681,7 +690,7 @@ ip_set_init_skbinfo(struct ip_set_skbinfo *skbinfo, + } + + #define IP_SET_INIT_KEXT(skb, opt, set) \ +- { .bytes = (skb)->len, .packets = 1, \ ++ { .bytes = (skb)->len, .packets = 1, .target = true,\ + .timeout = ip_set_adt_opt_timeout(opt, set) } + + #define IP_SET_INIT_UEXT(set) \ +diff --git a/include/linux/sched/nohz.h b/include/linux/sched/nohz.h +index 1abe91ff6e4a..6d67e9a5af6b 100644 +--- a/include/linux/sched/nohz.h ++++ b/include/linux/sched/nohz.h +@@ -15,9 +15,11 @@ static inline void nohz_balance_enter_idle(int cpu) { } + + #ifdef CONFIG_NO_HZ_COMMON + void calc_load_nohz_start(void); ++void calc_load_nohz_remote(struct rq *rq); + void calc_load_nohz_stop(void); + #else + static inline void calc_load_nohz_start(void) { } ++static inline void calc_load_nohz_remote(struct rq *rq) { } + static inline void calc_load_nohz_stop(void) { } + #endif /* CONFIG_NO_HZ_COMMON */ + +diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h +index e5fc8db1f783..78f6437cbc3a 100644 +--- a/include/net/flow_dissector.h ++++ b/include/net/flow_dissector.h +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + + /** +@@ -338,4 +339,12 @@ struct bpf_flow_dissector { + void *data_end; + }; + ++static inline void ++flow_dissector_init_keys(struct flow_dissector_key_control *key_control, ++ struct flow_dissector_key_basic *key_basic) ++{ ++ memset(key_control, 0, sizeof(*key_control)); ++ memset(key_basic, 0, sizeof(*key_basic)); ++} ++ + #endif +diff --git a/include/uapi/linux/usb/charger.h b/include/uapi/linux/usb/charger.h +index 5f72af35b3ed..ad22079125bf 100644 +--- a/include/uapi/linux/usb/charger.h ++++ b/include/uapi/linux/usb/charger.h +@@ -14,18 +14,18 @@ + * ACA (Accessory Charger Adapters) + */ + enum usb_charger_type { +- UNKNOWN_TYPE, +- SDP_TYPE, +- DCP_TYPE, +- CDP_TYPE, +- ACA_TYPE, ++ UNKNOWN_TYPE = 0, ++ SDP_TYPE = 1, ++ DCP_TYPE = 2, ++ CDP_TYPE = 3, ++ ACA_TYPE = 4, + }; + + /* USB charger state */ + enum usb_charger_state { +- USB_CHARGER_DEFAULT, +- USB_CHARGER_PRESENT, +- USB_CHARGER_ABSENT, ++ USB_CHARGER_DEFAULT = 0, ++ USB_CHARGER_PRESENT = 1, ++ USB_CHARGER_ABSENT = 2, + }; + + #endif /* _UAPI__LINUX_USB_CHARGER_H */ +diff --git a/init/Kconfig b/init/Kconfig +index 0328b53d09ad..0bffc8fdbf3d 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -105,29 +105,9 @@ config COMPILE_TEST + here. If you are a user/distributor, say N here to exclude useless + drivers to be distributed. + +-config HEADER_TEST +- bool "Compile test headers that should be standalone compilable" +- help +- Compile test headers listed in header-test-y target to ensure they are +- self-contained, i.e. compilable as standalone units. +- +- If you are a developer or tester and want to ensure the requested +- headers are self-contained, say Y here. Otherwise, choose N. +- +-config KERNEL_HEADER_TEST +- bool "Compile test kernel headers" +- depends on HEADER_TEST +- help +- Headers in include/ are used to build external moduls. +- Compile test them to ensure they are self-contained, i.e. +- compilable as standalone units. +- +- If you are a developer or tester and want to ensure the headers +- in include/ are self-contained, say Y here. Otherwise, choose N. +- + config UAPI_HEADER_TEST + bool "Compile test UAPI headers" +- depends on HEADER_TEST && HEADERS_INSTALL && CC_CAN_LINK ++ depends on HEADERS_INSTALL && CC_CAN_LINK + help + Compile test headers exported to user-space to ensure they are + self-contained, i.e. compilable as standalone units. +diff --git a/kernel/audit.c b/kernel/audit.c +index da8dc0db5bd3..dfc45063cb56 100644 +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -1100,13 +1100,11 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature + audit_log_end(ab); + } + +-static int audit_set_feature(struct sk_buff *skb) ++static int audit_set_feature(struct audit_features *uaf) + { +- struct audit_features *uaf; + int i; + + BUILD_BUG_ON(AUDIT_LAST_FEATURE + 1 > ARRAY_SIZE(audit_feature_names)); +- uaf = nlmsg_data(nlmsg_hdr(skb)); + + /* if there is ever a version 2 we should handle that here */ + +@@ -1174,6 +1172,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + { + u32 seq; + void *data; ++ int data_len; + int err; + struct audit_buffer *ab; + u16 msg_type = nlh->nlmsg_type; +@@ -1187,6 +1186,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + + seq = nlh->nlmsg_seq; + data = nlmsg_data(nlh); ++ data_len = nlmsg_len(nlh); + + switch (msg_type) { + case AUDIT_GET: { +@@ -1210,7 +1210,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + struct audit_status s; + memset(&s, 0, sizeof(s)); + /* guard against past and future API changes */ +- memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); ++ memcpy(&s, data, min_t(size_t, sizeof(s), data_len)); + if (s.mask & AUDIT_STATUS_ENABLED) { + err = audit_set_enabled(s.enabled); + if (err < 0) +@@ -1314,7 +1314,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + return err; + break; + case AUDIT_SET_FEATURE: +- err = audit_set_feature(skb); ++ if (data_len < sizeof(struct audit_features)) ++ return -EINVAL; ++ err = audit_set_feature(data); + if (err) + return err; + break; +@@ -1326,6 +1328,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + + err = audit_filter(msg_type, AUDIT_FILTER_USER); + if (err == 1) { /* match or error */ ++ char *str = data; ++ + err = 0; + if (msg_type == AUDIT_USER_TTY) { + err = tty_audit_push(); +@@ -1333,26 +1337,24 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + break; + } + audit_log_user_recv_msg(&ab, msg_type); +- if (msg_type != AUDIT_USER_TTY) ++ if (msg_type != AUDIT_USER_TTY) { ++ /* ensure NULL termination */ ++ str[data_len - 1] = '\0'; + audit_log_format(ab, " msg='%.*s'", + AUDIT_MESSAGE_TEXT_MAX, +- (char *)data); +- else { +- int size; +- ++ str); ++ } else { + audit_log_format(ab, " data="); +- size = nlmsg_len(nlh); +- if (size > 0 && +- ((unsigned char *)data)[size - 1] == '\0') +- size--; +- audit_log_n_untrustedstring(ab, data, size); ++ if (data_len > 0 && str[data_len - 1] == '\0') ++ data_len--; ++ audit_log_n_untrustedstring(ab, str, data_len); + } + audit_log_end(ab); + } + break; + case AUDIT_ADD_RULE: + case AUDIT_DEL_RULE: +- if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) ++ if (data_len < sizeof(struct audit_rule_data)) + return -EINVAL; + if (audit_enabled == AUDIT_LOCKED) { + audit_log_common_recv_msg(audit_context(), &ab, +@@ -1364,7 +1366,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + audit_log_end(ab); + return -EPERM; + } +- err = audit_rule_change(msg_type, seq, data, nlmsg_len(nlh)); ++ err = audit_rule_change(msg_type, seq, data, data_len); + break; + case AUDIT_LIST_RULES: + err = audit_list_rules_send(skb, seq); +@@ -1379,7 +1381,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + case AUDIT_MAKE_EQUIV: { + void *bufp = data; + u32 sizes[2]; +- size_t msglen = nlmsg_len(nlh); ++ size_t msglen = data_len; + char *old, *new; + + err = -EINVAL; +@@ -1455,7 +1457,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + + memset(&s, 0, sizeof(s)); + /* guard against past and future API changes */ +- memcpy(&s, data, min_t(size_t, sizeof(s), nlmsg_len(nlh))); ++ memcpy(&s, data, min_t(size_t, sizeof(s), data_len)); + /* check if new data is valid */ + if ((s.enabled != 0 && s.enabled != 1) || + (s.log_passwd != 0 && s.log_passwd != 1)) +diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c +index b0126e9c0743..026e34da4ace 100644 +--- a/kernel/auditfilter.c ++++ b/kernel/auditfilter.c +@@ -456,6 +456,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + bufp = data->buf; + for (i = 0; i < data->field_count; i++) { + struct audit_field *f = &entry->rule.fields[i]; ++ u32 f_val; + + err = -EINVAL; + +@@ -464,12 +465,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + goto exit_free; + + f->type = data->fields[i]; +- f->val = data->values[i]; ++ f_val = data->values[i]; + + /* Support legacy tests for a valid loginuid */ +- if ((f->type == AUDIT_LOGINUID) && (f->val == AUDIT_UID_UNSET)) { ++ if ((f->type == AUDIT_LOGINUID) && (f_val == AUDIT_UID_UNSET)) { + f->type = AUDIT_LOGINUID_SET; +- f->val = 0; ++ f_val = 0; + entry->rule.pflags |= AUDIT_LOGINUID_LEGACY; + } + +@@ -485,7 +486,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + case AUDIT_SUID: + case AUDIT_FSUID: + case AUDIT_OBJ_UID: +- f->uid = make_kuid(current_user_ns(), f->val); ++ f->uid = make_kuid(current_user_ns(), f_val); + if (!uid_valid(f->uid)) + goto exit_free; + break; +@@ -494,11 +495,12 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + case AUDIT_SGID: + case AUDIT_FSGID: + case AUDIT_OBJ_GID: +- f->gid = make_kgid(current_user_ns(), f->val); ++ f->gid = make_kgid(current_user_ns(), f_val); + if (!gid_valid(f->gid)) + goto exit_free; + break; + case AUDIT_ARCH: ++ f->val = f_val; + entry->rule.arch_f = f; + break; + case AUDIT_SUBJ_USER: +@@ -511,11 +513,13 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + case AUDIT_OBJ_TYPE: + case AUDIT_OBJ_LEV_LOW: + case AUDIT_OBJ_LEV_HIGH: +- str = audit_unpack_string(&bufp, &remain, f->val); +- if (IS_ERR(str)) ++ str = audit_unpack_string(&bufp, &remain, f_val); ++ if (IS_ERR(str)) { ++ err = PTR_ERR(str); + goto exit_free; +- entry->rule.buflen += f->val; +- ++ } ++ entry->rule.buflen += f_val; ++ f->lsm_str = str; + err = security_audit_rule_init(f->type, f->op, str, + (void **)&f->lsm_rule); + /* Keep currently invalid fields around in case they +@@ -524,68 +528,71 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, + pr_warn("audit rule for LSM \'%s\' is invalid\n", + str); + err = 0; +- } +- if (err) { +- kfree(str); ++ } else if (err) + goto exit_free; +- } else +- f->lsm_str = str; + break; + case AUDIT_WATCH: +- str = audit_unpack_string(&bufp, &remain, f->val); +- if (IS_ERR(str)) ++ str = audit_unpack_string(&bufp, &remain, f_val); ++ if (IS_ERR(str)) { ++ err = PTR_ERR(str); + goto exit_free; +- entry->rule.buflen += f->val; +- +- err = audit_to_watch(&entry->rule, str, f->val, f->op); ++ } ++ err = audit_to_watch(&entry->rule, str, f_val, f->op); + if (err) { + kfree(str); + goto exit_free; + } ++ entry->rule.buflen += f_val; + break; + case AUDIT_DIR: +- str = audit_unpack_string(&bufp, &remain, f->val); +- if (IS_ERR(str)) ++ str = audit_unpack_string(&bufp, &remain, f_val); ++ if (IS_ERR(str)) { ++ err = PTR_ERR(str); + goto exit_free; +- entry->rule.buflen += f->val; +- ++ } + err = audit_make_tree(&entry->rule, str, f->op); + kfree(str); + if (err) + goto exit_free; ++ entry->rule.buflen += f_val; + break; + case AUDIT_INODE: ++ f->val = f_val; + err = audit_to_inode(&entry->rule, f); + if (err) + goto exit_free; + break; + case AUDIT_FILTERKEY: +- if (entry->rule.filterkey || f->val > AUDIT_MAX_KEY_LEN) ++ if (entry->rule.filterkey || f_val > AUDIT_MAX_KEY_LEN) + goto exit_free; +- str = audit_unpack_string(&bufp, &remain, f->val); +- if (IS_ERR(str)) ++ str = audit_unpack_string(&bufp, &remain, f_val); ++ if (IS_ERR(str)) { ++ err = PTR_ERR(str); + goto exit_free; +- entry->rule.buflen += f->val; ++ } ++ entry->rule.buflen += f_val; + entry->rule.filterkey = str; + break; + case AUDIT_EXE: +- if (entry->rule.exe || f->val > PATH_MAX) ++ if (entry->rule.exe || f_val > PATH_MAX) + goto exit_free; +- str = audit_unpack_string(&bufp, &remain, f->val); ++ str = audit_unpack_string(&bufp, &remain, f_val); + if (IS_ERR(str)) { + err = PTR_ERR(str); + goto exit_free; + } +- entry->rule.buflen += f->val; +- +- audit_mark = audit_alloc_mark(&entry->rule, str, f->val); ++ audit_mark = audit_alloc_mark(&entry->rule, str, f_val); + if (IS_ERR(audit_mark)) { + kfree(str); + err = PTR_ERR(audit_mark); + goto exit_free; + } ++ entry->rule.buflen += f_val; + entry->rule.exe = audit_mark; + break; ++ default: ++ f->val = f_val; ++ break; + } + } + +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index 53534aa258a6..34e28b236d68 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -510,6 +510,8 @@ static void do_unoptimize_kprobes(void) + arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); + /* Loop free_list for disarming */ + list_for_each_entry_safe(op, tmp, &freeing_list, list) { ++ /* Switching from detour code to origin */ ++ op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; + /* Disarm probes if marked disabled */ + if (kprobe_disabled(&op->kp)) + arch_disarm_kprobe(&op->kp); +@@ -649,6 +651,7 @@ static void force_unoptimize_kprobe(struct optimized_kprobe *op) + { + lockdep_assert_cpus_held(); + arch_unoptimize_kprobe(op); ++ op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; + if (kprobe_disabled(&op->kp)) + arch_disarm_kprobe(&op->kp); + } +@@ -676,7 +679,6 @@ static void unoptimize_kprobe(struct kprobe *p, bool force) + return; + } + +- op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; + if (!list_empty(&op->list)) { + /* Dequeue from the optimization queue */ + list_del_init(&op->list); +diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c +index dadb7b7fba37..9bb6d2497b04 100644 +--- a/kernel/locking/lockdep_proc.c ++++ b/kernel/locking/lockdep_proc.c +@@ -286,9 +286,9 @@ static int lockdep_stats_show(struct seq_file *m, void *v) + seq_printf(m, " stack-trace entries: %11lu [max: %lu]\n", + nr_stack_trace_entries, MAX_STACK_TRACE_ENTRIES); + #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_PROVE_LOCKING) +- seq_printf(m, " number of stack traces: %llu\n", ++ seq_printf(m, " number of stack traces: %11llu\n", + lockdep_stack_trace_count()); +- seq_printf(m, " number of stack hash chains: %llu\n", ++ seq_printf(m, " number of stack hash chains: %11llu\n", + lockdep_stack_hash_count()); + #endif + seq_printf(m, " combined max dependencies: %11u\n", +diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h +index f504ac831779..df90d4d7ad2e 100644 +--- a/kernel/rcu/tree_exp.h ++++ b/kernel/rcu/tree_exp.h +@@ -540,14 +540,13 @@ static void rcu_exp_wait_wake(unsigned long s) + struct rcu_node *rnp; + + synchronize_sched_expedited_wait(); +- rcu_exp_gp_seq_end(); +- trace_rcu_exp_grace_period(rcu_state.name, s, TPS("end")); + +- /* +- * Switch over to wakeup mode, allowing the next GP, but -only- the +- * next GP, to proceed. +- */ ++ // Switch over to wakeup mode, allowing the next GP to proceed. ++ // End the previous grace period only after acquiring the mutex ++ // to ensure that only one GP runs concurrently with wakeups. + mutex_lock(&rcu_state.exp_wake_mutex); ++ rcu_exp_gp_seq_end(); ++ trace_rcu_exp_grace_period(rcu_state.name, s, TPS("end")); + + rcu_for_each_node_breadth_first(rnp) { + if (ULONG_CMP_LT(READ_ONCE(rnp->exp_seq_rq), s)) { +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index e6c65725b7ce..e921126aec84 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -3668,28 +3668,32 @@ static void sched_tick_remote(struct work_struct *work) + * statistics and checks timeslices in a time-independent way, regardless + * of when exactly it is running. + */ +- if (idle_cpu(cpu) || !tick_nohz_tick_stopped_cpu(cpu)) ++ if (!tick_nohz_tick_stopped_cpu(cpu)) + goto out_requeue; + + rq_lock_irq(rq, &rf); + curr = rq->curr; +- if (is_idle_task(curr) || cpu_is_offline(cpu)) ++ if (cpu_is_offline(cpu)) + goto out_unlock; + ++ curr = rq->curr; + update_rq_clock(rq); +- delta = rq_clock_task(rq) - curr->se.exec_start; + +- /* +- * Make sure the next tick runs within a reasonable +- * amount of time. +- */ +- WARN_ON_ONCE(delta > (u64)NSEC_PER_SEC * 3); ++ if (!is_idle_task(curr)) { ++ /* ++ * Make sure the next tick runs within a reasonable ++ * amount of time. ++ */ ++ delta = rq_clock_task(rq) - curr->se.exec_start; ++ WARN_ON_ONCE(delta > (u64)NSEC_PER_SEC * 3); ++ } + curr->sched_class->task_tick(rq, curr, 0); + ++ calc_load_nohz_remote(rq); + out_unlock: + rq_unlock_irq(rq, &rf); +- + out_requeue: ++ + /* + * Run the remote tick once per second (1Hz). This arbitrary + * frequency is large enough to avoid overload but short enough +@@ -7054,8 +7058,15 @@ void sched_move_task(struct task_struct *tsk) + + if (queued) + enqueue_task(rq, tsk, queue_flags); +- if (running) ++ if (running) { + set_next_task(rq, tsk); ++ /* ++ * After changing group, the running task may have joined a ++ * throttled one but it's still the running task. Trigger a ++ * resched to make sure that task can still run. ++ */ ++ resched_curr(rq); ++ } + + task_rq_unlock(rq, tsk, &rf); + } +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index c87a798d1456..f32ce3a359fa 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -5933,6 +5933,7 @@ static inline int select_idle_smt(struct task_struct *p, int target) + */ + static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target) + { ++ struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask); + struct sched_domain *this_sd; + u64 avg_cost, avg_idle; + u64 time, cost; +@@ -5964,11 +5965,11 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t + + time = cpu_clock(this); + +- for_each_cpu_wrap(cpu, sched_domain_span(sd), target) { ++ cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr); ++ ++ for_each_cpu_wrap(cpu, cpus, target) { + if (!--nr) + return si_cpu; +- if (!cpumask_test_cpu(cpu, p->cpus_ptr)) +- continue; + if (available_idle_cpu(cpu)) + break; + if (si_cpu == -1 && sched_idle_cpu(cpu)) +diff --git a/kernel/sched/loadavg.c b/kernel/sched/loadavg.c +index 28a516575c18..de22da666ac7 100644 +--- a/kernel/sched/loadavg.c ++++ b/kernel/sched/loadavg.c +@@ -231,16 +231,11 @@ static inline int calc_load_read_idx(void) + return calc_load_idx & 1; + } + +-void calc_load_nohz_start(void) ++static void calc_load_nohz_fold(struct rq *rq) + { +- struct rq *this_rq = this_rq(); + long delta; + +- /* +- * We're going into NO_HZ mode, if there's any pending delta, fold it +- * into the pending NO_HZ delta. +- */ +- delta = calc_load_fold_active(this_rq, 0); ++ delta = calc_load_fold_active(rq, 0); + if (delta) { + int idx = calc_load_write_idx(); + +@@ -248,6 +243,24 @@ void calc_load_nohz_start(void) + } + } + ++void calc_load_nohz_start(void) ++{ ++ /* ++ * We're going into NO_HZ mode, if there's any pending delta, fold it ++ * into the pending NO_HZ delta. ++ */ ++ calc_load_nohz_fold(this_rq()); ++} ++ ++/* ++ * Keep track of the load for NOHZ_FULL, must be called between ++ * calc_load_nohz_{start,stop}(). ++ */ ++void calc_load_nohz_remote(struct rq *rq) ++{ ++ calc_load_nohz_fold(rq); ++} ++ + void calc_load_nohz_stop(void) + { + struct rq *this_rq = this_rq(); +@@ -268,7 +281,7 @@ void calc_load_nohz_stop(void) + this_rq->calc_load_update += LOAD_FREQ; + } + +-static long calc_load_nohz_fold(void) ++static long calc_load_nohz_read(void) + { + int idx = calc_load_read_idx(); + long delta = 0; +@@ -323,7 +336,7 @@ static void calc_global_nohz(void) + } + #else /* !CONFIG_NO_HZ_COMMON */ + +-static inline long calc_load_nohz_fold(void) { return 0; } ++static inline long calc_load_nohz_read(void) { return 0; } + static inline void calc_global_nohz(void) { } + + #endif /* CONFIG_NO_HZ_COMMON */ +@@ -346,7 +359,7 @@ void calc_global_load(unsigned long ticks) + /* + * Fold the 'old' NO_HZ-delta to include all NO_HZ CPUs. + */ +- delta = calc_load_nohz_fold(); ++ delta = calc_load_nohz_read(); + if (delta) + atomic_long_add(delta, &calc_load_tasks); + +diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c +index 5ee0f7709410..9577c89179cd 100644 +--- a/kernel/time/vsyscall.c ++++ b/kernel/time/vsyscall.c +@@ -28,11 +28,6 @@ static inline void update_vdso_data(struct vdso_data *vdata, + vdata[CS_RAW].mult = tk->tkr_raw.mult; + vdata[CS_RAW].shift = tk->tkr_raw.shift; + +- /* CLOCK_REALTIME */ +- vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME]; +- vdso_ts->sec = tk->xtime_sec; +- vdso_ts->nsec = tk->tkr_mono.xtime_nsec; +- + /* CLOCK_MONOTONIC */ + vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC]; + vdso_ts->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; +@@ -70,12 +65,6 @@ static inline void update_vdso_data(struct vdso_data *vdata, + vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_TAI]; + vdso_ts->sec = tk->xtime_sec + (s64)tk->tai_offset; + vdso_ts->nsec = tk->tkr_mono.xtime_nsec; +- +- /* +- * Read without the seqlock held by clock_getres(). +- * Note: No need to have a second copy. +- */ +- WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution); + } + + void update_vsyscall(struct timekeeper *tk) +@@ -84,20 +73,17 @@ void update_vsyscall(struct timekeeper *tk) + struct vdso_timestamp *vdso_ts; + u64 nsec; + +- if (__arch_update_vdso_data()) { +- /* +- * Some architectures might want to skip the update of the +- * data page. +- */ +- return; +- } +- + /* copy vsyscall data */ + vdso_write_begin(vdata); + + vdata[CS_HRES_COARSE].clock_mode = __arch_get_clock_mode(tk); + vdata[CS_RAW].clock_mode = __arch_get_clock_mode(tk); + ++ /* CLOCK_REALTIME also required for time() */ ++ vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME]; ++ vdso_ts->sec = tk->xtime_sec; ++ vdso_ts->nsec = tk->tkr_mono.xtime_nsec; ++ + /* CLOCK_REALTIME_COARSE */ + vdso_ts = &vdata[CS_HRES_COARSE].basetime[CLOCK_REALTIME_COARSE]; + vdso_ts->sec = tk->xtime_sec; +@@ -110,7 +96,18 @@ void update_vsyscall(struct timekeeper *tk) + nsec = nsec + tk->wall_to_monotonic.tv_nsec; + vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &vdso_ts->nsec); + +- update_vdso_data(vdata, tk); ++ /* ++ * Read without the seqlock held by clock_getres(). ++ * Note: No need to have a second copy. ++ */ ++ WRITE_ONCE(vdata[CS_HRES_COARSE].hrtimer_res, hrtimer_resolution); ++ ++ /* ++ * Architectures can opt out of updating the high resolution part ++ * of the VDSO. ++ */ ++ if (__arch_update_vdso_data()) ++ update_vdso_data(vdata, tk); + + __arch_update_vsyscall(vdata, tk); + +diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c +index 2d6e93ab0478..4b2ad374167b 100644 +--- a/kernel/trace/blktrace.c ++++ b/kernel/trace/blktrace.c +@@ -336,6 +336,7 @@ static void put_probe_ref(void) + + static void blk_trace_cleanup(struct blk_trace *bt) + { ++ synchronize_rcu(); + blk_trace_free(bt); + put_probe_ref(); + } +@@ -630,8 +631,10 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name, + static int __blk_trace_startstop(struct request_queue *q, int start) + { + int ret; +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ bt = rcu_dereference_protected(q->blk_trace, ++ lockdep_is_held(&q->blk_trace_mutex)); + if (bt == NULL) + return -EINVAL; + +@@ -741,8 +744,8 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) + void blk_trace_shutdown(struct request_queue *q) + { + mutex_lock(&q->blk_trace_mutex); +- +- if (q->blk_trace) { ++ if (rcu_dereference_protected(q->blk_trace, ++ lockdep_is_held(&q->blk_trace_mutex))) { + __blk_trace_startstop(q, 0); + __blk_trace_remove(q); + } +@@ -754,8 +757,10 @@ void blk_trace_shutdown(struct request_queue *q) + static union kernfs_node_id * + blk_trace_bio_get_cgid(struct request_queue *q, struct bio *bio) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ /* We don't use the 'bt' value here except as an optimization... */ ++ bt = rcu_dereference_protected(q->blk_trace, 1); + if (!bt || !(blk_tracer_flags.val & TRACE_BLK_OPT_CGROUP)) + return NULL; + +@@ -800,10 +805,14 @@ static void blk_add_trace_rq(struct request *rq, int error, + unsigned int nr_bytes, u32 what, + union kernfs_node_id *cgid) + { +- struct blk_trace *bt = rq->q->blk_trace; ++ struct blk_trace *bt; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(rq->q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + if (blk_rq_is_passthrough(rq)) + what |= BLK_TC_ACT(BLK_TC_PC); +@@ -812,6 +821,7 @@ static void blk_add_trace_rq(struct request *rq, int error, + + __blk_add_trace(bt, blk_rq_trace_sector(rq), nr_bytes, req_op(rq), + rq->cmd_flags, what, error, 0, NULL, cgid); ++ rcu_read_unlock(); + } + + static void blk_add_trace_rq_insert(void *ignore, +@@ -857,14 +867,19 @@ static void blk_add_trace_rq_complete(void *ignore, struct request *rq, + static void blk_add_trace_bio(struct request_queue *q, struct bio *bio, + u32 what, int error) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size, + bio_op(bio), bio->bi_opf, what, error, 0, NULL, + blk_trace_bio_get_cgid(q, bio)); ++ rcu_read_unlock(); + } + + static void blk_add_trace_bio_bounce(void *ignore, +@@ -909,11 +924,14 @@ static void blk_add_trace_getrq(void *ignore, + if (bio) + blk_add_trace_bio(q, bio, BLK_TA_GETRQ, 0); + else { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) + __blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_GETRQ, 0, 0, + NULL, NULL); ++ rcu_read_unlock(); + } + } + +@@ -925,27 +943,35 @@ static void blk_add_trace_sleeprq(void *ignore, + if (bio) + blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ, 0); + else { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) + __blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_SLEEPRQ, + 0, 0, NULL, NULL); ++ rcu_read_unlock(); + } + } + + static void blk_add_trace_plug(void *ignore, struct request_queue *q) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) + __blk_add_trace(bt, 0, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL, NULL); ++ rcu_read_unlock(); + } + + static void blk_add_trace_unplug(void *ignore, struct request_queue *q, + unsigned int depth, bool explicit) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) { + __be64 rpdu = cpu_to_be64(depth); + u32 what; +@@ -957,14 +983,17 @@ static void blk_add_trace_unplug(void *ignore, struct request_queue *q, + + __blk_add_trace(bt, 0, 0, 0, 0, what, 0, sizeof(rpdu), &rpdu, NULL); + } ++ rcu_read_unlock(); + } + + static void blk_add_trace_split(void *ignore, + struct request_queue *q, struct bio *bio, + unsigned int pdu) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); + if (bt) { + __be64 rpdu = cpu_to_be64(pdu); + +@@ -973,6 +1002,7 @@ static void blk_add_trace_split(void *ignore, + BLK_TA_SPLIT, bio->bi_status, sizeof(rpdu), + &rpdu, blk_trace_bio_get_cgid(q, bio)); + } ++ rcu_read_unlock(); + } + + /** +@@ -992,11 +1022,15 @@ static void blk_add_trace_bio_remap(void *ignore, + struct request_queue *q, struct bio *bio, + dev_t dev, sector_t from) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + struct blk_io_trace_remap r; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + r.device_from = cpu_to_be32(dev); + r.device_to = cpu_to_be32(bio_dev(bio)); +@@ -1005,6 +1039,7 @@ static void blk_add_trace_bio_remap(void *ignore, + __blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size, + bio_op(bio), bio->bi_opf, BLK_TA_REMAP, bio->bi_status, + sizeof(r), &r, blk_trace_bio_get_cgid(q, bio)); ++ rcu_read_unlock(); + } + + /** +@@ -1025,11 +1060,15 @@ static void blk_add_trace_rq_remap(void *ignore, + struct request *rq, dev_t dev, + sector_t from) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + struct blk_io_trace_remap r; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + r.device_from = cpu_to_be32(dev); + r.device_to = cpu_to_be32(disk_devt(rq->rq_disk)); +@@ -1038,6 +1077,7 @@ static void blk_add_trace_rq_remap(void *ignore, + __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), + rq_data_dir(rq), 0, BLK_TA_REMAP, 0, + sizeof(r), &r, blk_trace_request_get_cgid(q, rq)); ++ rcu_read_unlock(); + } + + /** +@@ -1055,14 +1095,19 @@ void blk_add_driver_data(struct request_queue *q, + struct request *rq, + void *data, size_t len) + { +- struct blk_trace *bt = q->blk_trace; ++ struct blk_trace *bt; + +- if (likely(!bt)) ++ rcu_read_lock(); ++ bt = rcu_dereference(q->blk_trace); ++ if (likely(!bt)) { ++ rcu_read_unlock(); + return; ++ } + + __blk_add_trace(bt, blk_rq_trace_sector(rq), blk_rq_bytes(rq), 0, 0, + BLK_TA_DRV_DATA, 0, len, data, + blk_trace_request_get_cgid(q, rq)); ++ rcu_read_unlock(); + } + EXPORT_SYMBOL_GPL(blk_add_driver_data); + +@@ -1589,6 +1634,7 @@ static int blk_trace_remove_queue(struct request_queue *q) + return -EINVAL; + + put_probe_ref(); ++ synchronize_rcu(); + blk_trace_free(bt); + return 0; + } +@@ -1750,6 +1796,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, + struct hd_struct *p = dev_to_part(dev); + struct request_queue *q; + struct block_device *bdev; ++ struct blk_trace *bt; + ssize_t ret = -ENXIO; + + bdev = bdget(part_devt(p)); +@@ -1762,21 +1809,23 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, + + mutex_lock(&q->blk_trace_mutex); + ++ bt = rcu_dereference_protected(q->blk_trace, ++ lockdep_is_held(&q->blk_trace_mutex)); + if (attr == &dev_attr_enable) { +- ret = sprintf(buf, "%u\n", !!q->blk_trace); ++ ret = sprintf(buf, "%u\n", !!bt); + goto out_unlock_bdev; + } + +- if (q->blk_trace == NULL) ++ if (bt == NULL) + ret = sprintf(buf, "disabled\n"); + else if (attr == &dev_attr_act_mask) +- ret = blk_trace_mask2str(buf, q->blk_trace->act_mask); ++ ret = blk_trace_mask2str(buf, bt->act_mask); + else if (attr == &dev_attr_pid) +- ret = sprintf(buf, "%u\n", q->blk_trace->pid); ++ ret = sprintf(buf, "%u\n", bt->pid); + else if (attr == &dev_attr_start_lba) +- ret = sprintf(buf, "%llu\n", q->blk_trace->start_lba); ++ ret = sprintf(buf, "%llu\n", bt->start_lba); + else if (attr == &dev_attr_end_lba) +- ret = sprintf(buf, "%llu\n", q->blk_trace->end_lba); ++ ret = sprintf(buf, "%llu\n", bt->end_lba); + + out_unlock_bdev: + mutex_unlock(&q->blk_trace_mutex); +@@ -1793,6 +1842,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, + struct block_device *bdev; + struct request_queue *q; + struct hd_struct *p; ++ struct blk_trace *bt; + u64 value; + ssize_t ret = -EINVAL; + +@@ -1823,8 +1873,10 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, + + mutex_lock(&q->blk_trace_mutex); + ++ bt = rcu_dereference_protected(q->blk_trace, ++ lockdep_is_held(&q->blk_trace_mutex)); + if (attr == &dev_attr_enable) { +- if (!!value == !!q->blk_trace) { ++ if (!!value == !!bt) { + ret = 0; + goto out_unlock_bdev; + } +@@ -1836,18 +1888,18 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, + } + + ret = 0; +- if (q->blk_trace == NULL) ++ if (bt == NULL) + ret = blk_trace_setup_queue(q, bdev); + + if (ret == 0) { + if (attr == &dev_attr_act_mask) +- q->blk_trace->act_mask = value; ++ bt->act_mask = value; + else if (attr == &dev_attr_pid) +- q->blk_trace->pid = value; ++ bt->pid = value; + else if (attr == &dev_attr_start_lba) +- q->blk_trace->start_lba = value; ++ bt->start_lba = value; + else if (attr == &dev_attr_end_lba) +- q->blk_trace->end_lba = value; ++ bt->end_lba = value; + } + + out_unlock_bdev: +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 341aab32c946..c6ccaf6c62f7 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -1743,6 +1743,7 @@ static __init int init_trace_selftests(void) + + pr_info("Running postponed tracer tests:\n"); + ++ tracing_selftest_running = true; + list_for_each_entry_safe(p, n, &postponed_selftests, list) { + /* This loop can take minutes when sanitizers are enabled, so + * lets make sure we allow RCU processing. +@@ -1765,6 +1766,7 @@ static __init int init_trace_selftests(void) + list_del(&p->list); + kfree(p); + } ++ tracing_selftest_running = false; + + out: + mutex_unlock(&trace_types_lock); +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index 93d97f9b0157..f61d834e02fe 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -299,17 +299,6 @@ config HEADERS_INSTALL + user-space program samples. It is also needed by some features such + as uapi header sanity checks. + +-config HEADERS_CHECK +- bool "Run sanity checks on uapi headers when building 'all'" +- depends on HEADERS_INSTALL +- help +- This option will run basic sanity checks on uapi headers when +- building the 'all' target, for example, ensure that they do not +- attempt to include files which were not exported, etc. +- +- If you're making modifications to header files which are +- relevant for userspace, say 'Y'. +- + config OPTIMIZE_INLINING + def_bool y + help +diff --git a/mm/debug.c b/mm/debug.c +index 0461df1207cb..6a52316af839 100644 +--- a/mm/debug.c ++++ b/mm/debug.c +@@ -47,6 +47,7 @@ void __dump_page(struct page *page, const char *reason) + struct address_space *mapping; + bool page_poisoned = PagePoisoned(page); + int mapcount; ++ char *type = ""; + + /* + * If struct page is poisoned don't access Page*() functions as that +@@ -78,9 +79,9 @@ void __dump_page(struct page *page, const char *reason) + page, page_ref_count(page), mapcount, + page->mapping, page_to_pgoff(page)); + if (PageKsm(page)) +- pr_warn("ksm flags: %#lx(%pGp)\n", page->flags, &page->flags); ++ type = "ksm "; + else if (PageAnon(page)) +- pr_warn("anon flags: %#lx(%pGp)\n", page->flags, &page->flags); ++ type = "anon "; + else if (mapping) { + if (mapping->host && mapping->host->i_dentry.first) { + struct dentry *dentry; +@@ -88,10 +89,11 @@ void __dump_page(struct page *page, const char *reason) + pr_warn("%ps name:\"%pd\"\n", mapping->a_ops, dentry); + } else + pr_warn("%ps\n", mapping->a_ops); +- pr_warn("flags: %#lx(%pGp)\n", page->flags, &page->flags); + } + BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS + 1); + ++ pr_warn("%sflags: %#lx(%pGp)\n", type, page->flags, &page->flags); ++ + hex_only: + print_hex_dump(KERN_WARNING, "raw: ", DUMP_PREFIX_NONE, 32, + sizeof(unsigned long), page, +diff --git a/mm/gup.c b/mm/gup.c +index 8f236a335ae9..745b4036cdfd 100644 +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -2401,7 +2401,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, + unsigned long addr, len, end; + int nr = 0, ret = 0; + +- if (WARN_ON_ONCE(gup_flags & ~(FOLL_WRITE | FOLL_LONGTERM))) ++ if (WARN_ON_ONCE(gup_flags & ~(FOLL_WRITE | FOLL_LONGTERM | ++ FOLL_FORCE))) + return -EINVAL; + + start = untagged_addr(start) & PAGE_MASK; +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 1de7f53621a0..6c9689281c07 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -177,16 +177,13 @@ static ssize_t enabled_store(struct kobject *kobj, + { + ssize_t ret = count; + +- if (!memcmp("always", buf, +- min(sizeof("always")-1, count))) { ++ if (sysfs_streq(buf, "always")) { + clear_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("madvise", buf, +- min(sizeof("madvise")-1, count))) { ++ } else if (sysfs_streq(buf, "madvise")) { + clear_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("never", buf, +- min(sizeof("never")-1, count))) { ++ } else if (sysfs_streq(buf, "never")) { + clear_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags); + } else +@@ -250,32 +247,27 @@ static ssize_t defrag_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) + { +- if (!memcmp("always", buf, +- min(sizeof("always")-1, count))) { ++ if (sysfs_streq(buf, "always")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("defer+madvise", buf, +- min(sizeof("defer+madvise")-1, count))) { ++ } else if (sysfs_streq(buf, "defer+madvise")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("defer", buf, +- min(sizeof("defer")-1, count))) { ++ } else if (sysfs_streq(buf, "defer")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("madvise", buf, +- min(sizeof("madvise")-1, count))) { ++ } else if (sysfs_streq(buf, "madvise")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); + set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage_flags); +- } else if (!memcmp("never", buf, +- min(sizeof("never")-1, count))) { ++ } else if (sysfs_streq(buf, "never")) { + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_flags); + clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hugepage_flags); +@@ -2712,7 +2704,7 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) + unsigned long flags; + pgoff_t end; + +- VM_BUG_ON_PAGE(is_huge_zero_page(page), page); ++ VM_BUG_ON_PAGE(is_huge_zero_page(head), head); + VM_BUG_ON_PAGE(!PageLocked(page), page); + VM_BUG_ON_PAGE(!PageCompound(page), page); + +diff --git a/net/core/dev.c b/net/core/dev.c +index a7e2e57af63a..db8c229e0f4a 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -146,7 +146,6 @@ + #include "net-sysfs.h" + + #define MAX_GRO_SKBS 8 +-#define MAX_NEST_DEV 8 + + /* This should be increased if a protocol with a bigger head is added. */ + #define GRO_MAX_HEAD (MAX_HEADER + 128) +@@ -3386,26 +3385,8 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, + qdisc_calculate_pkt_len(skb, q); + + if (q->flags & TCQ_F_NOLOCK) { +- if ((q->flags & TCQ_F_CAN_BYPASS) && READ_ONCE(q->empty) && +- qdisc_run_begin(q)) { +- if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, +- &q->state))) { +- __qdisc_drop(skb, &to_free); +- rc = NET_XMIT_DROP; +- goto end_run; +- } +- qdisc_bstats_cpu_update(q, skb); +- +- rc = NET_XMIT_SUCCESS; +- if (sch_direct_xmit(skb, q, dev, txq, NULL, true)) +- __qdisc_run(q); +- +-end_run: +- qdisc_run_end(q); +- } else { +- rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK; +- qdisc_run(q); +- } ++ rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK; ++ qdisc_run(q); + + if (unlikely(to_free)) + kfree_skb_list(to_free); +@@ -6932,8 +6913,8 @@ static int __netdev_walk_all_lower_dev(struct net_device *dev, + return 0; + } + +-static struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, +- struct list_head **iter) ++struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, ++ struct list_head **iter) + { + struct netdev_adjacent *lower; + +@@ -6945,6 +6926,7 @@ static struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, + + return lower->dev; + } ++EXPORT_SYMBOL(netdev_next_lower_dev_rcu); + + static u8 __netdev_upper_depth(struct net_device *dev) + { +diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c +index dd220ce7ca7a..bb11fc87bbae 100644 +--- a/net/core/fib_rules.c ++++ b/net/core/fib_rules.c +@@ -967,7 +967,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, + + frh = nlmsg_data(nlh); + frh->family = ops->family; +- frh->table = rule->table; ++ frh->table = rule->table < 256 ? rule->table : RT_TABLE_COMPAT; + if (nla_put_u32(skb, FRA_TABLE, rule->table)) + goto nla_put_failure; + if (nla_put_u32(skb, FRA_SUPPRESS_PREFIXLEN, rule->suppress_prefixlen)) +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index 7ae7065758bd..f3b7cb725c1b 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1856,8 +1856,12 @@ int __udp_disconnect(struct sock *sk, int flags) + inet->inet_dport = 0; + sock_rps_reset_rxhash(sk); + sk->sk_bound_dev_if = 0; +- if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) ++ if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) { + inet_reset_saddr(sk); ++ if (sk->sk_prot->rehash && ++ (sk->sk_userlocks & SOCK_BINDPORT_LOCK)) ++ sk->sk_prot->rehash(sk); ++ } + + if (!(sk->sk_userlocks & SOCK_BINDPORT_LOCK)) { + sk->sk_prot->unhash(sk); +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index 6e2af411cd9c..c75274e0745c 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1050,8 +1050,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + found++; + break; + } +- if (rt_can_ecmp) +- fallback_ins = fallback_ins ?: ins; ++ fallback_ins = fallback_ins ?: ins; + goto next_iter; + } + +@@ -1094,7 +1093,9 @@ next_iter: + } + + if (fallback_ins && !found) { +- /* No ECMP-able route found, replace first non-ECMP one */ ++ /* No matching route with same ecmp-able-ness found, replace ++ * first matching route ++ */ + ins = fallback_ins; + iter = rcu_dereference_protected(*ins, + lockdep_is_held(&rt->fib6_table->tb6_lock)); +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index e4ed9c7b43b0..894c7370c1bd 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -5155,6 +5155,7 @@ static int ip6_route_multipath_add(struct fib6_config *cfg, + */ + cfg->fc_nlinfo.nlh->nlmsg_flags &= ~(NLM_F_EXCL | + NLM_F_REPLACE); ++ cfg->fc_nlinfo.nlh->nlmsg_flags |= NLM_F_CREATE; + nhn++; + } + +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 1e3b9d34aaa4..c7d8044ff0fa 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2959,7 +2959,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, + (auth_transaction == 2 && + ifmgd->auth_data->expected_transaction == 2)) { + if (!ieee80211_mark_sta_auth(sdata, bssid)) +- goto out_err; ++ return; /* ignore frame -- wait for timeout */ + } else if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && + auth_transaction == 2) { + sdata_info(sdata, "SAE peer confirmed\n"); +@@ -2967,10 +2967,6 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, + } + + cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); +- return; +- out_err: +- mutex_unlock(&sdata->local->sta_mtx); +- /* ignore frame -- wait for timeout */ + } + + #define case_WLAN(type) \ +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 32a7a53833c0..decd46b38393 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1063,16 +1063,22 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, + elem_parse_failed = true; + break; + case WLAN_EID_VHT_OPERATION: +- if (elen >= sizeof(struct ieee80211_vht_operation)) ++ if (elen >= sizeof(struct ieee80211_vht_operation)) { + elems->vht_operation = (void *)pos; +- else +- elem_parse_failed = true; ++ if (calc_crc) ++ crc = crc32_be(crc, pos - 2, elen + 2); ++ break; ++ } ++ elem_parse_failed = true; + break; + case WLAN_EID_OPMODE_NOTIF: +- if (elen > 0) ++ if (elen > 0) { + elems->opmode_notif = pos; +- else +- elem_parse_failed = true; ++ if (calc_crc) ++ crc = crc32_be(crc, pos - 2, elen + 2); ++ break; ++ } ++ elem_parse_failed = true; + break; + case WLAN_EID_MESH_ID: + elems->mesh_id = pos; +@@ -2987,10 +2993,22 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, + int cf0, cf1; + int ccfs0, ccfs1, ccfs2; + int ccf0, ccf1; ++ u32 vht_cap; ++ bool support_80_80 = false; ++ bool support_160 = false; + + if (!oper || !htop) + return false; + ++ vht_cap = hw->wiphy->bands[chandef->chan->band]->vht_cap.cap; ++ support_160 = (vht_cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK | ++ IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)); ++ support_80_80 = ((vht_cap & ++ IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) || ++ (vht_cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ && ++ vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) || ++ ((vht_cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) >> ++ IEEE80211_VHT_CAP_EXT_NSS_BW_SHIFT > 1)); + ccfs0 = oper->center_freq_seg0_idx; + ccfs1 = oper->center_freq_seg1_idx; + ccfs2 = (le16_to_cpu(htop->operation_mode) & +@@ -3018,10 +3036,10 @@ bool ieee80211_chandef_vht_oper(struct ieee80211_hw *hw, + unsigned int diff; + + diff = abs(ccf1 - ccf0); +- if (diff == 8) { ++ if ((diff == 8) && support_160) { + new.width = NL80211_CHAN_WIDTH_160; + new.center_freq1 = cf1; +- } else if (diff > 8) { ++ } else if ((diff > 8) && support_80_80) { + new.width = NL80211_CHAN_WIDTH_80P80; + new.center_freq2 = cf1; + } +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index a9df9dac57b2..75da200aa5d8 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -557,6 +557,20 @@ ip_set_rcu_get(struct net *net, ip_set_id_t index) + return set; + } + ++static inline void ++ip_set_lock(struct ip_set *set) ++{ ++ if (!set->variant->region_lock) ++ spin_lock_bh(&set->lock); ++} ++ ++static inline void ++ip_set_unlock(struct ip_set *set) ++{ ++ if (!set->variant->region_lock) ++ spin_unlock_bh(&set->lock); ++} ++ + int + ip_set_test(ip_set_id_t index, const struct sk_buff *skb, + const struct xt_action_param *par, struct ip_set_adt_opt *opt) +@@ -578,9 +592,9 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb, + if (ret == -EAGAIN) { + /* Type requests element to be completed */ + pr_debug("element must be completed, ADD is triggered\n"); +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + set->variant->kadt(set, skb, par, IPSET_ADD, opt); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + ret = 1; + } else { + /* --return-nomatch: invert matched element */ +@@ -609,9 +623,9 @@ ip_set_add(ip_set_id_t index, const struct sk_buff *skb, + !(opt->family == set->family || set->family == NFPROTO_UNSPEC)) + return -IPSET_ERR_TYPE_MISMATCH; + +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + ret = set->variant->kadt(set, skb, par, IPSET_ADD, opt); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + + return ret; + } +@@ -631,9 +645,9 @@ ip_set_del(ip_set_id_t index, const struct sk_buff *skb, + !(opt->family == set->family || set->family == NFPROTO_UNSPEC)) + return -IPSET_ERR_TYPE_MISMATCH; + +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + ret = set->variant->kadt(set, skb, par, IPSET_DEL, opt); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + + return ret; + } +@@ -1098,9 +1112,9 @@ ip_set_flush_set(struct ip_set *set) + { + pr_debug("set: %s\n", set->name); + +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + set->variant->flush(set); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + } + + static int ip_set_flush(struct net *net, struct sock *ctnl, struct sk_buff *skb, +@@ -1523,9 +1537,9 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set, + bool eexist = flags & IPSET_FLAG_EXIST, retried = false; + + do { +- spin_lock_bh(&set->lock); ++ ip_set_lock(set); + ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried); +- spin_unlock_bh(&set->lock); ++ ip_set_unlock(set); + retried = true; + } while (ret == -EAGAIN && + set->variant->resize && +diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h +index d098d87bc331..2389c9f89e48 100644 +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -7,13 +7,21 @@ + #include + #include + #include ++#include + #include + +-#define __ipset_dereference_protected(p, c) rcu_dereference_protected(p, c) +-#define ipset_dereference_protected(p, set) \ +- __ipset_dereference_protected(p, lockdep_is_held(&(set)->lock)) +- +-#define rcu_dereference_bh_nfnl(p) rcu_dereference_bh_check(p, 1) ++#define __ipset_dereference(p) \ ++ rcu_dereference_protected(p, 1) ++#define ipset_dereference_nfnl(p) \ ++ rcu_dereference_protected(p, \ ++ lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET)) ++#define ipset_dereference_set(p, set) \ ++ rcu_dereference_protected(p, \ ++ lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET) || \ ++ lockdep_is_held(&(set)->lock)) ++#define ipset_dereference_bh_nfnl(p) \ ++ rcu_dereference_bh_check(p, \ ++ lockdep_nfnl_is_held(NFNL_SUBSYS_IPSET)) + + /* Hashing which uses arrays to resolve clashing. The hash table is resized + * (doubled) when searching becomes too long. +@@ -72,11 +80,35 @@ struct hbucket { + __aligned(__alignof__(u64)); + }; + ++/* Region size for locking == 2^HTABLE_REGION_BITS */ ++#define HTABLE_REGION_BITS 10 ++#define ahash_numof_locks(htable_bits) \ ++ ((htable_bits) < HTABLE_REGION_BITS ? 1 \ ++ : jhash_size((htable_bits) - HTABLE_REGION_BITS)) ++#define ahash_sizeof_regions(htable_bits) \ ++ (ahash_numof_locks(htable_bits) * sizeof(struct ip_set_region)) ++#define ahash_region(n, htable_bits) \ ++ ((n) % ahash_numof_locks(htable_bits)) ++#define ahash_bucket_start(h, htable_bits) \ ++ ((htable_bits) < HTABLE_REGION_BITS ? 0 \ ++ : (h) * jhash_size(HTABLE_REGION_BITS)) ++#define ahash_bucket_end(h, htable_bits) \ ++ ((htable_bits) < HTABLE_REGION_BITS ? jhash_size(htable_bits) \ ++ : ((h) + 1) * jhash_size(HTABLE_REGION_BITS)) ++ ++struct htable_gc { ++ struct delayed_work dwork; ++ struct ip_set *set; /* Set the gc belongs to */ ++ u32 region; /* Last gc run position */ ++}; ++ + /* The hash table: the table size stored here in order to make resizing easy */ + struct htable { + atomic_t ref; /* References for resizing */ +- atomic_t uref; /* References for dumping */ ++ atomic_t uref; /* References for dumping and gc */ + u8 htable_bits; /* size of hash table == 2^htable_bits */ ++ u32 maxelem; /* Maxelem per region */ ++ struct ip_set_region *hregion; /* Region locks and ext sizes */ + struct hbucket __rcu *bucket[0]; /* hashtable buckets */ + }; + +@@ -162,6 +194,10 @@ htable_bits(u32 hashsize) + #define NLEN 0 + #endif /* IP_SET_HASH_WITH_NETS */ + ++#define SET_ELEM_EXPIRED(set, d) \ ++ (SET_WITH_TIMEOUT(set) && \ ++ ip_set_timeout_expired(ext_timeout(d, set))) ++ + #endif /* _IP_SET_HASH_GEN_H */ + + #ifndef MTYPE +@@ -205,10 +241,12 @@ htable_bits(u32 hashsize) + #undef mtype_test_cidrs + #undef mtype_test + #undef mtype_uref +-#undef mtype_expire + #undef mtype_resize ++#undef mtype_ext_size ++#undef mtype_resize_ad + #undef mtype_head + #undef mtype_list ++#undef mtype_gc_do + #undef mtype_gc + #undef mtype_gc_init + #undef mtype_variant +@@ -247,10 +285,12 @@ htable_bits(u32 hashsize) + #define mtype_test_cidrs IPSET_TOKEN(MTYPE, _test_cidrs) + #define mtype_test IPSET_TOKEN(MTYPE, _test) + #define mtype_uref IPSET_TOKEN(MTYPE, _uref) +-#define mtype_expire IPSET_TOKEN(MTYPE, _expire) + #define mtype_resize IPSET_TOKEN(MTYPE, _resize) ++#define mtype_ext_size IPSET_TOKEN(MTYPE, _ext_size) ++#define mtype_resize_ad IPSET_TOKEN(MTYPE, _resize_ad) + #define mtype_head IPSET_TOKEN(MTYPE, _head) + #define mtype_list IPSET_TOKEN(MTYPE, _list) ++#define mtype_gc_do IPSET_TOKEN(MTYPE, _gc_do) + #define mtype_gc IPSET_TOKEN(MTYPE, _gc) + #define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init) + #define mtype_variant IPSET_TOKEN(MTYPE, _variant) +@@ -275,8 +315,7 @@ htable_bits(u32 hashsize) + /* The generic hash structure */ + struct htype { + struct htable __rcu *table; /* the hash table */ +- struct timer_list gc; /* garbage collection when timeout enabled */ +- struct ip_set *set; /* attached to this ip_set */ ++ struct htable_gc gc; /* gc workqueue */ + u32 maxelem; /* max elements in the hash */ + u32 initval; /* random jhash init value */ + #ifdef IP_SET_HASH_WITH_MARKMASK +@@ -288,21 +327,33 @@ struct htype { + #ifdef IP_SET_HASH_WITH_NETMASK + u8 netmask; /* netmask value for subnets to store */ + #endif ++ struct list_head ad; /* Resize add|del backlist */ + struct mtype_elem next; /* temporary storage for uadd */ + #ifdef IP_SET_HASH_WITH_NETS + struct net_prefixes nets[NLEN]; /* book-keeping of prefixes */ + #endif + }; + ++/* ADD|DEL entries saved during resize */ ++struct mtype_resize_ad { ++ struct list_head list; ++ enum ipset_adt ad; /* ADD|DEL element */ ++ struct mtype_elem d; /* Element value */ ++ struct ip_set_ext ext; /* Extensions for ADD */ ++ struct ip_set_ext mext; /* Target extensions for ADD */ ++ u32 flags; /* Flags for ADD */ ++}; ++ + #ifdef IP_SET_HASH_WITH_NETS + /* Network cidr size book keeping when the hash stores different + * sized networks. cidr == real cidr + 1 to support /0. + */ + static void +-mtype_add_cidr(struct htype *h, u8 cidr, u8 n) ++mtype_add_cidr(struct ip_set *set, struct htype *h, u8 cidr, u8 n) + { + int i, j; + ++ spin_lock_bh(&set->lock); + /* Add in increasing prefix order, so larger cidr first */ + for (i = 0, j = -1; i < NLEN && h->nets[i].cidr[n]; i++) { + if (j != -1) { +@@ -311,7 +362,7 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 n) + j = i; + } else if (h->nets[i].cidr[n] == cidr) { + h->nets[CIDR_POS(cidr)].nets[n]++; +- return; ++ goto unlock; + } + } + if (j != -1) { +@@ -320,24 +371,29 @@ mtype_add_cidr(struct htype *h, u8 cidr, u8 n) + } + h->nets[i].cidr[n] = cidr; + h->nets[CIDR_POS(cidr)].nets[n] = 1; ++unlock: ++ spin_unlock_bh(&set->lock); + } + + static void +-mtype_del_cidr(struct htype *h, u8 cidr, u8 n) ++mtype_del_cidr(struct ip_set *set, struct htype *h, u8 cidr, u8 n) + { + u8 i, j, net_end = NLEN - 1; + ++ spin_lock_bh(&set->lock); + for (i = 0; i < NLEN; i++) { + if (h->nets[i].cidr[n] != cidr) + continue; + h->nets[CIDR_POS(cidr)].nets[n]--; + if (h->nets[CIDR_POS(cidr)].nets[n] > 0) +- return; ++ goto unlock; + for (j = i; j < net_end && h->nets[j].cidr[n]; j++) + h->nets[j].cidr[n] = h->nets[j + 1].cidr[n]; + h->nets[j].cidr[n] = 0; +- return; ++ goto unlock; + } ++unlock: ++ spin_unlock_bh(&set->lock); + } + #endif + +@@ -345,7 +401,7 @@ mtype_del_cidr(struct htype *h, u8 cidr, u8 n) + static size_t + mtype_ahash_memsize(const struct htype *h, const struct htable *t) + { +- return sizeof(*h) + sizeof(*t); ++ return sizeof(*h) + sizeof(*t) + ahash_sizeof_regions(t->htable_bits); + } + + /* Get the ith element from the array block n */ +@@ -369,24 +425,29 @@ mtype_flush(struct ip_set *set) + struct htype *h = set->data; + struct htable *t; + struct hbucket *n; +- u32 i; +- +- t = ipset_dereference_protected(h->table, set); +- for (i = 0; i < jhash_size(t->htable_bits); i++) { +- n = __ipset_dereference_protected(hbucket(t, i), 1); +- if (!n) +- continue; +- if (set->extensions & IPSET_EXT_DESTROY) +- mtype_ext_cleanup(set, n); +- /* FIXME: use slab cache */ +- rcu_assign_pointer(hbucket(t, i), NULL); +- kfree_rcu(n, rcu); ++ u32 r, i; ++ ++ t = ipset_dereference_nfnl(h->table); ++ for (r = 0; r < ahash_numof_locks(t->htable_bits); r++) { ++ spin_lock_bh(&t->hregion[r].lock); ++ for (i = ahash_bucket_start(r, t->htable_bits); ++ i < ahash_bucket_end(r, t->htable_bits); i++) { ++ n = __ipset_dereference(hbucket(t, i)); ++ if (!n) ++ continue; ++ if (set->extensions & IPSET_EXT_DESTROY) ++ mtype_ext_cleanup(set, n); ++ /* FIXME: use slab cache */ ++ rcu_assign_pointer(hbucket(t, i), NULL); ++ kfree_rcu(n, rcu); ++ } ++ t->hregion[r].ext_size = 0; ++ t->hregion[r].elements = 0; ++ spin_unlock_bh(&t->hregion[r].lock); + } + #ifdef IP_SET_HASH_WITH_NETS + memset(h->nets, 0, sizeof(h->nets)); + #endif +- set->elements = 0; +- set->ext_size = 0; + } + + /* Destroy the hashtable part of the set */ +@@ -397,7 +458,7 @@ mtype_ahash_destroy(struct ip_set *set, struct htable *t, bool ext_destroy) + u32 i; + + for (i = 0; i < jhash_size(t->htable_bits); i++) { +- n = __ipset_dereference_protected(hbucket(t, i), 1); ++ n = __ipset_dereference(hbucket(t, i)); + if (!n) + continue; + if (set->extensions & IPSET_EXT_DESTROY && ext_destroy) +@@ -406,6 +467,7 @@ mtype_ahash_destroy(struct ip_set *set, struct htable *t, bool ext_destroy) + kfree(n); + } + ++ ip_set_free(t->hregion); + ip_set_free(t); + } + +@@ -414,28 +476,21 @@ static void + mtype_destroy(struct ip_set *set) + { + struct htype *h = set->data; ++ struct list_head *l, *lt; + + if (SET_WITH_TIMEOUT(set)) +- del_timer_sync(&h->gc); ++ cancel_delayed_work_sync(&h->gc.dwork); + +- mtype_ahash_destroy(set, +- __ipset_dereference_protected(h->table, 1), true); ++ mtype_ahash_destroy(set, ipset_dereference_nfnl(h->table), true); ++ list_for_each_safe(l, lt, &h->ad) { ++ list_del(l); ++ kfree(l); ++ } + kfree(h); + + set->data = NULL; + } + +-static void +-mtype_gc_init(struct ip_set *set, void (*gc)(struct timer_list *t)) +-{ +- struct htype *h = set->data; +- +- timer_setup(&h->gc, gc, 0); +- mod_timer(&h->gc, jiffies + IPSET_GC_PERIOD(set->timeout) * HZ); +- pr_debug("gc initialized, run in every %u\n", +- IPSET_GC_PERIOD(set->timeout)); +-} +- + static bool + mtype_same_set(const struct ip_set *a, const struct ip_set *b) + { +@@ -454,11 +509,9 @@ mtype_same_set(const struct ip_set *a, const struct ip_set *b) + a->extensions == b->extensions; + } + +-/* Delete expired elements from the hashtable */ + static void +-mtype_expire(struct ip_set *set, struct htype *h) ++mtype_gc_do(struct ip_set *set, struct htype *h, struct htable *t, u32 r) + { +- struct htable *t; + struct hbucket *n, *tmp; + struct mtype_elem *data; + u32 i, j, d; +@@ -466,10 +519,12 @@ mtype_expire(struct ip_set *set, struct htype *h) + #ifdef IP_SET_HASH_WITH_NETS + u8 k; + #endif ++ u8 htable_bits = t->htable_bits; + +- t = ipset_dereference_protected(h->table, set); +- for (i = 0; i < jhash_size(t->htable_bits); i++) { +- n = __ipset_dereference_protected(hbucket(t, i), 1); ++ spin_lock_bh(&t->hregion[r].lock); ++ for (i = ahash_bucket_start(r, htable_bits); ++ i < ahash_bucket_end(r, htable_bits); i++) { ++ n = __ipset_dereference(hbucket(t, i)); + if (!n) + continue; + for (j = 0, d = 0; j < n->pos; j++) { +@@ -485,58 +540,100 @@ mtype_expire(struct ip_set *set, struct htype *h) + smp_mb__after_atomic(); + #ifdef IP_SET_HASH_WITH_NETS + for (k = 0; k < IPSET_NET_COUNT; k++) +- mtype_del_cidr(h, ++ mtype_del_cidr(set, h, + NCIDR_PUT(DCIDR_GET(data->cidr, k)), + k); + #endif ++ t->hregion[r].elements--; + ip_set_ext_destroy(set, data); +- set->elements--; + d++; + } + if (d >= AHASH_INIT_SIZE) { + if (d >= n->size) { ++ t->hregion[r].ext_size -= ++ ext_size(n->size, dsize); + rcu_assign_pointer(hbucket(t, i), NULL); + kfree_rcu(n, rcu); + continue; + } + tmp = kzalloc(sizeof(*tmp) + +- (n->size - AHASH_INIT_SIZE) * dsize, +- GFP_ATOMIC); ++ (n->size - AHASH_INIT_SIZE) * dsize, ++ GFP_ATOMIC); + if (!tmp) +- /* Still try to delete expired elements */ ++ /* Still try to delete expired elements. */ + continue; + tmp->size = n->size - AHASH_INIT_SIZE; + for (j = 0, d = 0; j < n->pos; j++) { + if (!test_bit(j, n->used)) + continue; + data = ahash_data(n, j, dsize); +- memcpy(tmp->value + d * dsize, data, dsize); ++ memcpy(tmp->value + d * dsize, ++ data, dsize); + set_bit(d, tmp->used); + d++; + } + tmp->pos = d; +- set->ext_size -= ext_size(AHASH_INIT_SIZE, dsize); ++ t->hregion[r].ext_size -= ++ ext_size(AHASH_INIT_SIZE, dsize); + rcu_assign_pointer(hbucket(t, i), tmp); + kfree_rcu(n, rcu); + } + } ++ spin_unlock_bh(&t->hregion[r].lock); + } + + static void +-mtype_gc(struct timer_list *t) ++mtype_gc(struct work_struct *work) + { +- struct htype *h = from_timer(h, t, gc); +- struct ip_set *set = h->set; ++ struct htable_gc *gc; ++ struct ip_set *set; ++ struct htype *h; ++ struct htable *t; ++ u32 r, numof_locks; ++ unsigned int next_run; ++ ++ gc = container_of(work, struct htable_gc, dwork.work); ++ set = gc->set; ++ h = set->data; + +- pr_debug("called\n"); + spin_lock_bh(&set->lock); +- mtype_expire(set, h); ++ t = ipset_dereference_set(h->table, set); ++ atomic_inc(&t->uref); ++ numof_locks = ahash_numof_locks(t->htable_bits); ++ r = gc->region++; ++ if (r >= numof_locks) { ++ r = gc->region = 0; ++ } ++ next_run = (IPSET_GC_PERIOD(set->timeout) * HZ) / numof_locks; ++ if (next_run < HZ/10) ++ next_run = HZ/10; + spin_unlock_bh(&set->lock); + +- h->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ; +- add_timer(&h->gc); ++ mtype_gc_do(set, h, t, r); ++ ++ if (atomic_dec_and_test(&t->uref) && atomic_read(&t->ref)) { ++ pr_debug("Table destroy after resize by expire: %p\n", t); ++ mtype_ahash_destroy(set, t, false); ++ } ++ ++ queue_delayed_work(system_power_efficient_wq, &gc->dwork, next_run); ++ ++} ++ ++static void ++mtype_gc_init(struct htable_gc *gc) ++{ ++ INIT_DEFERRABLE_WORK(&gc->dwork, mtype_gc); ++ queue_delayed_work(system_power_efficient_wq, &gc->dwork, HZ); + } + ++static int ++mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, ++ struct ip_set_ext *mext, u32 flags); ++static int ++mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, ++ struct ip_set_ext *mext, u32 flags); ++ + /* Resize a hash: create a new hash table with doubling the hashsize + * and inserting the elements to it. Repeat until we succeed or + * fail due to memory pressures. +@@ -547,7 +644,7 @@ mtype_resize(struct ip_set *set, bool retried) + struct htype *h = set->data; + struct htable *t, *orig; + u8 htable_bits; +- size_t extsize, dsize = set->dsize; ++ size_t dsize = set->dsize; + #ifdef IP_SET_HASH_WITH_NETS + u8 flags; + struct mtype_elem *tmp; +@@ -555,7 +652,9 @@ mtype_resize(struct ip_set *set, bool retried) + struct mtype_elem *data; + struct mtype_elem *d; + struct hbucket *n, *m; +- u32 i, j, key; ++ struct list_head *l, *lt; ++ struct mtype_resize_ad *x; ++ u32 i, j, r, nr, key; + int ret; + + #ifdef IP_SET_HASH_WITH_NETS +@@ -563,10 +662,8 @@ mtype_resize(struct ip_set *set, bool retried) + if (!tmp) + return -ENOMEM; + #endif +- rcu_read_lock_bh(); +- orig = rcu_dereference_bh_nfnl(h->table); ++ orig = ipset_dereference_bh_nfnl(h->table); + htable_bits = orig->htable_bits; +- rcu_read_unlock_bh(); + + retry: + ret = 0; +@@ -583,88 +680,124 @@ retry: + ret = -ENOMEM; + goto out; + } ++ t->hregion = ip_set_alloc(ahash_sizeof_regions(htable_bits)); ++ if (!t->hregion) { ++ kfree(t); ++ ret = -ENOMEM; ++ goto out; ++ } + t->htable_bits = htable_bits; ++ t->maxelem = h->maxelem / ahash_numof_locks(htable_bits); ++ for (i = 0; i < ahash_numof_locks(htable_bits); i++) ++ spin_lock_init(&t->hregion[i].lock); + +- spin_lock_bh(&set->lock); +- orig = __ipset_dereference_protected(h->table, 1); +- /* There can't be another parallel resizing, but dumping is possible */ ++ /* There can't be another parallel resizing, ++ * but dumping, gc, kernel side add/del are possible ++ */ ++ orig = ipset_dereference_bh_nfnl(h->table); + atomic_set(&orig->ref, 1); + atomic_inc(&orig->uref); +- extsize = 0; + pr_debug("attempt to resize set %s from %u to %u, t %p\n", + set->name, orig->htable_bits, htable_bits, orig); +- for (i = 0; i < jhash_size(orig->htable_bits); i++) { +- n = __ipset_dereference_protected(hbucket(orig, i), 1); +- if (!n) +- continue; +- for (j = 0; j < n->pos; j++) { +- if (!test_bit(j, n->used)) ++ for (r = 0; r < ahash_numof_locks(orig->htable_bits); r++) { ++ /* Expire may replace a hbucket with another one */ ++ rcu_read_lock_bh(); ++ for (i = ahash_bucket_start(r, orig->htable_bits); ++ i < ahash_bucket_end(r, orig->htable_bits); i++) { ++ n = __ipset_dereference(hbucket(orig, i)); ++ if (!n) + continue; +- data = ahash_data(n, j, dsize); ++ for (j = 0; j < n->pos; j++) { ++ if (!test_bit(j, n->used)) ++ continue; ++ data = ahash_data(n, j, dsize); ++ if (SET_ELEM_EXPIRED(set, data)) ++ continue; + #ifdef IP_SET_HASH_WITH_NETS +- /* We have readers running parallel with us, +- * so the live data cannot be modified. +- */ +- flags = 0; +- memcpy(tmp, data, dsize); +- data = tmp; +- mtype_data_reset_flags(data, &flags); ++ /* We have readers running parallel with us, ++ * so the live data cannot be modified. ++ */ ++ flags = 0; ++ memcpy(tmp, data, dsize); ++ data = tmp; ++ mtype_data_reset_flags(data, &flags); + #endif +- key = HKEY(data, h->initval, htable_bits); +- m = __ipset_dereference_protected(hbucket(t, key), 1); +- if (!m) { +- m = kzalloc(sizeof(*m) + ++ key = HKEY(data, h->initval, htable_bits); ++ m = __ipset_dereference(hbucket(t, key)); ++ nr = ahash_region(key, htable_bits); ++ if (!m) { ++ m = kzalloc(sizeof(*m) + + AHASH_INIT_SIZE * dsize, + GFP_ATOMIC); +- if (!m) { +- ret = -ENOMEM; +- goto cleanup; +- } +- m->size = AHASH_INIT_SIZE; +- extsize += ext_size(AHASH_INIT_SIZE, dsize); +- RCU_INIT_POINTER(hbucket(t, key), m); +- } else if (m->pos >= m->size) { +- struct hbucket *ht; +- +- if (m->size >= AHASH_MAX(h)) { +- ret = -EAGAIN; +- } else { +- ht = kzalloc(sizeof(*ht) + ++ if (!m) { ++ ret = -ENOMEM; ++ goto cleanup; ++ } ++ m->size = AHASH_INIT_SIZE; ++ t->hregion[nr].ext_size += ++ ext_size(AHASH_INIT_SIZE, ++ dsize); ++ RCU_INIT_POINTER(hbucket(t, key), m); ++ } else if (m->pos >= m->size) { ++ struct hbucket *ht; ++ ++ if (m->size >= AHASH_MAX(h)) { ++ ret = -EAGAIN; ++ } else { ++ ht = kzalloc(sizeof(*ht) + + (m->size + AHASH_INIT_SIZE) + * dsize, + GFP_ATOMIC); +- if (!ht) +- ret = -ENOMEM; ++ if (!ht) ++ ret = -ENOMEM; ++ } ++ if (ret < 0) ++ goto cleanup; ++ memcpy(ht, m, sizeof(struct hbucket) + ++ m->size * dsize); ++ ht->size = m->size + AHASH_INIT_SIZE; ++ t->hregion[nr].ext_size += ++ ext_size(AHASH_INIT_SIZE, ++ dsize); ++ kfree(m); ++ m = ht; ++ RCU_INIT_POINTER(hbucket(t, key), ht); + } +- if (ret < 0) +- goto cleanup; +- memcpy(ht, m, sizeof(struct hbucket) + +- m->size * dsize); +- ht->size = m->size + AHASH_INIT_SIZE; +- extsize += ext_size(AHASH_INIT_SIZE, dsize); +- kfree(m); +- m = ht; +- RCU_INIT_POINTER(hbucket(t, key), ht); +- } +- d = ahash_data(m, m->pos, dsize); +- memcpy(d, data, dsize); +- set_bit(m->pos++, m->used); ++ d = ahash_data(m, m->pos, dsize); ++ memcpy(d, data, dsize); ++ set_bit(m->pos++, m->used); ++ t->hregion[nr].elements++; + #ifdef IP_SET_HASH_WITH_NETS +- mtype_data_reset_flags(d, &flags); ++ mtype_data_reset_flags(d, &flags); + #endif ++ } + } ++ rcu_read_unlock_bh(); + } +- rcu_assign_pointer(h->table, t); +- set->ext_size = extsize; + +- spin_unlock_bh(&set->lock); ++ /* There can't be any other writer. */ ++ rcu_assign_pointer(h->table, t); + + /* Give time to other readers of the set */ + synchronize_rcu(); + + pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name, + orig->htable_bits, orig, t->htable_bits, t); +- /* If there's nobody else dumping the table, destroy it */ ++ /* Add/delete elements processed by the SET target during resize. ++ * Kernel-side add cannot trigger a resize and userspace actions ++ * are serialized by the mutex. ++ */ ++ list_for_each_safe(l, lt, &h->ad) { ++ x = list_entry(l, struct mtype_resize_ad, list); ++ if (x->ad == IPSET_ADD) { ++ mtype_add(set, &x->d, &x->ext, &x->mext, x->flags); ++ } else { ++ mtype_del(set, &x->d, NULL, NULL, 0); ++ } ++ list_del(l); ++ kfree(l); ++ } ++ /* If there's nobody else using the table, destroy it */ + if (atomic_dec_and_test(&orig->uref)) { + pr_debug("Table destroy by resize %p\n", orig); + mtype_ahash_destroy(set, orig, false); +@@ -677,15 +810,44 @@ out: + return ret; + + cleanup: ++ rcu_read_unlock_bh(); + atomic_set(&orig->ref, 0); + atomic_dec(&orig->uref); +- spin_unlock_bh(&set->lock); + mtype_ahash_destroy(set, t, false); + if (ret == -EAGAIN) + goto retry; + goto out; + } + ++/* Get the current number of elements and ext_size in the set */ ++static void ++mtype_ext_size(struct ip_set *set, u32 *elements, size_t *ext_size) ++{ ++ struct htype *h = set->data; ++ const struct htable *t; ++ u32 i, j, r; ++ struct hbucket *n; ++ struct mtype_elem *data; ++ ++ t = rcu_dereference_bh(h->table); ++ for (r = 0; r < ahash_numof_locks(t->htable_bits); r++) { ++ for (i = ahash_bucket_start(r, t->htable_bits); ++ i < ahash_bucket_end(r, t->htable_bits); i++) { ++ n = rcu_dereference_bh(hbucket(t, i)); ++ if (!n) ++ continue; ++ for (j = 0; j < n->pos; j++) { ++ if (!test_bit(j, n->used)) ++ continue; ++ data = ahash_data(n, j, set->dsize); ++ if (!SET_ELEM_EXPIRED(set, data)) ++ (*elements)++; ++ } ++ } ++ *ext_size += t->hregion[r].ext_size; ++ } ++} ++ + /* Add an element to a hash and update the internal counters when succeeded, + * otherwise report the proper error code. + */ +@@ -698,32 +860,49 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, + const struct mtype_elem *d = value; + struct mtype_elem *data; + struct hbucket *n, *old = ERR_PTR(-ENOENT); +- int i, j = -1; ++ int i, j = -1, ret; + bool flag_exist = flags & IPSET_FLAG_EXIST; + bool deleted = false, forceadd = false, reuse = false; +- u32 key, multi = 0; ++ u32 r, key, multi = 0, elements, maxelem; + +- if (set->elements >= h->maxelem) { +- if (SET_WITH_TIMEOUT(set)) +- /* FIXME: when set is full, we slow down here */ +- mtype_expire(set, h); +- if (set->elements >= h->maxelem && SET_WITH_FORCEADD(set)) ++ rcu_read_lock_bh(); ++ t = rcu_dereference_bh(h->table); ++ key = HKEY(value, h->initval, t->htable_bits); ++ r = ahash_region(key, t->htable_bits); ++ atomic_inc(&t->uref); ++ elements = t->hregion[r].elements; ++ maxelem = t->maxelem; ++ if (elements >= maxelem) { ++ u32 e; ++ if (SET_WITH_TIMEOUT(set)) { ++ rcu_read_unlock_bh(); ++ mtype_gc_do(set, h, t, r); ++ rcu_read_lock_bh(); ++ } ++ maxelem = h->maxelem; ++ elements = 0; ++ for (e = 0; e < ahash_numof_locks(t->htable_bits); e++) ++ elements += t->hregion[e].elements; ++ if (elements >= maxelem && SET_WITH_FORCEADD(set)) + forceadd = true; + } ++ rcu_read_unlock_bh(); + +- t = ipset_dereference_protected(h->table, set); +- key = HKEY(value, h->initval, t->htable_bits); +- n = __ipset_dereference_protected(hbucket(t, key), 1); ++ spin_lock_bh(&t->hregion[r].lock); ++ n = rcu_dereference_bh(hbucket(t, key)); + if (!n) { +- if (forceadd || set->elements >= h->maxelem) ++ if (forceadd || elements >= maxelem) + goto set_full; + old = NULL; + n = kzalloc(sizeof(*n) + AHASH_INIT_SIZE * set->dsize, + GFP_ATOMIC); +- if (!n) +- return -ENOMEM; ++ if (!n) { ++ ret = -ENOMEM; ++ goto unlock; ++ } + n->size = AHASH_INIT_SIZE; +- set->ext_size += ext_size(AHASH_INIT_SIZE, set->dsize); ++ t->hregion[r].ext_size += ++ ext_size(AHASH_INIT_SIZE, set->dsize); + goto copy_elem; + } + for (i = 0; i < n->pos; i++) { +@@ -737,38 +916,37 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, + } + data = ahash_data(n, i, set->dsize); + if (mtype_data_equal(data, d, &multi)) { +- if (flag_exist || +- (SET_WITH_TIMEOUT(set) && +- ip_set_timeout_expired(ext_timeout(data, set)))) { ++ if (flag_exist || SET_ELEM_EXPIRED(set, data)) { + /* Just the extensions could be overwritten */ + j = i; + goto overwrite_extensions; + } +- return -IPSET_ERR_EXIST; ++ ret = -IPSET_ERR_EXIST; ++ goto unlock; + } + /* Reuse first timed out entry */ +- if (SET_WITH_TIMEOUT(set) && +- ip_set_timeout_expired(ext_timeout(data, set)) && +- j == -1) { ++ if (SET_ELEM_EXPIRED(set, data) && j == -1) { + j = i; + reuse = true; + } + } + if (reuse || forceadd) { ++ if (j == -1) ++ j = 0; + data = ahash_data(n, j, set->dsize); + if (!deleted) { + #ifdef IP_SET_HASH_WITH_NETS + for (i = 0; i < IPSET_NET_COUNT; i++) +- mtype_del_cidr(h, ++ mtype_del_cidr(set, h, + NCIDR_PUT(DCIDR_GET(data->cidr, i)), + i); + #endif + ip_set_ext_destroy(set, data); +- set->elements--; ++ t->hregion[r].elements--; + } + goto copy_data; + } +- if (set->elements >= h->maxelem) ++ if (elements >= maxelem) + goto set_full; + /* Create a new slot */ + if (n->pos >= n->size) { +@@ -776,28 +954,32 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, + if (n->size >= AHASH_MAX(h)) { + /* Trigger rehashing */ + mtype_data_next(&h->next, d); +- return -EAGAIN; ++ ret = -EAGAIN; ++ goto resize; + } + old = n; + n = kzalloc(sizeof(*n) + + (old->size + AHASH_INIT_SIZE) * set->dsize, + GFP_ATOMIC); +- if (!n) +- return -ENOMEM; ++ if (!n) { ++ ret = -ENOMEM; ++ goto unlock; ++ } + memcpy(n, old, sizeof(struct hbucket) + + old->size * set->dsize); + n->size = old->size + AHASH_INIT_SIZE; +- set->ext_size += ext_size(AHASH_INIT_SIZE, set->dsize); ++ t->hregion[r].ext_size += ++ ext_size(AHASH_INIT_SIZE, set->dsize); + } + + copy_elem: + j = n->pos++; + data = ahash_data(n, j, set->dsize); + copy_data: +- set->elements++; ++ t->hregion[r].elements++; + #ifdef IP_SET_HASH_WITH_NETS + for (i = 0; i < IPSET_NET_COUNT; i++) +- mtype_add_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, i)), i); ++ mtype_add_cidr(set, h, NCIDR_PUT(DCIDR_GET(d->cidr, i)), i); + #endif + memcpy(data, d, sizeof(struct mtype_elem)); + overwrite_extensions: +@@ -820,13 +1002,41 @@ overwrite_extensions: + if (old) + kfree_rcu(old, rcu); + } ++ ret = 0; ++resize: ++ spin_unlock_bh(&t->hregion[r].lock); ++ if (atomic_read(&t->ref) && ext->target) { ++ /* Resize is in process and kernel side add, save values */ ++ struct mtype_resize_ad *x; ++ ++ x = kzalloc(sizeof(struct mtype_resize_ad), GFP_ATOMIC); ++ if (!x) ++ /* Don't bother */ ++ goto out; ++ x->ad = IPSET_ADD; ++ memcpy(&x->d, value, sizeof(struct mtype_elem)); ++ memcpy(&x->ext, ext, sizeof(struct ip_set_ext)); ++ memcpy(&x->mext, mext, sizeof(struct ip_set_ext)); ++ x->flags = flags; ++ spin_lock_bh(&set->lock); ++ list_add_tail(&x->list, &h->ad); ++ spin_unlock_bh(&set->lock); ++ } ++ goto out; + +- return 0; + set_full: + if (net_ratelimit()) + pr_warn("Set %s is full, maxelem %u reached\n", +- set->name, h->maxelem); +- return -IPSET_ERR_HASH_FULL; ++ set->name, maxelem); ++ ret = -IPSET_ERR_HASH_FULL; ++unlock: ++ spin_unlock_bh(&t->hregion[r].lock); ++out: ++ if (atomic_dec_and_test(&t->uref) && atomic_read(&t->ref)) { ++ pr_debug("Table destroy after resize by add: %p\n", t); ++ mtype_ahash_destroy(set, t, false); ++ } ++ return ret; + } + + /* Delete an element from the hash and free up space if possible. +@@ -840,13 +1050,23 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + const struct mtype_elem *d = value; + struct mtype_elem *data; + struct hbucket *n; +- int i, j, k, ret = -IPSET_ERR_EXIST; ++ struct mtype_resize_ad *x = NULL; ++ int i, j, k, r, ret = -IPSET_ERR_EXIST; + u32 key, multi = 0; + size_t dsize = set->dsize; + +- t = ipset_dereference_protected(h->table, set); ++ /* Userspace add and resize is excluded by the mutex. ++ * Kernespace add does not trigger resize. ++ */ ++ rcu_read_lock_bh(); ++ t = rcu_dereference_bh(h->table); + key = HKEY(value, h->initval, t->htable_bits); +- n = __ipset_dereference_protected(hbucket(t, key), 1); ++ r = ahash_region(key, t->htable_bits); ++ atomic_inc(&t->uref); ++ rcu_read_unlock_bh(); ++ ++ spin_lock_bh(&t->hregion[r].lock); ++ n = rcu_dereference_bh(hbucket(t, key)); + if (!n) + goto out; + for (i = 0, k = 0; i < n->pos; i++) { +@@ -857,8 +1077,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + data = ahash_data(n, i, dsize); + if (!mtype_data_equal(data, d, &multi)) + continue; +- if (SET_WITH_TIMEOUT(set) && +- ip_set_timeout_expired(ext_timeout(data, set))) ++ if (SET_ELEM_EXPIRED(set, data)) + goto out; + + ret = 0; +@@ -866,20 +1085,33 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + smp_mb__after_atomic(); + if (i + 1 == n->pos) + n->pos--; +- set->elements--; ++ t->hregion[r].elements--; + #ifdef IP_SET_HASH_WITH_NETS + for (j = 0; j < IPSET_NET_COUNT; j++) +- mtype_del_cidr(h, NCIDR_PUT(DCIDR_GET(d->cidr, j)), +- j); ++ mtype_del_cidr(set, h, ++ NCIDR_PUT(DCIDR_GET(d->cidr, j)), j); + #endif + ip_set_ext_destroy(set, data); + ++ if (atomic_read(&t->ref) && ext->target) { ++ /* Resize is in process and kernel side del, ++ * save values ++ */ ++ x = kzalloc(sizeof(struct mtype_resize_ad), ++ GFP_ATOMIC); ++ if (x) { ++ x->ad = IPSET_DEL; ++ memcpy(&x->d, value, ++ sizeof(struct mtype_elem)); ++ x->flags = flags; ++ } ++ } + for (; i < n->pos; i++) { + if (!test_bit(i, n->used)) + k++; + } + if (n->pos == 0 && k == 0) { +- set->ext_size -= ext_size(n->size, dsize); ++ t->hregion[r].ext_size -= ext_size(n->size, dsize); + rcu_assign_pointer(hbucket(t, key), NULL); + kfree_rcu(n, rcu); + } else if (k >= AHASH_INIT_SIZE) { +@@ -898,7 +1130,8 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + k++; + } + tmp->pos = k; +- set->ext_size -= ext_size(AHASH_INIT_SIZE, dsize); ++ t->hregion[r].ext_size -= ++ ext_size(AHASH_INIT_SIZE, dsize); + rcu_assign_pointer(hbucket(t, key), tmp); + kfree_rcu(n, rcu); + } +@@ -906,6 +1139,16 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, + } + + out: ++ spin_unlock_bh(&t->hregion[r].lock); ++ if (x) { ++ spin_lock_bh(&set->lock); ++ list_add(&x->list, &h->ad); ++ spin_unlock_bh(&set->lock); ++ } ++ if (atomic_dec_and_test(&t->uref) && atomic_read(&t->ref)) { ++ pr_debug("Table destroy after resize by del: %p\n", t); ++ mtype_ahash_destroy(set, t, false); ++ } + return ret; + } + +@@ -991,6 +1234,7 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext, + int i, ret = 0; + u32 key, multi = 0; + ++ rcu_read_lock_bh(); + t = rcu_dereference_bh(h->table); + #ifdef IP_SET_HASH_WITH_NETS + /* If we test an IP address and not a network address, +@@ -1022,6 +1266,7 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext, + goto out; + } + out: ++ rcu_read_unlock_bh(); + return ret; + } + +@@ -1033,23 +1278,14 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) + const struct htable *t; + struct nlattr *nested; + size_t memsize; ++ u32 elements = 0; ++ size_t ext_size = 0; + u8 htable_bits; + +- /* If any members have expired, set->elements will be wrong +- * mytype_expire function will update it with the right count. +- * we do not hold set->lock here, so grab it first. +- * set->elements can still be incorrect in the case of a huge set, +- * because elements might time out during the listing. +- */ +- if (SET_WITH_TIMEOUT(set)) { +- spin_lock_bh(&set->lock); +- mtype_expire(set, h); +- spin_unlock_bh(&set->lock); +- } +- + rcu_read_lock_bh(); +- t = rcu_dereference_bh_nfnl(h->table); +- memsize = mtype_ahash_memsize(h, t) + set->ext_size; ++ t = rcu_dereference_bh(h->table); ++ mtype_ext_size(set, &elements, &ext_size); ++ memsize = mtype_ahash_memsize(h, t) + ext_size + set->ext_size; + htable_bits = t->htable_bits; + rcu_read_unlock_bh(); + +@@ -1071,7 +1307,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) + #endif + if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || + nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) || +- nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(set->elements))) ++ nla_put_net32(skb, IPSET_ATTR_ELEMENTS, htonl(elements))) + goto nla_put_failure; + if (unlikely(ip_set_put_flags(skb, set))) + goto nla_put_failure; +@@ -1091,15 +1327,15 @@ mtype_uref(struct ip_set *set, struct netlink_callback *cb, bool start) + + if (start) { + rcu_read_lock_bh(); +- t = rcu_dereference_bh_nfnl(h->table); ++ t = ipset_dereference_bh_nfnl(h->table); + atomic_inc(&t->uref); + cb->args[IPSET_CB_PRIVATE] = (unsigned long)t; + rcu_read_unlock_bh(); + } else if (cb->args[IPSET_CB_PRIVATE]) { + t = (struct htable *)cb->args[IPSET_CB_PRIVATE]; + if (atomic_dec_and_test(&t->uref) && atomic_read(&t->ref)) { +- /* Resizing didn't destroy the hash table */ +- pr_debug("Table destroy by dump: %p\n", t); ++ pr_debug("Table destroy after resize " ++ " by dump: %p\n", t); + mtype_ahash_destroy(set, t, false); + } + cb->args[IPSET_CB_PRIVATE] = 0; +@@ -1141,8 +1377,7 @@ mtype_list(const struct ip_set *set, + if (!test_bit(i, n->used)) + continue; + e = ahash_data(n, i, set->dsize); +- if (SET_WITH_TIMEOUT(set) && +- ip_set_timeout_expired(ext_timeout(e, set))) ++ if (SET_ELEM_EXPIRED(set, e)) + continue; + pr_debug("list hash %lu hbucket %p i %u, data %p\n", + cb->args[IPSET_CB_ARG0], n, i, e); +@@ -1208,6 +1443,7 @@ static const struct ip_set_type_variant mtype_variant = { + .uref = mtype_uref, + .resize = mtype_resize, + .same_set = mtype_same_set, ++ .region_lock = true, + }; + + #ifdef IP_SET_EMIT_CREATE +@@ -1226,6 +1462,7 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + size_t hsize; + struct htype *h; + struct htable *t; ++ u32 i; + + pr_debug("Create set %s with family %s\n", + set->name, set->family == NFPROTO_IPV4 ? "inet" : "inet6"); +@@ -1294,6 +1531,15 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + kfree(h); + return -ENOMEM; + } ++ t->hregion = ip_set_alloc(ahash_sizeof_regions(hbits)); ++ if (!t->hregion) { ++ kfree(t); ++ kfree(h); ++ return -ENOMEM; ++ } ++ h->gc.set = set; ++ for (i = 0; i < ahash_numof_locks(hbits); i++) ++ spin_lock_init(&t->hregion[i].lock); + h->maxelem = maxelem; + #ifdef IP_SET_HASH_WITH_NETMASK + h->netmask = netmask; +@@ -1304,9 +1550,10 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + get_random_bytes(&h->initval, sizeof(h->initval)); + + t->htable_bits = hbits; ++ t->maxelem = h->maxelem / ahash_numof_locks(hbits); + RCU_INIT_POINTER(h->table, t); + +- h->set = set; ++ INIT_LIST_HEAD(&h->ad); + set->data = h; + #ifndef IP_SET_PROTO_UNDEF + if (set->family == NFPROTO_IPV4) { +@@ -1329,12 +1576,10 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + #ifndef IP_SET_PROTO_UNDEF + if (set->family == NFPROTO_IPV4) + #endif +- IPSET_TOKEN(HTYPE, 4_gc_init)(set, +- IPSET_TOKEN(HTYPE, 4_gc)); ++ IPSET_TOKEN(HTYPE, 4_gc_init)(&h->gc); + #ifndef IP_SET_PROTO_UNDEF + else +- IPSET_TOKEN(HTYPE, 6_gc_init)(set, +- IPSET_TOKEN(HTYPE, 6_gc)); ++ IPSET_TOKEN(HTYPE, 6_gc_init)(&h->gc); + #endif + } + pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n", +diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c +index f8d2919cf9fd..037e8fce9b30 100644 +--- a/net/netfilter/nft_tunnel.c ++++ b/net/netfilter/nft_tunnel.c +@@ -505,8 +505,8 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb, + static int nft_tunnel_ports_dump(struct sk_buff *skb, + struct ip_tunnel_info *info) + { +- if (nla_put_be16(skb, NFTA_TUNNEL_KEY_SPORT, htons(info->key.tp_src)) < 0 || +- nla_put_be16(skb, NFTA_TUNNEL_KEY_DPORT, htons(info->key.tp_dst)) < 0) ++ if (nla_put_be16(skb, NFTA_TUNNEL_KEY_SPORT, info->key.tp_src) < 0 || ++ nla_put_be16(skb, NFTA_TUNNEL_KEY_DPORT, info->key.tp_dst) < 0) + return -1; + + return 0; +diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c +index 6520d9ec1297..1b68a131083c 100644 +--- a/net/netfilter/xt_hashlimit.c ++++ b/net/netfilter/xt_hashlimit.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + #include + + #define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \ +@@ -114,7 +115,7 @@ struct dsthash_ent { + + struct xt_hashlimit_htable { + struct hlist_node node; /* global list of all htables */ +- int use; ++ refcount_t use; + u_int8_t family; + bool rnd_initialized; + +@@ -315,7 +316,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg, + for (i = 0; i < hinfo->cfg.size; i++) + INIT_HLIST_HEAD(&hinfo->hash[i]); + +- hinfo->use = 1; ++ refcount_set(&hinfo->use, 1); + hinfo->count = 0; + hinfo->family = family; + hinfo->rnd_initialized = false; +@@ -434,7 +435,7 @@ static struct xt_hashlimit_htable *htable_find_get(struct net *net, + hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) { + if (!strcmp(name, hinfo->name) && + hinfo->family == family) { +- hinfo->use++; ++ refcount_inc(&hinfo->use); + return hinfo; + } + } +@@ -443,12 +444,11 @@ static struct xt_hashlimit_htable *htable_find_get(struct net *net, + + static void htable_put(struct xt_hashlimit_htable *hinfo) + { +- mutex_lock(&hashlimit_mutex); +- if (--hinfo->use == 0) { ++ if (refcount_dec_and_mutex_lock(&hinfo->use, &hashlimit_mutex)) { + hlist_del(&hinfo->node); ++ mutex_unlock(&hashlimit_mutex); + htable_destroy(hinfo); + } +- mutex_unlock(&hashlimit_mutex); + } + + /* The algorithm used is the Simple Token Bucket Filter (TBF) +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 90b2ab9dd449..e64b8784d487 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1014,7 +1014,8 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, + if (nlk->netlink_bind && groups) { + int group; + +- for (group = 0; group < nlk->ngroups; group++) { ++ /* nl_groups is a u32, so cap the maximum groups we can bind */ ++ for (group = 0; group < BITS_PER_TYPE(u32); group++) { + if (!test_bit(group, &groups)) + continue; + err = nlk->netlink_bind(net, group + 1); +@@ -1033,7 +1034,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, + netlink_insert(sk, nladdr->nl_pid) : + netlink_autobind(sock); + if (err) { +- netlink_undo_bind(nlk->ngroups, groups, sk); ++ netlink_undo_bind(BITS_PER_TYPE(u32), groups, sk); + goto unlock; + } + } +diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c +index 5eceeee593cf..1d270540e74d 100644 +--- a/net/sched/cls_flower.c ++++ b/net/sched/cls_flower.c +@@ -303,6 +303,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp, + struct cls_fl_filter *f; + + list_for_each_entry_rcu(mask, &head->masks, list) { ++ flow_dissector_init_keys(&skb_key.control, &skb_key.basic); + fl_clear_masked_range(&skb_key, mask); + + skb_flow_dissect_meta(skb, &mask->dissector, &skb_key); +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index 4ab8208a2dd4..c6d83a64eac3 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -170,6 +170,16 @@ static inline bool sctp_chunk_length_valid(struct sctp_chunk *chunk, + return true; + } + ++/* Check for format error in an ABORT chunk */ ++static inline bool sctp_err_chunk_valid(struct sctp_chunk *chunk) ++{ ++ struct sctp_errhdr *err; ++ ++ sctp_walk_errors(err, chunk->chunk_hdr); ++ ++ return (void *)err == (void *)chunk->chunk_end; ++} ++ + /********************************************************** + * These are the state functions for handling chunk events. + **********************************************************/ +@@ -2255,6 +2265,9 @@ enum sctp_disposition sctp_sf_shutdown_pending_abort( + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + ++ if (!sctp_err_chunk_valid(chunk)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands); + } + +@@ -2298,6 +2311,9 @@ enum sctp_disposition sctp_sf_shutdown_sent_abort( + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + ++ if (!sctp_err_chunk_valid(chunk)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + /* Stop the T2-shutdown timer. */ + sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, + SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); +@@ -2565,6 +2581,9 @@ enum sctp_disposition sctp_sf_do_9_1_abort( + sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) + return sctp_sf_discard_chunk(net, ep, asoc, type, arg, commands); + ++ if (!sctp_err_chunk_valid(chunk)) ++ return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); ++ + return __sctp_sf_do_9_1_abort(net, ep, asoc, type, arg, commands); + } + +@@ -2582,16 +2601,8 @@ static enum sctp_disposition __sctp_sf_do_9_1_abort( + + /* See if we have an error cause code in the chunk. */ + len = ntohs(chunk->chunk_hdr->length); +- if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) { +- struct sctp_errhdr *err; +- +- sctp_walk_errors(err, chunk->chunk_hdr); +- if ((void *)err != (void *)chunk->chunk_end) +- return sctp_sf_pdiscard(net, ep, asoc, type, arg, +- commands); +- ++ if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) + error = ((struct sctp_errhdr *)chunk->skb->data)->cause; +- } + + sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); + /* ASSOC_FAILED will DELETE_TCB. */ +diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c +index 6a6d3b2aa5a9..dc09a72f8110 100644 +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -467,6 +467,8 @@ static void smc_switch_to_fallback(struct smc_sock *smc) + if (smc->sk.sk_socket && smc->sk.sk_socket->file) { + smc->clcsock->file = smc->sk.sk_socket->file; + smc->clcsock->file->private_data = smc->clcsock; ++ smc->clcsock->wq.fasync_list = ++ smc->sk.sk_socket->wq.fasync_list; + } + } + +diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c +index 49bcebff6378..aee9ccfa99c2 100644 +--- a/net/smc/smc_clc.c ++++ b/net/smc/smc_clc.c +@@ -372,7 +372,9 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info) + dclc.hdr.length = htons(sizeof(struct smc_clc_msg_decline)); + dclc.hdr.version = SMC_CLC_V1; + dclc.hdr.flag = (peer_diag_info == SMC_CLC_DECL_SYNCERR) ? 1 : 0; +- memcpy(dclc.id_for_peer, local_systemid, sizeof(local_systemid)); ++ if (smc->conn.lgr && !smc->conn.lgr->is_smcd) ++ memcpy(dclc.id_for_peer, local_systemid, ++ sizeof(local_systemid)); + dclc.peer_diagnosis = htonl(peer_diag_info); + memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)); + +diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c +index 3f5209e2d4ee..1adeb1c0473b 100644 +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -581,7 +581,7 @@ struct tls_record_info *tls_get_record(struct tls_offload_context_tx *context, + u32 seq, u64 *p_record_sn) + { + u64 record_sn = context->hint_record_sn; +- struct tls_record_info *info; ++ struct tls_record_info *info, *last; + + info = context->retransmit_hint; + if (!info || +@@ -593,6 +593,24 @@ struct tls_record_info *tls_get_record(struct tls_offload_context_tx *context, + struct tls_record_info, list); + if (!info) + return NULL; ++ /* send the start_marker record if seq number is before the ++ * tls offload start marker sequence number. This record is ++ * required to handle TCP packets which are before TLS offload ++ * started. ++ * And if it's not start marker, look if this seq number ++ * belongs to the list. ++ */ ++ if (likely(!tls_record_is_start_marker(info))) { ++ /* we have the first record, get the last record to see ++ * if this seq number belongs to the list. ++ */ ++ last = list_last_entry(&context->records_list, ++ struct tls_record_info, list); ++ ++ if (!between(seq, tls_record_start_seq(info), ++ last->end_seq)) ++ return NULL; ++ } + record_sn = context->unacked_record_sn; + } + +diff --git a/net/wireless/ethtool.c b/net/wireless/ethtool.c +index a9c0f368db5d..24e18405cdb4 100644 +--- a/net/wireless/ethtool.c ++++ b/net/wireless/ethtool.c +@@ -7,9 +7,13 @@ + void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) + { + struct wireless_dev *wdev = dev->ieee80211_ptr; ++ struct device *pdev = wiphy_dev(wdev->wiphy); + +- strlcpy(info->driver, wiphy_dev(wdev->wiphy)->driver->name, +- sizeof(info->driver)); ++ if (pdev->driver) ++ strlcpy(info->driver, pdev->driver->name, ++ sizeof(info->driver)); ++ else ++ strlcpy(info->driver, "N/A", sizeof(info->driver)); + + strlcpy(info->version, init_utsname()->release, sizeof(info->version)); + +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index c74646b7a751..17514744af9e 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -437,6 +437,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG }, + [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG }, + [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, ++ [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 }, + [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, + [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, + [NL80211_ATTR_PID] = { .type = NLA_U32 }, +@@ -4794,8 +4795,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) + err = nl80211_parse_he_obss_pd( + info->attrs[NL80211_ATTR_HE_OBSS_PD], + ¶ms.he_obss_pd); +- if (err) +- return err; ++ goto out; + } + + nl80211_calculate_ap_params(¶ms); +@@ -4817,6 +4817,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) + } + wdev_unlock(wdev); + ++out: + kfree(params.acl); + + return err; +diff --git a/scripts/Makefile.build b/scripts/Makefile.build +index a9e47953ca53..24a33c01bbf7 100644 +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -283,15 +283,6 @@ quiet_cmd_cc_lst_c = MKLST $@ + $(obj)/%.lst: $(src)/%.c FORCE + $(call if_changed_dep,cc_lst_c) + +-# header test (header-test-y, header-test-m target) +-# --------------------------------------------------------------------------- +- +-quiet_cmd_cc_s_h = CC $@ +- cmd_cc_s_h = $(CC) $(c_flags) -S -o $@ -x c /dev/null -include $< +- +-$(obj)/%.h.s: $(src)/%.h FORCE +- $(call if_changed_dep,cc_s_h) +- + # Compile assembler sources (.S) + # --------------------------------------------------------------------------- + +diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst +index 1b405a7ed14f..708fbd08a2c5 100644 +--- a/scripts/Makefile.headersinst ++++ b/scripts/Makefile.headersinst +@@ -56,9 +56,6 @@ new-dirs := $(filter-out $(existing-dirs), $(wanted-dirs)) + $(if $(new-dirs), $(shell mkdir -p $(new-dirs))) + + # Rules +- +-ifndef HDRCHECK +- + quiet_cmd_install = HDRINST $@ + cmd_install = $(CONFIG_SHELL) $(srctree)/scripts/headers_install.sh $< $@ + +@@ -81,21 +78,6 @@ existing-headers := $(filter $(old-headers), $(all-headers)) + + -include $(foreach f,$(existing-headers),$(dir $(f)).$(notdir $(f)).cmd) + +-else +- +-quiet_cmd_check = HDRCHK $< +- cmd_check = $(PERL) $(srctree)/scripts/headers_check.pl $(dst) $(SRCARCH) $<; touch $@ +- +-check-files := $(addsuffix .chk, $(all-headers)) +- +-$(check-files): $(dst)/%.chk : $(dst)/% $(srctree)/scripts/headers_check.pl +- $(call cmd,check) +- +-__headers: $(check-files) +- @: +- +-endif +- + PHONY += FORCE + FORCE: + +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index 179d55af5852..a66fc0acad1e 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -65,20 +65,6 @@ extra-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y)) + extra-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-)) + endif + +-# Test self-contained headers +- +-# Wildcard searches in $(srctree)/$(src)/, but not in $(objtree)/$(obj)/. +-# Stale generated headers are often left over, so pattern matching should +-# be avoided. Please notice $(srctree)/$(src)/ and $(objtree)/$(obj) point +-# to the same location for in-tree building. So, header-test-pattern-y should +-# be used with care. +-header-test-y += $(filter-out $(header-test-), \ +- $(patsubst $(srctree)/$(src)/%, %, \ +- $(wildcard $(addprefix $(srctree)/$(src)/, \ +- $(header-test-pattern-y))))) +- +-extra-$(CONFIG_HEADER_TEST) += $(addsuffix .s, $(header-test-y) $(header-test-m)) +- + # Add subdir path + + extra-y := $(addprefix $(obj)/,$(extra-y)) +@@ -305,13 +291,13 @@ DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.yaml + quiet_cmd_dtb_check = CHECK $@ + cmd_dtb_check = $(DT_CHECKER) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ ; + +-define rule_dtc_dt_yaml ++define rule_dtc + $(call cmd_and_fixdep,dtc,yaml) + $(call cmd,dtb_check) + endef + + $(obj)/%.dt.yaml: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE +- $(call if_changed_rule,dtc_dt_yaml) ++ $(call if_changed_rule,dtc) + + dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) + +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index 5380aca2b351..ee9aec5e98f0 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -263,7 +263,7 @@ static void ima_lsm_free_rule(struct ima_rule_entry *entry) + static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) + { + struct ima_rule_entry *nentry; +- int i, result; ++ int i; + + nentry = kmalloc(sizeof(*nentry), GFP_KERNEL); + if (!nentry) +@@ -277,7 +277,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) + memset(nentry->lsm, 0, FIELD_SIZEOF(struct ima_rule_entry, lsm)); + + for (i = 0; i < MAX_LSM_RULES; i++) { +- if (!entry->lsm[i].rule) ++ if (!entry->lsm[i].args_p) + continue; + + nentry->lsm[i].type = entry->lsm[i].type; +@@ -286,13 +286,13 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) + if (!nentry->lsm[i].args_p) + goto out_err; + +- result = security_filter_rule_init(nentry->lsm[i].type, +- Audit_equal, +- nentry->lsm[i].args_p, +- &nentry->lsm[i].rule); +- if (result == -EINVAL) +- pr_warn("ima: rule for LSM \'%d\' is undefined\n", +- entry->lsm[i].type); ++ security_filter_rule_init(nentry->lsm[i].type, ++ Audit_equal, ++ nentry->lsm[i].args_p, ++ &nentry->lsm[i].rule); ++ if (!nentry->lsm[i].rule) ++ pr_warn("rule for LSM \'%s\' is undefined\n", ++ (char *)entry->lsm[i].args_p); + } + return nentry; + +@@ -329,7 +329,7 @@ static void ima_lsm_update_rules(void) + list_for_each_entry_safe(entry, e, &ima_policy_rules, list) { + needs_update = 0; + for (i = 0; i < MAX_LSM_RULES; i++) { +- if (entry->lsm[i].rule) { ++ if (entry->lsm[i].args_p) { + needs_update = 1; + break; + } +@@ -339,8 +339,7 @@ static void ima_lsm_update_rules(void) + + result = ima_lsm_update_rule(entry); + if (result) { +- pr_err("ima: lsm rule update error %d\n", +- result); ++ pr_err("lsm rule update error %d\n", result); + return; + } + } +@@ -357,7 +356,7 @@ int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event, + } + + /** +- * ima_match_rules - determine whether an inode matches the measure rule. ++ * ima_match_rules - determine whether an inode matches the policy rule. + * @rule: a pointer to a rule + * @inode: a pointer to an inode + * @cred: a pointer to a credentials structure for user validation +@@ -415,9 +414,12 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, + int rc = 0; + u32 osid; + +- if (!rule->lsm[i].rule) +- continue; +- ++ if (!rule->lsm[i].rule) { ++ if (!rule->lsm[i].args_p) ++ continue; ++ else ++ return false; ++ } + switch (i) { + case LSM_OBJ_USER: + case LSM_OBJ_ROLE: +@@ -822,8 +824,14 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, + entry->lsm[lsm_rule].args_p, + &entry->lsm[lsm_rule].rule); + if (!entry->lsm[lsm_rule].rule) { +- kfree(entry->lsm[lsm_rule].args_p); +- return -EINVAL; ++ pr_warn("rule for LSM \'%s\' is undefined\n", ++ (char *)entry->lsm[lsm_rule].args_p); ++ ++ if (ima_rules == &ima_default_rules) { ++ kfree(entry->lsm[lsm_rule].args_p); ++ result = -EINVAL; ++ } else ++ result = 0; + } + + return result; +diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c +index 7a7187e069b4..88c3df24b748 100644 +--- a/tools/perf/ui/browsers/hists.c ++++ b/tools/perf/ui/browsers/hists.c +@@ -3054,6 +3054,7 @@ static int perf_evsel__hists_browse(struct evsel *evsel, int nr_events, + + continue; + } ++ actions->ms.map = map; + top = pstack__peek(browser->pstack); + if (top == &browser->hists->dso_filter) { + /* +diff --git a/tools/perf/ui/gtk/Build b/tools/perf/ui/gtk/Build +index ec22e899a224..9b5d5cbb7af7 100644 +--- a/tools/perf/ui/gtk/Build ++++ b/tools/perf/ui/gtk/Build +@@ -7,3 +7,8 @@ gtk-y += util.o + gtk-y += helpline.o + gtk-y += progress.o + gtk-y += annotate.o ++gtk-y += zalloc.o ++ ++$(OUTPUT)ui/gtk/zalloc.o: ../lib/zalloc.c FORCE ++ $(call rule_mkdir) ++ $(call if_changed_dep,cc_o_c) +diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile +index cd1f5b3a7774..d6e106fbce11 100644 +--- a/tools/testing/selftests/ftrace/Makefile ++++ b/tools/testing/selftests/ftrace/Makefile +@@ -2,7 +2,7 @@ + all: + + TEST_PROGS := ftracetest +-TEST_FILES := test.d ++TEST_FILES := test.d settings + EXTRA_CLEAN := $(OUTPUT)/logs/* + + include ../lib.mk +diff --git a/tools/testing/selftests/livepatch/Makefile b/tools/testing/selftests/livepatch/Makefile +index fd405402c3ff..485696a01989 100644 +--- a/tools/testing/selftests/livepatch/Makefile ++++ b/tools/testing/selftests/livepatch/Makefile +@@ -6,4 +6,6 @@ TEST_PROGS := \ + test-callbacks.sh \ + test-shadow-vars.sh + ++TEST_FILES := settings ++ + include ../lib.mk +diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh +index 76c1897e6352..474638ef2697 100755 +--- a/tools/testing/selftests/net/fib_tests.sh ++++ b/tools/testing/selftests/net/fib_tests.sh +@@ -910,6 +910,12 @@ ipv6_rt_replace_mpath() + check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" + log_test $? 0 "Multipath with single path via multipath attribute" + ++ # multipath with dev-only ++ add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" ++ run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1" ++ check_route6 "2001:db8:104::/64 dev veth1 metric 1024" ++ log_test $? 0 "Multipath with dev-only" ++ + # route replace fails - invalid nexthop 1 + add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" + run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3" +diff --git a/tools/testing/selftests/rseq/Makefile b/tools/testing/selftests/rseq/Makefile +index d6469535630a..f1053630bb6f 100644 +--- a/tools/testing/selftests/rseq/Makefile ++++ b/tools/testing/selftests/rseq/Makefile +@@ -19,6 +19,8 @@ TEST_GEN_PROGS_EXTENDED = librseq.so + + TEST_PROGS = run_param_test.sh + ++TEST_FILES := settings ++ + include ../lib.mk + + $(OUTPUT)/librseq.so: rseq.c rseq.h rseq-*.h +diff --git a/tools/testing/selftests/rtc/Makefile b/tools/testing/selftests/rtc/Makefile +index de9c8566672a..90fa1a346908 100644 +--- a/tools/testing/selftests/rtc/Makefile ++++ b/tools/testing/selftests/rtc/Makefile +@@ -6,4 +6,6 @@ TEST_GEN_PROGS = rtctest + + TEST_GEN_PROGS_EXTENDED = setdate + ++TEST_FILES := settings ++ + include ../lib.mk +diff --git a/usr/include/Makefile b/usr/include/Makefile +index 57b20f7b6729..47cb91d3a51d 100644 +--- a/usr/include/Makefile ++++ b/usr/include/Makefile +@@ -99,9 +99,16 @@ endif + # asm-generic/*.h is used by asm/*.h, and should not be included directly + header-test- += asm-generic/% + +-# The rest are compile-tested +-header-test-y += $(filter-out $(header-test-), \ +- $(patsubst $(obj)/%,%, $(wildcard \ +- $(addprefix $(obj)/, *.h */*.h */*/*.h */*/*/*.h)))) ++extra-y := $(patsubst $(obj)/%.h,%.hdrtest, $(shell find $(obj) -name '*.h')) ++ ++quiet_cmd_hdrtest = HDRTEST $< ++ cmd_hdrtest = \ ++ $(CC) $(c_flags) -S -o /dev/null -x c /dev/null \ ++ $(if $(filter-out $(header-test-), $*.h), -include $<); \ ++ $(PERL) $(srctree)/scripts/headers_check.pl $(obj) $(SRCARCH) $<; \ ++ touch $@ ++ ++$(obj)/%.hdrtest: $(obj)/%.h FORCE ++ $(call if_changed_dep,hdrtest) + + clean-files += $(filter-out Makefile, $(notdir $(wildcard $(obj)/*))) +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index b5ea1bafe513..03c681568ab1 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -2275,12 +2275,12 @@ int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + if (slots->generation != ghc->generation) + __kvm_gfn_to_hva_cache_init(slots, ghc, ghc->gpa, ghc->len); + +- if (unlikely(!ghc->memslot)) +- return kvm_write_guest(kvm, gpa, data, len); +- + if (kvm_is_error_hva(ghc->hva)) + return -EFAULT; + ++ if (unlikely(!ghc->memslot)) ++ return kvm_write_guest(kvm, gpa, data, len); ++ + r = __copy_to_user((void __user *)ghc->hva + offset, data, len); + if (r) + return -EFAULT; +@@ -2308,12 +2308,12 @@ int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + if (slots->generation != ghc->generation) + __kvm_gfn_to_hva_cache_init(slots, ghc, ghc->gpa, ghc->len); + +- if (unlikely(!ghc->memslot)) +- return kvm_read_guest(kvm, ghc->gpa, data, len); +- + if (kvm_is_error_hva(ghc->hva)) + return -EFAULT; + ++ if (unlikely(!ghc->memslot)) ++ return kvm_read_guest(kvm, ghc->gpa, data, len); ++ + r = __copy_from_user(data, (void __user *)ghc->hva, len); + if (r) + return -EFAULT; diff --git a/patch/kernel/odroidxu4-current/03-patch-5.4.24-25.patch b/patch/kernel/odroidxu4-current/03-patch-5.4.24-25.patch new file mode 100644 index 0000000000..58f0901530 --- /dev/null +++ b/patch/kernel/odroidxu4-current/03-patch-5.4.24-25.patch @@ -0,0 +1,6231 @@ +diff --git a/Makefile b/Makefile +index c32c78cf2fe5..85e41313f078 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 24 ++SUBLEVEL = 25 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arm/boot/dts/am437x-idk-evm.dts b/arch/arm/boot/dts/am437x-idk-evm.dts +index f3ced6df0c9b..9f66f96d09c9 100644 +--- a/arch/arm/boot/dts/am437x-idk-evm.dts ++++ b/arch/arm/boot/dts/am437x-idk-evm.dts +@@ -526,11 +526,11 @@ + * Supply voltage supervisor on board will not allow opp50 so + * disable it and set opp100 as suspend OPP. + */ +- opp50@300000000 { ++ opp50-300000000 { + status = "disabled"; + }; + +- opp100@600000000 { ++ opp100-600000000 { + opp-suspend; + }; + }; +diff --git a/arch/arm/boot/dts/dra76x.dtsi b/arch/arm/boot/dts/dra76x.dtsi +index cdcba3f561c4..9f6fbe4c1fee 100644 +--- a/arch/arm/boot/dts/dra76x.dtsi ++++ b/arch/arm/boot/dts/dra76x.dtsi +@@ -86,3 +86,8 @@ + &usb4_tm { + status = "disabled"; + }; ++ ++&mmc3 { ++ /* dra76x is not affected by i887 */ ++ max-frequency = <96000000>; ++}; +diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi +index 93e1eb83bed9..d7d98d2069df 100644 +--- a/arch/arm/boot/dts/dra7xx-clocks.dtsi ++++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi +@@ -796,16 +796,6 @@ + clock-div = <1>; + }; + +- ipu1_gfclk_mux: ipu1_gfclk_mux@520 { +- #clock-cells = <0>; +- compatible = "ti,mux-clock"; +- clocks = <&dpll_abe_m2x2_ck>, <&dpll_core_h22x2_ck>; +- ti,bit-shift = <24>; +- reg = <0x0520>; +- assigned-clocks = <&ipu1_gfclk_mux>; +- assigned-clock-parents = <&dpll_core_h22x2_ck>; +- }; +- + dummy_ck: dummy_ck { + #clock-cells = <0>; + compatible = "fixed-clock"; +@@ -1564,6 +1554,8 @@ + compatible = "ti,clkctrl"; + reg = <0x20 0x4>; + #clock-cells = <2>; ++ assigned-clocks = <&ipu1_clkctrl DRA7_IPU1_MMU_IPU1_CLKCTRL 24>; ++ assigned-clock-parents = <&dpll_core_h22x2_ck>; + }; + + ipu_clkctrl: ipu-clkctrl@50 { +diff --git a/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi +index 6486df3e2942..881cea0b61ba 100644 +--- a/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi +@@ -183,7 +183,6 @@ + pinctrl-0 = <&pinctrl_usdhc4>; + bus-width = <8>; + non-removable; +- vmmc-supply = <&vdd_emmc_1p8>; + status = "disabled"; + }; + +diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi +index 917eb0b58b13..eed78f12e79e 100644 +--- a/arch/arm/boot/dts/imx7-colibri.dtsi ++++ b/arch/arm/boot/dts/imx7-colibri.dtsi +@@ -337,7 +337,6 @@ + assigned-clock-rates = <400000000>; + bus-width = <8>; + fsl,tuning-step = <2>; +- max-frequency = <100000000>; + vmmc-supply = <®_module_3v3>; + vqmmc-supply = <®_DCDC3>; + non-removable; +diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi +index 2f6977ada447..63d9f4a066e3 100644 +--- a/arch/arm/boot/dts/ls1021a.dtsi ++++ b/arch/arm/boot/dts/ls1021a.dtsi +@@ -728,7 +728,7 @@ + }; + + mdio0: mdio@2d24000 { +- compatible = "fsl,etsec2-mdio"; ++ compatible = "gianfar"; + device_type = "mdio"; + #address-cells = <1>; + #size-cells = <0>; +@@ -737,7 +737,7 @@ + }; + + mdio1: mdio@2d64000 { +- compatible = "fsl,etsec2-mdio"; ++ compatible = "gianfar"; + device_type = "mdio"; + #address-cells = <1>; + #size-cells = <0>; +diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile +index 35ff620537e6..03506ce46149 100644 +--- a/arch/arm/mach-imx/Makefile ++++ b/arch/arm/mach-imx/Makefile +@@ -91,6 +91,8 @@ AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a + obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o + obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o + endif ++AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a ++obj-$(CONFIG_SOC_IMX6) += resume-imx6.o + obj-$(CONFIG_SOC_IMX6) += pm-imx6.o + + obj-$(CONFIG_SOC_IMX1) += mach-imx1.o +diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h +index 912aeceb4ff8..5aa5796cff0e 100644 +--- a/arch/arm/mach-imx/common.h ++++ b/arch/arm/mach-imx/common.h +@@ -109,17 +109,17 @@ void imx_cpu_die(unsigned int cpu); + int imx_cpu_kill(unsigned int cpu); + + #ifdef CONFIG_SUSPEND +-void v7_cpu_resume(void); + void imx53_suspend(void __iomem *ocram_vbase); + extern const u32 imx53_suspend_sz; + void imx6_suspend(void __iomem *ocram_vbase); + #else +-static inline void v7_cpu_resume(void) {} + static inline void imx53_suspend(void __iomem *ocram_vbase) {} + static const u32 imx53_suspend_sz; + static inline void imx6_suspend(void __iomem *ocram_vbase) {} + #endif + ++void v7_cpu_resume(void); ++ + void imx6_pm_ccm_init(const char *ccm_compat); + void imx6q_pm_init(void); + void imx6dl_pm_init(void); +diff --git a/arch/arm/mach-imx/resume-imx6.S b/arch/arm/mach-imx/resume-imx6.S +new file mode 100644 +index 000000000000..5bd1ba7ef15b +--- /dev/null ++++ b/arch/arm/mach-imx/resume-imx6.S +@@ -0,0 +1,24 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ * Copyright 2014 Freescale Semiconductor, Inc. ++ */ ++ ++#include ++#include ++#include ++#include ++#include "hardware.h" ++ ++/* ++ * The following code must assume it is running from physical address ++ * where absolute virtual addresses to the data section have to be ++ * turned into relative ones. ++ */ ++ ++ENTRY(v7_cpu_resume) ++ bl v7_invalidate_l1 ++#ifdef CONFIG_CACHE_L2X0 ++ bl l2c310_early_resume ++#endif ++ b cpu_resume ++ENDPROC(v7_cpu_resume) +diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S +index 062391ff13da..1eabf2d2834b 100644 +--- a/arch/arm/mach-imx/suspend-imx6.S ++++ b/arch/arm/mach-imx/suspend-imx6.S +@@ -327,17 +327,3 @@ resume: + + ret lr + ENDPROC(imx6_suspend) +- +-/* +- * The following code must assume it is running from physical address +- * where absolute virtual addresses to the data section have to be +- * turned into relative ones. +- */ +- +-ENTRY(v7_cpu_resume) +- bl v7_invalidate_l1 +-#ifdef CONFIG_CACHE_L2X0 +- bl l2c310_early_resume +-#endif +- b cpu_resume +-ENDPROC(v7_cpu_resume) +diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +index 4d67eb715b91..3f43716d5c45 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +@@ -327,7 +327,7 @@ + #size-cells = <0>; + + bus-width = <4>; +- max-frequency = <50000000>; ++ max-frequency = <60000000>; + + non-removable; + disable-wp; +diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts +index 5d6a8dafe8dc..29ac78ddc057 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts ++++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts +@@ -363,6 +363,7 @@ + compatible = "brcm,bcm43438-bt"; + interrupt-parent = <&gpio_intc>; + interrupts = <95 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-names = "host-wakeup"; + shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; +diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts +index 19468058e6ae..8148196902dd 100644 +--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts ++++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts +@@ -52,11 +52,6 @@ + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; +- +- ethphy1: ethernet-phy@1 { +- compatible = "ethernet-phy-ieee802.3-c22"; +- reg = <1>; +- }; + }; + }; + +diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi +index d2cb28da3fff..d911d38877e5 100644 +--- a/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi ++++ b/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi +@@ -82,7 +82,7 @@ + ranges = <0 0 0 0xffffffff>; + + gmac0: ethernet@ff800000 { +- compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; ++ compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; + reg = <0xff800000 0x2000>; + interrupts = <0 90 4>; + interrupt-names = "macirq"; +@@ -97,7 +97,7 @@ + }; + + gmac1: ethernet@ff802000 { +- compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; ++ compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; + reg = <0xff802000 0x2000>; + interrupts = <0 91 4>; + interrupt-names = "macirq"; +@@ -112,7 +112,7 @@ + }; + + gmac2: ethernet@ff804000 { +- compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; ++ compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; + reg = <0xff804000 0x2000>; + interrupts = <0 92 4>; + interrupt-names = "macirq"; +diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig +index 3973847b5f42..48b2e1b59119 100644 +--- a/arch/csky/Kconfig ++++ b/arch/csky/Kconfig +@@ -36,6 +36,7 @@ config CSKY + select GX6605S_TIMER if CPU_CK610 + select HAVE_ARCH_TRACEHOOK + select HAVE_ARCH_AUDITSYSCALL ++ select HAVE_COPY_THREAD_TLS + select HAVE_DYNAMIC_FTRACE + select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_GRAPH_TRACER +@@ -74,7 +75,7 @@ config CPU_HAS_TLBI + config CPU_HAS_LDSTEX + bool + help +- For SMP, CPU needs "ldex&stex" instrcutions to atomic operations. ++ For SMP, CPU needs "ldex&stex" instructions for atomic operations. + + config CPU_NEED_TLBSYNC + bool +diff --git a/arch/csky/abiv1/inc/abi/entry.h b/arch/csky/abiv1/inc/abi/entry.h +index 7ab78bd0f3b1..f35a9f3315ee 100644 +--- a/arch/csky/abiv1/inc/abi/entry.h ++++ b/arch/csky/abiv1/inc/abi/entry.h +@@ -16,14 +16,16 @@ + #define LSAVE_A4 40 + #define LSAVE_A5 44 + ++#define usp ss1 ++ + .macro USPTOKSP +- mtcr sp, ss1 ++ mtcr sp, usp + mfcr sp, ss0 + .endm + + .macro KSPTOUSP + mtcr sp, ss0 +- mfcr sp, ss1 ++ mfcr sp, usp + .endm + + .macro SAVE_ALL epc_inc +@@ -45,7 +47,13 @@ + add lr, r13 + stw lr, (sp, 8) + ++ mov lr, sp ++ addi lr, 32 ++ addi lr, 32 ++ addi lr, 16 ++ bt 2f + mfcr lr, ss1 ++2: + stw lr, (sp, 16) + + stw a0, (sp, 20) +@@ -79,9 +87,10 @@ + ldw a0, (sp, 12) + mtcr a0, epsr + btsti a0, 31 ++ bt 1f + ldw a0, (sp, 16) + mtcr a0, ss1 +- ++1: + ldw a0, (sp, 24) + ldw a1, (sp, 28) + ldw a2, (sp, 32) +@@ -102,9 +111,9 @@ + addi sp, 32 + addi sp, 8 + +- bt 1f ++ bt 2f + KSPTOUSP +-1: ++2: + rte + .endm + +diff --git a/arch/csky/abiv2/inc/abi/entry.h b/arch/csky/abiv2/inc/abi/entry.h +index 9897a16b45e5..94a7a58765df 100644 +--- a/arch/csky/abiv2/inc/abi/entry.h ++++ b/arch/csky/abiv2/inc/abi/entry.h +@@ -31,7 +31,13 @@ + + mfcr lr, epsr + stw lr, (sp, 12) ++ btsti lr, 31 ++ bf 1f ++ addi lr, sp, 152 ++ br 2f ++1: + mfcr lr, usp ++2: + stw lr, (sp, 16) + + stw a0, (sp, 20) +@@ -64,8 +70,10 @@ + mtcr a0, epc + ldw a0, (sp, 12) + mtcr a0, epsr ++ btsti a0, 31 + ldw a0, (sp, 16) + mtcr a0, usp ++ mtcr a0, ss0 + + #ifdef CONFIG_CPU_HAS_HILO + ldw a0, (sp, 140) +@@ -86,6 +94,9 @@ + addi sp, 40 + ldm r16-r30, (sp) + addi sp, 72 ++ bf 1f ++ mfcr sp, ss0 ++1: + rte + .endm + +diff --git a/arch/csky/include/uapi/asm/unistd.h b/arch/csky/include/uapi/asm/unistd.h +index 211c983c7282..ba4018929733 100644 +--- a/arch/csky/include/uapi/asm/unistd.h ++++ b/arch/csky/include/uapi/asm/unistd.h +@@ -1,7 +1,10 @@ + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ + // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + ++#define __ARCH_WANT_STAT64 ++#define __ARCH_WANT_NEW_STAT + #define __ARCH_WANT_SYS_CLONE ++#define __ARCH_WANT_SYS_CLONE3 + #define __ARCH_WANT_SET_GET_RLIMIT + #define __ARCH_WANT_TIME32_SYSCALLS + #include +diff --git a/arch/csky/kernel/atomic.S b/arch/csky/kernel/atomic.S +index 5b84f11485ae..3821ef9b7567 100644 +--- a/arch/csky/kernel/atomic.S ++++ b/arch/csky/kernel/atomic.S +@@ -17,10 +17,12 @@ ENTRY(csky_cmpxchg) + mfcr a3, epc + addi a3, TRAP0_SIZE + +- subi sp, 8 ++ subi sp, 16 + stw a3, (sp, 0) + mfcr a3, epsr + stw a3, (sp, 4) ++ mfcr a3, usp ++ stw a3, (sp, 8) + + psrset ee + #ifdef CONFIG_CPU_HAS_LDSTEX +@@ -47,7 +49,9 @@ ENTRY(csky_cmpxchg) + mtcr a3, epc + ldw a3, (sp, 4) + mtcr a3, epsr +- addi sp, 8 ++ ldw a3, (sp, 8) ++ mtcr a3, usp ++ addi sp, 16 + KSPTOUSP + rte + END(csky_cmpxchg) +diff --git a/arch/csky/kernel/process.c b/arch/csky/kernel/process.c +index f320d9248a22..397962e11bd1 100644 +--- a/arch/csky/kernel/process.c ++++ b/arch/csky/kernel/process.c +@@ -34,10 +34,11 @@ unsigned long thread_saved_pc(struct task_struct *tsk) + return sw->r15; + } + +-int copy_thread(unsigned long clone_flags, ++int copy_thread_tls(unsigned long clone_flags, + unsigned long usp, + unsigned long kthread_arg, +- struct task_struct *p) ++ struct task_struct *p, ++ unsigned long tls) + { + struct switch_stack *childstack; + struct pt_regs *childregs = task_pt_regs(p); +@@ -64,7 +65,7 @@ int copy_thread(unsigned long clone_flags, + childregs->usp = usp; + if (clone_flags & CLONE_SETTLS) + task_thread_info(p)->tp_value = childregs->tls +- = childregs->regs[0]; ++ = tls; + + childregs->a0 = 0; + childstack->r15 = (unsigned long) ret_from_fork; +diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c +index b753d382e4ce..0bb0954d5570 100644 +--- a/arch/csky/kernel/smp.c ++++ b/arch/csky/kernel/smp.c +@@ -120,7 +120,7 @@ void __init setup_smp_ipi(void) + int rc; + + if (ipi_irq == 0) +- panic("%s IRQ mapping failed\n", __func__); ++ return; + + rc = request_percpu_irq(ipi_irq, handle_ipi, "IPI Interrupt", + &ipi_dummy_dev); +diff --git a/arch/csky/mm/Makefile b/arch/csky/mm/Makefile +index c94ef6481098..efb7ebab342b 100644 +--- a/arch/csky/mm/Makefile ++++ b/arch/csky/mm/Makefile +@@ -1,8 +1,10 @@ + # SPDX-License-Identifier: GPL-2.0-only + ifeq ($(CONFIG_CPU_HAS_CACHEV2),y) + obj-y += cachev2.o ++CFLAGS_REMOVE_cachev2.o = $(CC_FLAGS_FTRACE) + else + obj-y += cachev1.o ++CFLAGS_REMOVE_cachev1.o = $(CC_FLAGS_FTRACE) + endif + + obj-y += dma-mapping.o +diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c +index d4c2292ea46b..00e96278b377 100644 +--- a/arch/csky/mm/init.c ++++ b/arch/csky/mm/init.c +@@ -31,6 +31,7 @@ + + pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss; + pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss; ++EXPORT_SYMBOL(invalid_pte_table); + unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] + __page_aligned_bss; + EXPORT_SYMBOL(empty_zero_page); +diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h +index 45e3137ccd71..72b81015cebe 100644 +--- a/arch/powerpc/include/asm/cache.h ++++ b/arch/powerpc/include/asm/cache.h +@@ -55,42 +55,48 @@ struct ppc64_caches { + + extern struct ppc64_caches ppc64_caches; + +-static inline u32 l1_cache_shift(void) ++static inline u32 l1_dcache_shift(void) + { + return ppc64_caches.l1d.log_block_size; + } + +-static inline u32 l1_cache_bytes(void) ++static inline u32 l1_dcache_bytes(void) + { + return ppc64_caches.l1d.block_size; + } ++ ++static inline u32 l1_icache_shift(void) ++{ ++ return ppc64_caches.l1i.log_block_size; ++} ++ ++static inline u32 l1_icache_bytes(void) ++{ ++ return ppc64_caches.l1i.block_size; ++} + #else +-static inline u32 l1_cache_shift(void) ++static inline u32 l1_dcache_shift(void) + { + return L1_CACHE_SHIFT; + } + +-static inline u32 l1_cache_bytes(void) ++static inline u32 l1_dcache_bytes(void) + { + return L1_CACHE_BYTES; + } ++ ++static inline u32 l1_icache_shift(void) ++{ ++ return L1_CACHE_SHIFT; ++} ++ ++static inline u32 l1_icache_bytes(void) ++{ ++ return L1_CACHE_BYTES; ++} ++ + #endif +-#endif /* ! __ASSEMBLY__ */ +- +-#if defined(__ASSEMBLY__) +-/* +- * For a snooping icache, we still need a dummy icbi to purge all the +- * prefetched instructions from the ifetch buffers. We also need a sync +- * before the icbi to order the the actual stores to memory that might +- * have modified instructions with the icbi. +- */ +-#define PURGE_PREFETCHED_INS \ +- sync; \ +- icbi 0,r3; \ +- sync; \ +- isync + +-#else + #define __read_mostly __attribute__((__section__(".data..read_mostly"))) + + #ifdef CONFIG_PPC_BOOK3S_32 +@@ -124,6 +130,17 @@ static inline void dcbst(void *addr) + { + __asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory"); + } ++ ++static inline void icbi(void *addr) ++{ ++ asm volatile ("icbi 0, %0" : : "r"(addr) : "memory"); ++} ++ ++static inline void iccci(void *addr) ++{ ++ asm volatile ("iccci 0, %0" : : "r"(addr) : "memory"); ++} ++ + #endif /* !__ASSEMBLY__ */ + #endif /* __KERNEL__ */ + #endif /* _ASM_POWERPC_CACHE_H */ +diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h +index eef388f2659f..4a1c9f0200e1 100644 +--- a/arch/powerpc/include/asm/cacheflush.h ++++ b/arch/powerpc/include/asm/cacheflush.h +@@ -42,29 +42,25 @@ extern void flush_dcache_page(struct page *page); + #define flush_dcache_mmap_lock(mapping) do { } while (0) + #define flush_dcache_mmap_unlock(mapping) do { } while (0) + +-extern void flush_icache_range(unsigned long, unsigned long); ++void flush_icache_range(unsigned long start, unsigned long stop); + extern void flush_icache_user_range(struct vm_area_struct *vma, + struct page *page, unsigned long addr, + int len); +-extern void __flush_dcache_icache(void *page_va); + extern void flush_dcache_icache_page(struct page *page); +-#if defined(CONFIG_PPC32) && !defined(CONFIG_BOOKE) +-extern void __flush_dcache_icache_phys(unsigned long physaddr); +-#else +-static inline void __flush_dcache_icache_phys(unsigned long physaddr) +-{ +- BUG(); +-} +-#endif +- +-/* +- * Write any modified data cache blocks out to memory and invalidate them. +- * Does not invalidate the corresponding instruction cache blocks. ++void __flush_dcache_icache(void *page); ++ ++/** ++ * flush_dcache_range(): Write any modified data cache blocks out to memory and ++ * invalidate them. Does not invalidate the corresponding instruction cache ++ * blocks. ++ * ++ * @start: the start address ++ * @stop: the stop address (exclusive) + */ + static inline void flush_dcache_range(unsigned long start, unsigned long stop) + { +- unsigned long shift = l1_cache_shift(); +- unsigned long bytes = l1_cache_bytes(); ++ unsigned long shift = l1_dcache_shift(); ++ unsigned long bytes = l1_dcache_bytes(); + void *addr = (void *)(start & ~(bytes - 1)); + unsigned long size = stop - (unsigned long)addr + (bytes - 1); + unsigned long i; +@@ -89,8 +85,8 @@ static inline void flush_dcache_range(unsigned long start, unsigned long stop) + */ + static inline void clean_dcache_range(unsigned long start, unsigned long stop) + { +- unsigned long shift = l1_cache_shift(); +- unsigned long bytes = l1_cache_bytes(); ++ unsigned long shift = l1_dcache_shift(); ++ unsigned long bytes = l1_dcache_bytes(); + void *addr = (void *)(start & ~(bytes - 1)); + unsigned long size = stop - (unsigned long)addr + (bytes - 1); + unsigned long i; +@@ -108,8 +104,8 @@ static inline void clean_dcache_range(unsigned long start, unsigned long stop) + static inline void invalidate_dcache_range(unsigned long start, + unsigned long stop) + { +- unsigned long shift = l1_cache_shift(); +- unsigned long bytes = l1_cache_bytes(); ++ unsigned long shift = l1_dcache_shift(); ++ unsigned long bytes = l1_dcache_bytes(); + void *addr = (void *)(start & ~(bytes - 1)); + unsigned long size = stop - (unsigned long)addr + (bytes - 1); + unsigned long i; +diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c +index e745abc5457a..245be4fafe13 100644 +--- a/arch/powerpc/kernel/cputable.c ++++ b/arch/powerpc/kernel/cputable.c +@@ -2193,11 +2193,13 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset, + * oprofile_cpu_type already has a value, then we are + * possibly overriding a real PVR with a logical one, + * and, in that case, keep the current value for +- * oprofile_cpu_type. ++ * oprofile_cpu_type. Futhermore, let's ensure that the ++ * fix for the PMAO bug is enabled on compatibility mode. + */ + if (old.oprofile_cpu_type != NULL) { + t->oprofile_cpu_type = old.oprofile_cpu_type; + t->oprofile_type = old.oprofile_type; ++ t->cpu_features |= old.cpu_features & CPU_FTR_PMAO_BUG; + } + } + +diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S +index 82df4b09e79f..f4e4a1926a7a 100644 +--- a/arch/powerpc/kernel/misc_32.S ++++ b/arch/powerpc/kernel/misc_32.S +@@ -316,126 +316,6 @@ _GLOBAL(flush_instruction_cache) + EXPORT_SYMBOL(flush_instruction_cache) + #endif /* CONFIG_PPC_8xx */ + +-/* +- * Write any modified data cache blocks out to memory +- * and invalidate the corresponding instruction cache blocks. +- * This is a no-op on the 601. +- * +- * flush_icache_range(unsigned long start, unsigned long stop) +- */ +-_GLOBAL(flush_icache_range) +-#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200) +- PURGE_PREFETCHED_INS +- blr /* for 601 and e200, do nothing */ +-#else +- rlwinm r3,r3,0,0,31 - L1_CACHE_SHIFT +- subf r4,r3,r4 +- addi r4,r4,L1_CACHE_BYTES - 1 +- srwi. r4,r4,L1_CACHE_SHIFT +- beqlr +- mtctr r4 +- mr r6,r3 +-1: dcbst 0,r3 +- addi r3,r3,L1_CACHE_BYTES +- bdnz 1b +- sync /* wait for dcbst's to get to ram */ +-#ifndef CONFIG_44x +- mtctr r4 +-2: icbi 0,r6 +- addi r6,r6,L1_CACHE_BYTES +- bdnz 2b +-#else +- /* Flash invalidate on 44x because we are passed kmapped addresses and +- this doesn't work for userspace pages due to the virtually tagged +- icache. Sigh. */ +- iccci 0, r0 +-#endif +- sync /* additional sync needed on g4 */ +- isync +- blr +-#endif +-_ASM_NOKPROBE_SYMBOL(flush_icache_range) +-EXPORT_SYMBOL(flush_icache_range) +- +-/* +- * Flush a particular page from the data cache to RAM. +- * Note: this is necessary because the instruction cache does *not* +- * snoop from the data cache. +- * This is a no-op on the 601 and e200 which have a unified cache. +- * +- * void __flush_dcache_icache(void *page) +- */ +-_GLOBAL(__flush_dcache_icache) +-#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200) +- PURGE_PREFETCHED_INS +- blr +-#else +- rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ +- li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ +- mtctr r4 +- mr r6,r3 +-0: dcbst 0,r3 /* Write line to ram */ +- addi r3,r3,L1_CACHE_BYTES +- bdnz 0b +- sync +-#ifdef CONFIG_44x +- /* We don't flush the icache on 44x. Those have a virtual icache +- * and we don't have access to the virtual address here (it's +- * not the page vaddr but where it's mapped in user space). The +- * flushing of the icache on these is handled elsewhere, when +- * a change in the address space occurs, before returning to +- * user space +- */ +-BEGIN_MMU_FTR_SECTION +- blr +-END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x) +-#endif /* CONFIG_44x */ +- mtctr r4 +-1: icbi 0,r6 +- addi r6,r6,L1_CACHE_BYTES +- bdnz 1b +- sync +- isync +- blr +-#endif +- +-#ifndef CONFIG_BOOKE +-/* +- * Flush a particular page from the data cache to RAM, identified +- * by its physical address. We turn off the MMU so we can just use +- * the physical address (this may be a highmem page without a kernel +- * mapping). +- * +- * void __flush_dcache_icache_phys(unsigned long physaddr) +- */ +-_GLOBAL(__flush_dcache_icache_phys) +-#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200) +- PURGE_PREFETCHED_INS +- blr /* for 601 and e200, do nothing */ +-#else +- mfmsr r10 +- rlwinm r0,r10,0,28,26 /* clear DR */ +- mtmsr r0 +- isync +- rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ +- li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ +- mtctr r4 +- mr r6,r3 +-0: dcbst 0,r3 /* Write line to ram */ +- addi r3,r3,L1_CACHE_BYTES +- bdnz 0b +- sync +- mtctr r4 +-1: icbi 0,r6 +- addi r6,r6,L1_CACHE_BYTES +- bdnz 1b +- sync +- mtmsr r10 /* restore DR */ +- isync +- blr +-#endif +-#endif /* CONFIG_BOOKE */ +- + /* + * Copy a whole page. We use the dcbz instruction on the destination + * to reduce memory traffic (it eliminates the unnecessary reads of +diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S +index 9bc0aa9aeb65..ff20c253f273 100644 +--- a/arch/powerpc/kernel/misc_64.S ++++ b/arch/powerpc/kernel/misc_64.S +@@ -49,108 +49,6 @@ _GLOBAL(call_do_irq) + mtlr r0 + blr + +- .section ".toc","aw" +-PPC64_CACHES: +- .tc ppc64_caches[TC],ppc64_caches +- .section ".text" +- +-/* +- * Write any modified data cache blocks out to memory +- * and invalidate the corresponding instruction cache blocks. +- * +- * flush_icache_range(unsigned long start, unsigned long stop) +- * +- * flush all bytes from start through stop-1 inclusive +- */ +- +-_GLOBAL_TOC(flush_icache_range) +-BEGIN_FTR_SECTION +- PURGE_PREFETCHED_INS +- blr +-END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) +-/* +- * Flush the data cache to memory +- * +- * Different systems have different cache line sizes +- * and in some cases i-cache and d-cache line sizes differ from +- * each other. +- */ +- ld r10,PPC64_CACHES@toc(r2) +- lwz r7,DCACHEL1BLOCKSIZE(r10)/* Get cache block size */ +- addi r5,r7,-1 +- andc r6,r3,r5 /* round low to line bdy */ +- subf r8,r6,r4 /* compute length */ +- add r8,r8,r5 /* ensure we get enough */ +- lwz r9,DCACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of cache block size */ +- srd. r8,r8,r9 /* compute line count */ +- beqlr /* nothing to do? */ +- mtctr r8 +-1: dcbst 0,r6 +- add r6,r6,r7 +- bdnz 1b +- sync +- +-/* Now invalidate the instruction cache */ +- +- lwz r7,ICACHEL1BLOCKSIZE(r10) /* Get Icache block size */ +- addi r5,r7,-1 +- andc r6,r3,r5 /* round low to line bdy */ +- subf r8,r6,r4 /* compute length */ +- add r8,r8,r5 +- lwz r9,ICACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of Icache block size */ +- srd. r8,r8,r9 /* compute line count */ +- beqlr /* nothing to do? */ +- mtctr r8 +-2: icbi 0,r6 +- add r6,r6,r7 +- bdnz 2b +- isync +- blr +-_ASM_NOKPROBE_SYMBOL(flush_icache_range) +-EXPORT_SYMBOL(flush_icache_range) +- +-/* +- * Flush a particular page from the data cache to RAM. +- * Note: this is necessary because the instruction cache does *not* +- * snoop from the data cache. +- * +- * void __flush_dcache_icache(void *page) +- */ +-_GLOBAL(__flush_dcache_icache) +-/* +- * Flush the data cache to memory +- * +- * Different systems have different cache line sizes +- */ +- +-BEGIN_FTR_SECTION +- PURGE_PREFETCHED_INS +- blr +-END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) +- +-/* Flush the dcache */ +- ld r7,PPC64_CACHES@toc(r2) +- clrrdi r3,r3,PAGE_SHIFT /* Page align */ +- lwz r4,DCACHEL1BLOCKSPERPAGE(r7) /* Get # dcache blocks per page */ +- lwz r5,DCACHEL1BLOCKSIZE(r7) /* Get dcache block size */ +- mr r6,r3 +- mtctr r4 +-0: dcbst 0,r6 +- add r6,r6,r5 +- bdnz 0b +- sync +- +-/* Now invalidate the icache */ +- +- lwz r4,ICACHEL1BLOCKSPERPAGE(r7) /* Get # icache blocks per page */ +- lwz r5,ICACHEL1BLOCKSIZE(r7) /* Get icache block size */ +- mtctr r4 +-1: icbi 0,r3 +- add r3,r3,r5 +- bdnz 1b +- isync +- blr +- + _GLOBAL(__bswapdi2) + EXPORT_SYMBOL(__bswapdi2) + srdi r8,r3,32 +diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c +index 9f5b32163bda..96ca90ce0264 100644 +--- a/arch/powerpc/mm/mem.c ++++ b/arch/powerpc/mm/mem.c +@@ -348,6 +348,122 @@ void free_initmem(void) + free_initmem_default(POISON_FREE_INITMEM); + } + ++/** ++ * flush_coherent_icache() - if a CPU has a coherent icache, flush it ++ * @addr: The base address to use (can be any valid address, the whole cache will be flushed) ++ * Return true if the cache was flushed, false otherwise ++ */ ++static inline bool flush_coherent_icache(unsigned long addr) ++{ ++ /* ++ * For a snooping icache, we still need a dummy icbi to purge all the ++ * prefetched instructions from the ifetch buffers. We also need a sync ++ * before the icbi to order the the actual stores to memory that might ++ * have modified instructions with the icbi. ++ */ ++ if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { ++ mb(); /* sync */ ++ allow_read_from_user((const void __user *)addr, L1_CACHE_BYTES); ++ icbi((void *)addr); ++ prevent_read_from_user((const void __user *)addr, L1_CACHE_BYTES); ++ mb(); /* sync */ ++ isync(); ++ return true; ++ } ++ ++ return false; ++} ++ ++/** ++ * invalidate_icache_range() - Flush the icache by issuing icbi across an address range ++ * @start: the start address ++ * @stop: the stop address (exclusive) ++ */ ++static void invalidate_icache_range(unsigned long start, unsigned long stop) ++{ ++ unsigned long shift = l1_icache_shift(); ++ unsigned long bytes = l1_icache_bytes(); ++ char *addr = (char *)(start & ~(bytes - 1)); ++ unsigned long size = stop - (unsigned long)addr + (bytes - 1); ++ unsigned long i; ++ ++ for (i = 0; i < size >> shift; i++, addr += bytes) ++ icbi(addr); ++ ++ mb(); /* sync */ ++ isync(); ++} ++ ++/** ++ * flush_icache_range: Write any modified data cache blocks out to memory ++ * and invalidate the corresponding blocks in the instruction cache ++ * ++ * Generic code will call this after writing memory, before executing from it. ++ * ++ * @start: the start address ++ * @stop: the stop address (exclusive) ++ */ ++void flush_icache_range(unsigned long start, unsigned long stop) ++{ ++ if (flush_coherent_icache(start)) ++ return; ++ ++ clean_dcache_range(start, stop); ++ ++ if (IS_ENABLED(CONFIG_44x)) { ++ /* ++ * Flash invalidate on 44x because we are passed kmapped ++ * addresses and this doesn't work for userspace pages due to ++ * the virtually tagged icache. ++ */ ++ iccci((void *)start); ++ mb(); /* sync */ ++ isync(); ++ } else ++ invalidate_icache_range(start, stop); ++} ++EXPORT_SYMBOL(flush_icache_range); ++ ++#if !defined(CONFIG_PPC_8xx) && !defined(CONFIG_PPC64) ++/** ++ * flush_dcache_icache_phys() - Flush a page by it's physical address ++ * @physaddr: the physical address of the page ++ */ ++static void flush_dcache_icache_phys(unsigned long physaddr) ++{ ++ unsigned long bytes = l1_dcache_bytes(); ++ unsigned long nb = PAGE_SIZE / bytes; ++ unsigned long addr = physaddr & PAGE_MASK; ++ unsigned long msr, msr0; ++ unsigned long loop1 = addr, loop2 = addr; ++ ++ msr0 = mfmsr(); ++ msr = msr0 & ~MSR_DR; ++ /* ++ * This must remain as ASM to prevent potential memory accesses ++ * while the data MMU is disabled ++ */ ++ asm volatile( ++ " mtctr %2;\n" ++ " mtmsr %3;\n" ++ " isync;\n" ++ "0: dcbst 0, %0;\n" ++ " addi %0, %0, %4;\n" ++ " bdnz 0b;\n" ++ " sync;\n" ++ " mtctr %2;\n" ++ "1: icbi 0, %1;\n" ++ " addi %1, %1, %4;\n" ++ " bdnz 1b;\n" ++ " sync;\n" ++ " mtmsr %5;\n" ++ " isync;\n" ++ : "+&r" (loop1), "+&r" (loop2) ++ : "r" (nb), "r" (msr), "i" (bytes), "r" (msr0) ++ : "ctr", "memory"); ++} ++#endif // !defined(CONFIG_PPC_8xx) && !defined(CONFIG_PPC64) ++ + /* + * This is called when a page has been modified by the kernel. + * It just marks the page as not i-cache clean. We do the i-cache +@@ -380,12 +496,46 @@ void flush_dcache_icache_page(struct page *page) + __flush_dcache_icache(start); + kunmap_atomic(start); + } else { +- __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT); ++ unsigned long addr = page_to_pfn(page) << PAGE_SHIFT; ++ ++ if (flush_coherent_icache(addr)) ++ return; ++ flush_dcache_icache_phys(addr); + } + #endif + } + EXPORT_SYMBOL(flush_dcache_icache_page); + ++/** ++ * __flush_dcache_icache(): Flush a particular page from the data cache to RAM. ++ * Note: this is necessary because the instruction cache does *not* ++ * snoop from the data cache. ++ * ++ * @page: the address of the page to flush ++ */ ++void __flush_dcache_icache(void *p) ++{ ++ unsigned long addr = (unsigned long)p; ++ ++ if (flush_coherent_icache(addr)) ++ return; ++ ++ clean_dcache_range(addr, addr + PAGE_SIZE); ++ ++ /* ++ * We don't flush the icache on 44x. Those have a virtual icache and we ++ * don't have access to the virtual address here (it's not the page ++ * vaddr but where it's mapped in user space). The flushing of the ++ * icache on these is handled elsewhere, when a change in the address ++ * space occurs, before returning to user space. ++ */ ++ ++ if (cpu_has_feature(MMU_FTR_TYPE_44x)) ++ return; ++ ++ invalidate_icache_range(addr, addr + PAGE_SIZE); ++} ++ + void clear_user_page(void *page, unsigned long vaddr, struct page *pg) + { + clear_page(page); +diff --git a/arch/s390/Makefile b/arch/s390/Makefile +index 9ce1baeac2b2..2faaf456956a 100644 +--- a/arch/s390/Makefile ++++ b/arch/s390/Makefile +@@ -146,7 +146,7 @@ all: bzImage + #KBUILD_IMAGE is necessary for packaging targets like rpm-pkg, deb-pkg... + KBUILD_IMAGE := $(boot)/bzImage + +-install: vmlinux ++install: + $(Q)$(MAKE) $(build)=$(boot) $@ + + bzImage: vmlinux +diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile +index e2c47d3a1c89..0ff9261c915e 100644 +--- a/arch/s390/boot/Makefile ++++ b/arch/s390/boot/Makefile +@@ -70,7 +70,7 @@ $(obj)/compressed/vmlinux: $(obj)/startup.a FORCE + $(obj)/startup.a: $(OBJECTS) FORCE + $(call if_changed,ar) + +-install: $(CONFIGURE) $(obj)/bzImage ++install: + sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ + System.map "$(INSTALL_PATH)" + +diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h +index a9e46b83c536..34a655ad7123 100644 +--- a/arch/s390/include/asm/pgtable.h ++++ b/arch/s390/include/asm/pgtable.h +@@ -756,6 +756,12 @@ static inline int pmd_write(pmd_t pmd) + return (pmd_val(pmd) & _SEGMENT_ENTRY_WRITE) != 0; + } + ++#define pud_write pud_write ++static inline int pud_write(pud_t pud) ++{ ++ return (pud_val(pud) & _REGION3_ENTRY_WRITE) != 0; ++} ++ + static inline int pmd_dirty(pmd_t pmd) + { + int dirty = 1; +diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h +index e3f238e8c611..4f35b1055f30 100644 +--- a/arch/s390/include/asm/qdio.h ++++ b/arch/s390/include/asm/qdio.h +@@ -227,7 +227,7 @@ struct qdio_buffer { + * @sbal: absolute SBAL address + */ + struct sl_element { +- unsigned long sbal; ++ u64 sbal; + } __attribute__ ((packed)); + + /** +diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c +index 5b24fcc9c361..6105b1b6e49b 100644 +--- a/arch/s390/pci/pci.c ++++ b/arch/s390/pci/pci.c +@@ -423,7 +423,7 @@ static void zpci_map_resources(struct pci_dev *pdev) + + if (zpci_use_mio(zdev)) + pdev->resource[i].start = +- (resource_size_t __force) zdev->bars[i].mio_wb; ++ (resource_size_t __force) zdev->bars[i].mio_wt; + else + pdev->resource[i].start = (resource_size_t __force) + pci_iomap_range_fh(pdev, i, 0, 0); +@@ -530,7 +530,7 @@ static int zpci_setup_bus_resources(struct zpci_dev *zdev, + flags |= IORESOURCE_MEM_64; + + if (zpci_use_mio(zdev)) +- addr = (unsigned long) zdev->bars[i].mio_wb; ++ addr = (unsigned long) zdev->bars[i].mio_wt; + else + addr = ZPCI_ADDR(entry); + size = 1UL << zdev->bars[i].size; +diff --git a/arch/x86/boot/compressed/kaslr_64.c b/arch/x86/boot/compressed/kaslr_64.c +index 748456c365f4..9557c5a15b91 100644 +--- a/arch/x86/boot/compressed/kaslr_64.c ++++ b/arch/x86/boot/compressed/kaslr_64.c +@@ -29,9 +29,6 @@ + #define __PAGE_OFFSET __PAGE_OFFSET_BASE + #include "../../mm/ident_map.c" + +-/* Used by pgtable.h asm code to force instruction serialization. */ +-unsigned long __force_order; +- + /* Used to track our page table allocation area. */ + struct alloc_pgt_data { + unsigned char *pgt_buf; +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index fffe21945374..704caec136cf 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -464,7 +464,7 @@ static __always_inline void setup_pku(struct cpuinfo_x86 *c) + * cpuid bit to be set. We need to ensure that we + * update that bit in this CPU's "cpu_info". + */ +- get_cpu_cap(c); ++ set_cpu_cap(c, X86_FEATURE_OSPKE); + } + + #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c +index 52a1e5192fa8..fe0e647411da 100644 +--- a/arch/x86/platform/efi/efi_64.c ++++ b/arch/x86/platform/efi/efi_64.c +@@ -316,7 +316,7 @@ void efi_sync_low_kernel_mappings(void) + static inline phys_addr_t + virt_to_phys_or_null_size(void *va, unsigned long size) + { +- bool bad_size; ++ phys_addr_t pa; + + if (!va) + return 0; +@@ -324,16 +324,13 @@ virt_to_phys_or_null_size(void *va, unsigned long size) + if (virt_addr_valid(va)) + return virt_to_phys(va); + +- /* +- * A fully aligned variable on the stack is guaranteed not to +- * cross a page bounary. Try to catch strings on the stack by +- * checking that 'size' is a power of two. +- */ +- bad_size = size > PAGE_SIZE || !is_power_of_2(size); ++ pa = slow_virt_to_phys(va); + +- WARN_ON(!IS_ALIGNED((unsigned long)va, size) || bad_size); ++ /* check if the object crosses a page boundary */ ++ if (WARN_ON((pa ^ (pa + size - 1)) & PAGE_MASK)) ++ return 0; + +- return slow_virt_to_phys(va); ++ return pa; + } + + #define virt_to_phys_or_null(addr) \ +@@ -791,6 +788,8 @@ static efi_status_t + efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor, + u32 *attr, unsigned long *data_size, void *data) + { ++ u8 buf[24] __aligned(8); ++ efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); + efi_status_t status; + u32 phys_name, phys_vendor, phys_attr; + u32 phys_data_size, phys_data; +@@ -798,14 +797,19 @@ efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor, + + spin_lock_irqsave(&efi_runtime_lock, flags); + ++ *vnd = *vendor; ++ + phys_data_size = virt_to_phys_or_null(data_size); +- phys_vendor = virt_to_phys_or_null(vendor); ++ phys_vendor = virt_to_phys_or_null(vnd); + phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); + phys_attr = virt_to_phys_or_null(attr); + phys_data = virt_to_phys_or_null_size(data, *data_size); + +- status = efi_thunk(get_variable, phys_name, phys_vendor, +- phys_attr, phys_data_size, phys_data); ++ if (!phys_name || (data && !phys_data)) ++ status = EFI_INVALID_PARAMETER; ++ else ++ status = efi_thunk(get_variable, phys_name, phys_vendor, ++ phys_attr, phys_data_size, phys_data); + + spin_unlock_irqrestore(&efi_runtime_lock, flags); + +@@ -816,19 +820,25 @@ static efi_status_t + efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor, + u32 attr, unsigned long data_size, void *data) + { ++ u8 buf[24] __aligned(8); ++ efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); + u32 phys_name, phys_vendor, phys_data; + efi_status_t status; + unsigned long flags; + + spin_lock_irqsave(&efi_runtime_lock, flags); + ++ *vnd = *vendor; ++ + phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); +- phys_vendor = virt_to_phys_or_null(vendor); ++ phys_vendor = virt_to_phys_or_null(vnd); + phys_data = virt_to_phys_or_null_size(data, data_size); + +- /* If data_size is > sizeof(u32) we've got problems */ +- status = efi_thunk(set_variable, phys_name, phys_vendor, +- attr, data_size, phys_data); ++ if (!phys_name || !phys_data) ++ status = EFI_INVALID_PARAMETER; ++ else ++ status = efi_thunk(set_variable, phys_name, phys_vendor, ++ attr, data_size, phys_data); + + spin_unlock_irqrestore(&efi_runtime_lock, flags); + +@@ -840,6 +850,8 @@ efi_thunk_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, + u32 attr, unsigned long data_size, + void *data) + { ++ u8 buf[24] __aligned(8); ++ efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); + u32 phys_name, phys_vendor, phys_data; + efi_status_t status; + unsigned long flags; +@@ -847,13 +859,17 @@ efi_thunk_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, + if (!spin_trylock_irqsave(&efi_runtime_lock, flags)) + return EFI_NOT_READY; + ++ *vnd = *vendor; ++ + phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); +- phys_vendor = virt_to_phys_or_null(vendor); ++ phys_vendor = virt_to_phys_or_null(vnd); + phys_data = virt_to_phys_or_null_size(data, data_size); + +- /* If data_size is > sizeof(u32) we've got problems */ +- status = efi_thunk(set_variable, phys_name, phys_vendor, +- attr, data_size, phys_data); ++ if (!phys_name || !phys_data) ++ status = EFI_INVALID_PARAMETER; ++ else ++ status = efi_thunk(set_variable, phys_name, phys_vendor, ++ attr, data_size, phys_data); + + spin_unlock_irqrestore(&efi_runtime_lock, flags); + +@@ -865,21 +881,29 @@ efi_thunk_get_next_variable(unsigned long *name_size, + efi_char16_t *name, + efi_guid_t *vendor) + { ++ u8 buf[24] __aligned(8); ++ efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); + efi_status_t status; + u32 phys_name_size, phys_name, phys_vendor; + unsigned long flags; + + spin_lock_irqsave(&efi_runtime_lock, flags); + ++ *vnd = *vendor; ++ + phys_name_size = virt_to_phys_or_null(name_size); +- phys_vendor = virt_to_phys_or_null(vendor); ++ phys_vendor = virt_to_phys_or_null(vnd); + phys_name = virt_to_phys_or_null_size(name, *name_size); + +- status = efi_thunk(get_next_variable, phys_name_size, +- phys_name, phys_vendor); ++ if (!phys_name) ++ status = EFI_INVALID_PARAMETER; ++ else ++ status = efi_thunk(get_next_variable, phys_name_size, ++ phys_name, phys_vendor); + + spin_unlock_irqrestore(&efi_runtime_lock, flags); + ++ *vendor = *vnd; + return status; + } + +diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c +index 6ea215cdeada..6d4d8a5700b7 100644 +--- a/arch/x86/xen/enlighten_pv.c ++++ b/arch/x86/xen/enlighten_pv.c +@@ -905,14 +905,15 @@ static u64 xen_read_msr_safe(unsigned int msr, int *err) + static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high) + { + int ret; ++#ifdef CONFIG_X86_64 ++ unsigned int which; ++ u64 base; ++#endif + + ret = 0; + + switch (msr) { + #ifdef CONFIG_X86_64 +- unsigned which; +- u64 base; +- + case MSR_FS_BASE: which = SEGBASE_FS; goto set; + case MSR_KERNEL_GS_BASE: which = SEGBASE_GS_USER; goto set; + case MSR_GS_BASE: which = SEGBASE_GS_KERNEL; goto set; +diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c +index 86a607cf19a1..d0e36d652264 100644 +--- a/block/bfq-cgroup.c ++++ b/block/bfq-cgroup.c +@@ -332,7 +332,7 @@ static void bfqg_put(struct bfq_group *bfqg) + kfree(bfqg); + } + +-static void bfqg_and_blkg_get(struct bfq_group *bfqg) ++void bfqg_and_blkg_get(struct bfq_group *bfqg) + { + /* see comments in bfq_bic_update_cgroup for why refcounting bfqg */ + bfqg_get(bfqg); +@@ -634,6 +634,12 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, + bfq_bfqq_expire(bfqd, bfqd->in_service_queue, + false, BFQQE_PREEMPTED); + ++ /* ++ * get extra reference to prevent bfqq from being freed in ++ * next possible deactivate ++ */ ++ bfqq->ref++; ++ + if (bfq_bfqq_busy(bfqq)) + bfq_deactivate_bfqq(bfqd, bfqq, false, false); + else if (entity->on_st) +@@ -653,6 +659,8 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, + + if (!bfqd->in_service_queue && !bfqd->rq_in_driver) + bfq_schedule_dispatch(bfqd); ++ /* release extra ref taken above */ ++ bfq_put_queue(bfqq); + } + + /** +@@ -1380,6 +1388,10 @@ struct bfq_group *bfqq_group(struct bfq_queue *bfqq) + return bfqq->bfqd->root_group; + } + ++void bfqg_and_blkg_get(struct bfq_group *bfqg) {} ++ ++void bfqg_and_blkg_put(struct bfq_group *bfqg) {} ++ + struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node) + { + struct bfq_group *bfqg; +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index 5498d05b873d..48189ff88916 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -614,6 +614,10 @@ bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq) + bfqq->pos_root = NULL; + } + ++ /* oom_bfqq does not participate in queue merging */ ++ if (bfqq == &bfqd->oom_bfqq) ++ return; ++ + /* + * bfqq cannot be merged any longer (see comments in + * bfq_setup_cooperator): no point in adding bfqq into the +@@ -4822,9 +4826,7 @@ void bfq_put_queue(struct bfq_queue *bfqq) + { + struct bfq_queue *item; + struct hlist_node *n; +-#ifdef CONFIG_BFQ_GROUP_IOSCHED + struct bfq_group *bfqg = bfqq_group(bfqq); +-#endif + + if (bfqq->bfqd) + bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p %d", +@@ -4897,9 +4899,7 @@ void bfq_put_queue(struct bfq_queue *bfqq) + bfqq->bfqd->last_completed_rq_bfqq = NULL; + + kmem_cache_free(bfq_pool, bfqq); +-#ifdef CONFIG_BFQ_GROUP_IOSCHED + bfqg_and_blkg_put(bfqg); +-#endif + } + + static void bfq_put_cooperator(struct bfq_queue *bfqq) +@@ -6383,10 +6383,10 @@ static void bfq_exit_queue(struct elevator_queue *e) + + hrtimer_cancel(&bfqd->idle_slice_timer); + +-#ifdef CONFIG_BFQ_GROUP_IOSCHED + /* release oom-queue reference to root group */ + bfqg_and_blkg_put(bfqd->root_group); + ++#ifdef CONFIG_BFQ_GROUP_IOSCHED + blkcg_deactivate_policy(bfqd->queue, &blkcg_policy_bfq); + #else + spin_lock_irq(&bfqd->lock); +diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h +index 5d1a519640f6..1553a4e8f7ad 100644 +--- a/block/bfq-iosched.h ++++ b/block/bfq-iosched.h +@@ -916,6 +916,7 @@ struct bfq_group { + + #else + struct bfq_group { ++ struct bfq_entity entity; + struct bfq_sched_data sched_data; + + struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; +@@ -978,6 +979,7 @@ struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, + struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg); + struct bfq_group *bfqq_group(struct bfq_queue *bfqq); + struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node); ++void bfqg_and_blkg_get(struct bfq_group *bfqg); + void bfqg_and_blkg_put(struct bfq_group *bfqg); + + #ifdef CONFIG_BFQ_GROUP_IOSCHED +diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c +index 05f0bf4a1144..44079147e396 100644 +--- a/block/bfq-wf2q.c ++++ b/block/bfq-wf2q.c +@@ -536,7 +536,9 @@ static void bfq_get_entity(struct bfq_entity *entity) + bfqq->ref++; + bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d", + bfqq, bfqq->ref); +- } ++ } else ++ bfqg_and_blkg_get(container_of(entity, struct bfq_group, ++ entity)); + } + + /** +@@ -650,8 +652,14 @@ static void bfq_forget_entity(struct bfq_service_tree *st, + + entity->on_st = false; + st->wsum -= entity->weight; +- if (bfqq && !is_in_service) ++ if (is_in_service) ++ return; ++ ++ if (bfqq) + bfq_put_queue(bfqq); ++ else ++ bfqg_and_blkg_put(container_of(entity, struct bfq_group, ++ entity)); + } + + /** +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index 254f87b627fe..34a6de65aa7e 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -5230,6 +5230,7 @@ static int binder_open(struct inode *nodp, struct file *filp) + binder_dev = container_of(filp->private_data, + struct binder_device, miscdev); + } ++ refcount_inc(&binder_dev->ref); + proc->context = &binder_dev->context; + binder_alloc_init(&proc->alloc); + +@@ -5407,6 +5408,7 @@ static int binder_node_release(struct binder_node *node, int refs) + static void binder_deferred_release(struct binder_proc *proc) + { + struct binder_context *context = proc->context; ++ struct binder_device *device; + struct rb_node *n; + int threads, nodes, incoming_refs, outgoing_refs, active_transactions; + +@@ -5423,6 +5425,12 @@ static void binder_deferred_release(struct binder_proc *proc) + context->binder_context_mgr_node = NULL; + } + mutex_unlock(&context->context_mgr_node_lock); ++ device = container_of(proc->context, struct binder_device, context); ++ if (refcount_dec_and_test(&device->ref)) { ++ kfree(context->name); ++ kfree(device); ++ } ++ proc->context = NULL; + binder_inner_proc_lock(proc); + /* + * Make sure proc stays alive after we +@@ -6079,6 +6087,7 @@ static int __init init_binder_device(const char *name) + binder_device->miscdev.minor = MISC_DYNAMIC_MINOR; + binder_device->miscdev.name = name; + ++ refcount_set(&binder_device->ref, 1); + binder_device->context.binder_context_mgr_uid = INVALID_UID; + binder_device->context.name = name; + mutex_init(&binder_device->context.context_mgr_node_lock); +diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h +index ae991097d14d..283d3cb9c16e 100644 +--- a/drivers/android/binder_internal.h ++++ b/drivers/android/binder_internal.h +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -33,6 +34,7 @@ struct binder_device { + struct miscdevice miscdev; + struct binder_context context; + struct inode *binderfs_inode; ++ refcount_t ref; + }; + + /** +diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c +index e2580e5316a2..110e41f920c2 100644 +--- a/drivers/android/binderfs.c ++++ b/drivers/android/binderfs.c +@@ -154,6 +154,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode, + if (!name) + goto err; + ++ refcount_set(&device->ref, 1); + device->binderfs_inode = inode; + device->context.binder_context_mgr_uid = INVALID_UID; + device->context.name = name; +@@ -257,8 +258,10 @@ static void binderfs_evict_inode(struct inode *inode) + ida_free(&binderfs_minors, device->miscdev.minor); + mutex_unlock(&binderfs_minors_mutex); + +- kfree(device->context.name); +- kfree(device); ++ if (refcount_dec_and_test(&device->ref)) { ++ kfree(device->context.name); ++ kfree(device); ++ } + } + + /** +diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c +index a0cecb12b6f9..f0bc0841cbc4 100644 +--- a/drivers/bus/ti-sysc.c ++++ b/drivers/bus/ti-sysc.c +@@ -1406,7 +1406,7 @@ static void sysc_init_revision_quirks(struct sysc *ddata) + } + + /* 1-wire needs module's internal clocks enabled for reset */ +-static void sysc_clk_enable_quirk_hdq1w(struct sysc *ddata) ++static void sysc_pre_reset_quirk_hdq1w(struct sysc *ddata) + { + int offset = 0x0c; /* HDQ_CTRL_STATUS */ + u16 val; +@@ -1494,7 +1494,7 @@ static void sysc_init_module_quirks(struct sysc *ddata) + return; + + if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_HDQ1W) { +- ddata->clk_enable_quirk = sysc_clk_enable_quirk_hdq1w; ++ ddata->clk_disable_quirk = sysc_pre_reset_quirk_hdq1w; + + return; + } +diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c +index 433d91d710e4..0fb0358f0073 100644 +--- a/drivers/dma-buf/dma-buf.c ++++ b/drivers/dma-buf/dma-buf.c +@@ -108,6 +108,7 @@ static int dma_buf_release(struct inode *inode, struct file *file) + dma_resv_fini(dmabuf->resv); + + module_put(dmabuf->owner); ++ kfree(dmabuf->name); + kfree(dmabuf); + return 0; + } +diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c +index e51d836afcc7..1092d4ce723e 100644 +--- a/drivers/dma/coh901318.c ++++ b/drivers/dma/coh901318.c +@@ -1947,8 +1947,6 @@ static void dma_tc_handle(struct coh901318_chan *cohc) + return; + } + +- spin_lock(&cohc->lock); +- + /* + * When we reach this point, at least one queue item + * should have been moved over from cohc->queue to +@@ -1969,8 +1967,6 @@ static void dma_tc_handle(struct coh901318_chan *cohc) + if (coh901318_queue_start(cohc) == NULL) + cohc->busy = 0; + +- spin_unlock(&cohc->lock); +- + /* + * This tasklet will remove items from cohc->active + * and thus terminates them. +diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c +index c27e206a764c..67736c801f3c 100644 +--- a/drivers/dma/imx-sdma.c ++++ b/drivers/dma/imx-sdma.c +@@ -1328,13 +1328,14 @@ static void sdma_free_chan_resources(struct dma_chan *chan) + + sdma_channel_synchronize(chan); + +- if (sdmac->event_id0) ++ if (sdmac->event_id0 >= 0) + sdma_event_disable(sdmac, sdmac->event_id0); + if (sdmac->event_id1) + sdma_event_disable(sdmac, sdmac->event_id1); + + sdmac->event_id0 = 0; + sdmac->event_id1 = 0; ++ sdmac->context_loaded = false; + + sdma_set_channel_priority(sdmac, 0); + +@@ -1628,7 +1629,7 @@ static int sdma_config(struct dma_chan *chan, + memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg)); + + /* Set ENBLn earlier to make sure dma request triggered after that */ +- if (sdmac->event_id0) { ++ if (sdmac->event_id0 >= 0) { + if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events) + return -EINVAL; + sdma_event_enable(sdmac, sdmac->event_id0); +diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c +index 3a45079d11ec..4a750e29bfb5 100644 +--- a/drivers/dma/tegra20-apb-dma.c ++++ b/drivers/dma/tegra20-apb-dma.c +@@ -281,7 +281,7 @@ static struct tegra_dma_desc *tegra_dma_desc_get( + + /* Do not allocate if desc are waiting for ack */ + list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) { +- if (async_tx_test_ack(&dma_desc->txd)) { ++ if (async_tx_test_ack(&dma_desc->txd) && !dma_desc->cb_count) { + list_del(&dma_desc->node); + spin_unlock_irqrestore(&tdc->lock, flags); + dma_desc->txd.flags = 0; +@@ -756,10 +756,6 @@ static int tegra_dma_terminate_all(struct dma_chan *dc) + bool was_busy; + + spin_lock_irqsave(&tdc->lock, flags); +- if (list_empty(&tdc->pending_sg_req)) { +- spin_unlock_irqrestore(&tdc->lock, flags); +- return 0; +- } + + if (!tdc->busy) + goto skip_dma_stop; +diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c +index 2d263382d797..880ffd833718 100644 +--- a/drivers/edac/synopsys_edac.c ++++ b/drivers/edac/synopsys_edac.c +@@ -479,20 +479,14 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p) + pinf = &p->ceinfo; + if (!priv->p_data->quirks) { + snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, +- "DDR ECC error type:%s Row %d Bank %d Col %d ", +- "CE", pinf->row, pinf->bank, pinf->col); +- snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, +- "Bit Position: %d Data: 0x%08x\n", ++ "DDR ECC error type:%s Row %d Bank %d Col %d Bit Position: %d Data: 0x%08x", ++ "CE", pinf->row, pinf->bank, pinf->col, + pinf->bitpos, pinf->data); + } else { + snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, +- "DDR ECC error type:%s Row %d Bank %d Col %d ", +- "CE", pinf->row, pinf->bank, pinf->col); +- snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, +- "BankGroup Number %d Block Number %d ", +- pinf->bankgrpnr, pinf->blknr); +- snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, +- "Bit Position: %d Data: 0x%08x\n", ++ "DDR ECC error type:%s Row %d Bank %d Col %d BankGroup Number %d Block Number %d Bit Position: %d Data: 0x%08x", ++ "CE", pinf->row, pinf->bank, pinf->col, ++ pinf->bankgrpnr, pinf->blknr, + pinf->bitpos, pinf->data); + } + +@@ -509,10 +503,8 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p) + "UE", pinf->row, pinf->bank, pinf->col); + } else { + snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, +- "DDR ECC error type :%s Row %d Bank %d Col %d ", +- "UE", pinf->row, pinf->bank, pinf->col); +- snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, +- "BankGroup Number %d Block Number %d", ++ "DDR ECC error type :%s Row %d Bank %d Col %d BankGroup Number %d Block Number %d", ++ "UE", pinf->row, pinf->bank, pinf->col, + pinf->bankgrpnr, pinf->blknr); + } + +diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c +index 34d41f67b54d..ad8a4bc074fb 100644 +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -544,7 +544,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz, + + seed = early_memremap(efi.rng_seed, sizeof(*seed)); + if (seed != NULL) { +- size = seed->size; ++ size = READ_ONCE(seed->size); + early_memunmap(seed, sizeof(*seed)); + } else { + pr_err("Could not map UEFI random seed!\n"); +@@ -554,7 +554,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz, + sizeof(*seed) + size); + if (seed != NULL) { + pr_notice("seeding entropy pool\n"); +- add_bootloader_randomness(seed->bits, seed->size); ++ add_bootloader_randomness(seed->bits, size); + early_memunmap(seed, sizeof(*seed) + size); + } else { + pr_err("Could not map UEFI random seed!\n"); +diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c +index 04a24a863d6e..35a5f8f8eea5 100644 +--- a/drivers/firmware/imx/imx-scu.c ++++ b/drivers/firmware/imx/imx-scu.c +@@ -29,6 +29,7 @@ struct imx_sc_chan { + struct mbox_client cl; + struct mbox_chan *ch; + int idx; ++ struct completion tx_done; + }; + + struct imx_sc_ipc { +@@ -100,6 +101,14 @@ int imx_scu_get_handle(struct imx_sc_ipc **ipc) + } + EXPORT_SYMBOL(imx_scu_get_handle); + ++/* Callback called when the word of a message is ack-ed, eg read by SCU */ ++static void imx_scu_tx_done(struct mbox_client *cl, void *mssg, int r) ++{ ++ struct imx_sc_chan *sc_chan = container_of(cl, struct imx_sc_chan, cl); ++ ++ complete(&sc_chan->tx_done); ++} ++ + static void imx_scu_rx_callback(struct mbox_client *c, void *msg) + { + struct imx_sc_chan *sc_chan = container_of(c, struct imx_sc_chan, cl); +@@ -143,6 +152,19 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg) + + for (i = 0; i < hdr->size; i++) { + sc_chan = &sc_ipc->chans[i % 4]; ++ ++ /* ++ * SCU requires that all messages words are written ++ * sequentially but linux MU driver implements multiple ++ * independent channels for each register so ordering between ++ * different channels must be ensured by SCU API interface. ++ * ++ * Wait for tx_done before every send to ensure that no ++ * queueing happens at the mailbox channel level. ++ */ ++ wait_for_completion(&sc_chan->tx_done); ++ reinit_completion(&sc_chan->tx_done); ++ + ret = mbox_send_message(sc_chan->ch, &data[i]); + if (ret < 0) + return ret; +@@ -225,6 +247,11 @@ static int imx_scu_probe(struct platform_device *pdev) + cl->knows_txdone = true; + cl->rx_callback = imx_scu_rx_callback; + ++ /* Initial tx_done completion as "done" */ ++ cl->tx_done = imx_scu_tx_done; ++ init_completion(&sc_chan->tx_done); ++ complete(&sc_chan->tx_done); ++ + sc_chan->sc_ipc = sc_ipc; + sc_chan->idx = i % 4; + sc_chan->ch = mbox_request_channel_byname(cl, chan_name); +diff --git a/drivers/firmware/imx/misc.c b/drivers/firmware/imx/misc.c +index 4b56a587dacd..d073cb3ce699 100644 +--- a/drivers/firmware/imx/misc.c ++++ b/drivers/firmware/imx/misc.c +@@ -16,7 +16,7 @@ struct imx_sc_msg_req_misc_set_ctrl { + u32 ctrl; + u32 val; + u16 resource; +-} __packed; ++} __packed __aligned(4); + + struct imx_sc_msg_req_cpu_start { + struct imx_sc_rpc_msg hdr; +@@ -24,18 +24,18 @@ struct imx_sc_msg_req_cpu_start { + u32 address_lo; + u16 resource; + u8 enable; +-} __packed; ++} __packed __aligned(4); + + struct imx_sc_msg_req_misc_get_ctrl { + struct imx_sc_rpc_msg hdr; + u32 ctrl; + u16 resource; +-} __packed; ++} __packed __aligned(4); + + struct imx_sc_msg_resp_misc_get_ctrl { + struct imx_sc_rpc_msg hdr; + u32 val; +-} __packed; ++} __packed __aligned(4); + + /* + * This function sets a miscellaneous control value. +diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c +index b556612207e5..af3ae0087de4 100644 +--- a/drivers/firmware/imx/scu-pd.c ++++ b/drivers/firmware/imx/scu-pd.c +@@ -61,7 +61,7 @@ struct imx_sc_msg_req_set_resource_power_mode { + struct imx_sc_rpc_msg hdr; + u16 resource; + u8 mode; +-} __packed; ++} __packed __aligned(4); + + #define IMX_SCU_PD_NAME_SIZE 20 + struct imx_sc_pm_domain { +diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c +index 12e748b202d6..18cb88b9105e 100644 +--- a/drivers/gpu/drm/drm_client_modeset.c ++++ b/drivers/gpu/drm/drm_client_modeset.c +@@ -952,7 +952,8 @@ bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation) + * depending on the hardware this may require the framebuffer + * to be in a specific tiling format. + */ +- if ((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180 || ++ if (((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0 && ++ (*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180) || + !plane->rotation_property) + return false; + +diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c +index 88232698d7a0..3fd35e6b9d53 100644 +--- a/drivers/gpu/drm/drm_modes.c ++++ b/drivers/gpu/drm/drm_modes.c +@@ -1672,6 +1672,13 @@ static int drm_mode_parse_cmdline_options(char *str, size_t len, + } + } + ++ if (!(rotation & DRM_MODE_ROTATE_MASK)) ++ rotation |= DRM_MODE_ROTATE_0; ++ ++ /* Make sure there is exactly one rotation defined */ ++ if (!is_power_of_2(rotation & DRM_MODE_ROTATE_MASK)) ++ return -EINVAL; ++ + mode->rotation_reflection = rotation; + + return 0; +diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h b/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h +index 0da860200410..e2ac09894a6d 100644 +--- a/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h ++++ b/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h +@@ -83,7 +83,6 @@ + #define VSIZE_OFST 20 + #define LDI_INT_EN 0x741C + #define FRAME_END_INT_EN_OFST 1 +-#define UNDERFLOW_INT_EN_OFST 2 + #define LDI_CTRL 0x7420 + #define BPP_OFST 3 + #define DATA_GATE_EN BIT(2) +diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +index 73cd28a6ea07..86000127d4ee 100644 +--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c ++++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +@@ -46,7 +46,6 @@ struct ade_hw_ctx { + struct clk *media_noc_clk; + struct clk *ade_pix_clk; + struct reset_control *reset; +- struct work_struct display_reset_wq; + bool power_on; + int irq; + +@@ -136,7 +135,6 @@ static void ade_init(struct ade_hw_ctx *ctx) + */ + ade_update_bits(base + ADE_CTRL, FRM_END_START_OFST, + FRM_END_START_MASK, REG_EFFECTIVE_IN_ADEEN_FRMEND); +- ade_update_bits(base + LDI_INT_EN, UNDERFLOW_INT_EN_OFST, MASK(1), 1); + } + + static bool ade_crtc_mode_fixup(struct drm_crtc *crtc, +@@ -304,17 +302,6 @@ static void ade_crtc_disable_vblank(struct drm_crtc *crtc) + MASK(1), 0); + } + +-static void drm_underflow_wq(struct work_struct *work) +-{ +- struct ade_hw_ctx *ctx = container_of(work, struct ade_hw_ctx, +- display_reset_wq); +- struct drm_device *drm_dev = ctx->crtc->dev; +- struct drm_atomic_state *state; +- +- state = drm_atomic_helper_suspend(drm_dev); +- drm_atomic_helper_resume(drm_dev, state); +-} +- + static irqreturn_t ade_irq_handler(int irq, void *data) + { + struct ade_hw_ctx *ctx = data; +@@ -331,12 +318,6 @@ static irqreturn_t ade_irq_handler(int irq, void *data) + MASK(1), 1); + drm_crtc_handle_vblank(crtc); + } +- if (status & BIT(UNDERFLOW_INT_EN_OFST)) { +- ade_update_bits(base + LDI_INT_CLR, UNDERFLOW_INT_EN_OFST, +- MASK(1), 1); +- DRM_ERROR("LDI underflow!"); +- schedule_work(&ctx->display_reset_wq); +- } + + return IRQ_HANDLED; + } +@@ -919,7 +900,6 @@ static void *ade_hw_ctx_alloc(struct platform_device *pdev, + if (ret) + return ERR_PTR(-EIO); + +- INIT_WORK(&ctx->display_reset_wq, drm_underflow_wq); + ctx->crtc = crtc; + + return ctx; +diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c +index c002f234ff31..2422af6a99a0 100644 +--- a/drivers/gpu/drm/i915/display/intel_display_power.c ++++ b/drivers/gpu/drm/i915/display/intel_display_power.c +@@ -4205,13 +4205,19 @@ static void icl_dbuf_disable(struct drm_i915_private *dev_priv) + + static void icl_mbus_init(struct drm_i915_private *dev_priv) + { +- u32 val; ++ u32 mask, val; + +- val = MBUS_ABOX_BT_CREDIT_POOL1(16) | +- MBUS_ABOX_BT_CREDIT_POOL2(16) | +- MBUS_ABOX_B_CREDIT(1) | +- MBUS_ABOX_BW_CREDIT(1); ++ mask = MBUS_ABOX_BT_CREDIT_POOL1_MASK | ++ MBUS_ABOX_BT_CREDIT_POOL2_MASK | ++ MBUS_ABOX_B_CREDIT_MASK | ++ MBUS_ABOX_BW_CREDIT_MASK; + ++ val = I915_READ(MBUS_ABOX_CTL); ++ val &= ~mask; ++ val |= MBUS_ABOX_BT_CREDIT_POOL1(16) | ++ MBUS_ABOX_BT_CREDIT_POOL2(16) | ++ MBUS_ABOX_B_CREDIT(1) | ++ MBUS_ABOX_BW_CREDIT(1); + I915_WRITE(MBUS_ABOX_CTL, val); + } + +diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +index 1d27babff0ce..dc9d3a5ec4a6 100644 +--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c ++++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +@@ -375,7 +375,7 @@ static bool assert_mmap_offset(struct drm_i915_private *i915, + + obj = i915_gem_object_create_internal(i915, size); + if (IS_ERR(obj)) +- return PTR_ERR(obj); ++ return false; + + err = create_mmap_offset(obj); + i915_gem_object_put(obj); +diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +index eb0b4b7dc7cc..03c6d6157e4d 100644 +--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c ++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +@@ -1112,8 +1112,8 @@ static void mdp5_crtc_wait_for_pp_done(struct drm_crtc *crtc) + ret = wait_for_completion_timeout(&mdp5_crtc->pp_completion, + msecs_to_jiffies(50)); + if (ret == 0) +- dev_warn(dev->dev, "pp done time out, lm=%d\n", +- mdp5_cstate->pipeline.mixer->lm); ++ dev_warn_ratelimited(dev->dev, "pp done time out, lm=%d\n", ++ mdp5_cstate->pipeline.mixer->lm); + } + + static void mdp5_crtc_wait_for_flush_done(struct drm_crtc *crtc) +diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c +index 271aa7bbca92..73127948f54d 100644 +--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c ++++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c +@@ -336,7 +336,7 @@ static int dsi_mgr_connector_get_modes(struct drm_connector *connector) + return num; + } + +-static int dsi_mgr_connector_mode_valid(struct drm_connector *connector, ++static enum drm_mode_status dsi_mgr_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) + { + int id = dsi_mgr_connector_get_id(connector); +@@ -479,6 +479,7 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) + struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); + struct mipi_dsi_host *host = msm_dsi->host; + struct drm_panel *panel = msm_dsi->panel; ++ struct msm_dsi_pll *src_pll; + bool is_dual_dsi = IS_DUAL_DSI(); + int ret; + +@@ -519,6 +520,10 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) + id, ret); + } + ++ /* Save PLL status if it is a clock source */ ++ src_pll = msm_dsi_phy_get_pll(msm_dsi->phy); ++ msm_dsi_pll_save_state(src_pll); ++ + ret = msm_dsi_host_power_off(host); + if (ret) + pr_err("%s: host %d power off failed,%d\n", __func__, id, ret); +diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +index 3522863a4984..21519229fe73 100644 +--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c ++++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +@@ -724,10 +724,6 @@ void msm_dsi_phy_disable(struct msm_dsi_phy *phy) + if (!phy || !phy->cfg->ops.disable) + return; + +- /* Save PLL status if it is a clock source */ +- if (phy->usecase != MSM_DSI_PHY_SLAVE) +- msm_dsi_pll_save_state(phy->pll); +- + phy->cfg->ops.disable(phy); + + dsi_phy_regulator_disable(phy); +diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c +index 8f6100db90ed..aa9385d5bfff 100644 +--- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c ++++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c +@@ -411,6 +411,12 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) + if (pll_10nm->slave) + dsi_pll_enable_pll_bias(pll_10nm->slave); + ++ rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0); ++ if (rc) { ++ pr_err("vco_set_rate failed, rc=%d\n", rc); ++ return rc; ++ } ++ + /* Start PLL */ + pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, + 0x01); +diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c +index 3107b0738e40..5d75f8cf6477 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c ++++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c +@@ -601,33 +601,27 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) + source_id = (fault_status >> 16); + + /* Page fault only */ +- if ((status & mask) == BIT(i)) { +- WARN_ON(exception_type < 0xC1 || exception_type > 0xC4); +- ++ ret = -1; ++ if ((status & mask) == BIT(i) && (exception_type & 0xF8) == 0xC0) + ret = panfrost_mmu_map_fault_addr(pfdev, i, addr); +- if (!ret) { +- mmu_write(pfdev, MMU_INT_CLEAR, BIT(i)); +- status &= ~mask; +- continue; +- } +- } + +- /* terminal fault, print info about the fault */ +- dev_err(pfdev->dev, +- "Unhandled Page fault in AS%d at VA 0x%016llX\n" +- "Reason: %s\n" +- "raw fault status: 0x%X\n" +- "decoded fault status: %s\n" +- "exception type 0x%X: %s\n" +- "access type 0x%X: %s\n" +- "source id 0x%X\n", +- i, addr, +- "TODO", +- fault_status, +- (fault_status & (1 << 10) ? "DECODER FAULT" : "SLAVE FAULT"), +- exception_type, panfrost_exception_name(pfdev, exception_type), +- access_type, access_type_name(pfdev, fault_status), +- source_id); ++ if (ret) ++ /* terminal fault, print info about the fault */ ++ dev_err(pfdev->dev, ++ "Unhandled Page fault in AS%d at VA 0x%016llX\n" ++ "Reason: %s\n" ++ "raw fault status: 0x%X\n" ++ "decoded fault status: %s\n" ++ "exception type 0x%X: %s\n" ++ "access type 0x%X: %s\n" ++ "source id 0x%X\n", ++ i, addr, ++ "TODO", ++ fault_status, ++ (fault_status & (1 << 10) ? "DECODER FAULT" : "SLAVE FAULT"), ++ exception_type, panfrost_exception_name(pfdev, exception_type), ++ access_type, access_type_name(pfdev, fault_status), ++ source_id); + + mmu_write(pfdev, MMU_INT_CLEAR, mask); + +diff --git a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h b/drivers/gpu/drm/selftests/drm_cmdline_selftests.h +index 6d61a0eb5d64..84e6bc050bf2 100644 +--- a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h ++++ b/drivers/gpu/drm/selftests/drm_cmdline_selftests.h +@@ -53,6 +53,7 @@ cmdline_test(drm_cmdline_test_rotate_0) + cmdline_test(drm_cmdline_test_rotate_90) + cmdline_test(drm_cmdline_test_rotate_180) + cmdline_test(drm_cmdline_test_rotate_270) ++cmdline_test(drm_cmdline_test_rotate_multiple) + cmdline_test(drm_cmdline_test_rotate_invalid_val) + cmdline_test(drm_cmdline_test_rotate_truncated) + cmdline_test(drm_cmdline_test_hmirror) +diff --git a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c +index 013de9d27c35..035f86c5d648 100644 +--- a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c ++++ b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c +@@ -856,6 +856,17 @@ static int drm_cmdline_test_rotate_270(void *ignored) + return 0; + } + ++static int drm_cmdline_test_rotate_multiple(void *ignored) ++{ ++ struct drm_cmdline_mode mode = { }; ++ ++ FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=0,rotate=90", ++ &no_connector, ++ &mode)); ++ ++ return 0; ++} ++ + static int drm_cmdline_test_rotate_invalid_val(void *ignored) + { + struct drm_cmdline_mode mode = { }; +@@ -888,7 +899,7 @@ static int drm_cmdline_test_hmirror(void *ignored) + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); +- FAIL_ON(mode.rotation_reflection != DRM_MODE_REFLECT_X); ++ FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X)); + + FAIL_ON(mode.refresh_specified); + +@@ -913,7 +924,7 @@ static int drm_cmdline_test_vmirror(void *ignored) + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); +- FAIL_ON(mode.rotation_reflection != DRM_MODE_REFLECT_Y); ++ FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y)); + + FAIL_ON(mode.refresh_specified); + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index 8b803eb903b8..18b4881f4481 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -106,48 +106,128 @@ static const struct de2_fmt_info de2_formats[] = { + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_XRGB4444, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ARGB4444, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_ABGR4444, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_XBGR4444, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_RGBA4444, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_RGBX4444, ++ .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_BGRA4444, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_BGRX4444, ++ .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_ARGB1555, + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_XRGB1555, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_ABGR1555, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_XBGR1555, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_RGBA5551, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_RGBX5551, ++ .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_BGRA5551, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_BGRX5551, ++ .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, ++ { ++ .drm_fmt = DRM_FORMAT_ARGB2101010, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ARGB2101010, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, ++ { ++ .drm_fmt = DRM_FORMAT_ABGR2101010, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ABGR2101010, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, ++ { ++ .drm_fmt = DRM_FORMAT_RGBA1010102, ++ .de2_fmt = SUN8I_MIXER_FBFMT_RGBA1010102, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, ++ { ++ .drm_fmt = DRM_FORMAT_BGRA1010102, ++ .de2_fmt = SUN8I_MIXER_FBFMT_BGRA1010102, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_UYVY, + .de2_fmt = SUN8I_MIXER_FBFMT_UYVY, +@@ -196,12 +276,6 @@ static const struct de2_fmt_info de2_formats[] = { + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, +- { +- .drm_fmt = DRM_FORMAT_YUV444, +- .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, +- .rgb = true, +- .csc = SUN8I_CSC_MODE_YUV2RGB, +- }, + { + .drm_fmt = DRM_FORMAT_YUV422, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, +@@ -220,12 +294,6 @@ static const struct de2_fmt_info de2_formats[] = { + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, +- { +- .drm_fmt = DRM_FORMAT_YVU444, +- .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, +- .rgb = true, +- .csc = SUN8I_CSC_MODE_YVU2RGB, +- }, + { + .drm_fmt = DRM_FORMAT_YVU422, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, +@@ -244,6 +312,18 @@ static const struct de2_fmt_info de2_formats[] = { + .rgb = false, + .csc = SUN8I_CSC_MODE_YVU2RGB, + }, ++ { ++ .drm_fmt = DRM_FORMAT_P010, ++ .de2_fmt = SUN8I_MIXER_FBFMT_P010_YUV, ++ .rgb = false, ++ .csc = SUN8I_CSC_MODE_YUV2RGB, ++ }, ++ { ++ .drm_fmt = DRM_FORMAT_P210, ++ .de2_fmt = SUN8I_MIXER_FBFMT_P210_YUV, ++ .rgb = false, ++ .csc = SUN8I_CSC_MODE_YUV2RGB, ++ }, + }; + + const struct de2_fmt_info *sun8i_mixer_format_info(u32 format) +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h +index c6cc94057faf..345b28b0a80a 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h +@@ -93,6 +93,10 @@ + #define SUN8I_MIXER_FBFMT_ABGR1555 17 + #define SUN8I_MIXER_FBFMT_RGBA5551 18 + #define SUN8I_MIXER_FBFMT_BGRA5551 19 ++#define SUN8I_MIXER_FBFMT_ARGB2101010 20 ++#define SUN8I_MIXER_FBFMT_ABGR2101010 21 ++#define SUN8I_MIXER_FBFMT_RGBA1010102 22 ++#define SUN8I_MIXER_FBFMT_BGRA1010102 23 + + #define SUN8I_MIXER_FBFMT_YUYV 0 + #define SUN8I_MIXER_FBFMT_UYVY 1 +@@ -109,6 +113,13 @@ + /* format 12 is semi-planar YUV411 UVUV */ + /* format 13 is semi-planar YUV411 VUVU */ + #define SUN8I_MIXER_FBFMT_YUV411 14 ++/* format 15 doesn't exist */ ++/* format 16 is P010 YVU */ ++#define SUN8I_MIXER_FBFMT_P010_YUV 17 ++/* format 18 is P210 YVU */ ++#define SUN8I_MIXER_FBFMT_P210_YUV 19 ++/* format 20 is packed YVU444 10-bit */ ++/* format 21 is packed YUV444 10-bit */ + + /* + * Sub-engines listed bellow are unused for now. The EN registers are here only +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index 42d445d23773..b8398ca18b0f 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -398,24 +398,66 @@ static const struct drm_plane_funcs sun8i_vi_layer_funcs = { + }; + + /* +- * While all RGB formats are supported, VI planes don't support +- * alpha blending, so there is no point having formats with alpha +- * channel if their opaque analog exist. ++ * While DE2 VI layer supports same RGB formats as UI layer, alpha ++ * channel is ignored. This structure lists all unique variants ++ * where alpha channel is replaced with "don't care" (X) channel. + */ + static const u32 sun8i_vi_layer_formats[] = { ++ DRM_FORMAT_BGR565, ++ DRM_FORMAT_BGR888, ++ DRM_FORMAT_BGRX4444, ++ DRM_FORMAT_BGRX5551, ++ DRM_FORMAT_BGRX8888, ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_RGB888, ++ DRM_FORMAT_RGBX4444, ++ DRM_FORMAT_RGBX5551, ++ DRM_FORMAT_RGBX8888, ++ DRM_FORMAT_XBGR1555, ++ DRM_FORMAT_XBGR4444, ++ DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_XRGB1555, ++ DRM_FORMAT_XRGB4444, ++ DRM_FORMAT_XRGB8888, ++ ++ DRM_FORMAT_NV16, ++ DRM_FORMAT_NV12, ++ DRM_FORMAT_NV21, ++ DRM_FORMAT_NV61, ++ DRM_FORMAT_UYVY, ++ DRM_FORMAT_VYUY, ++ DRM_FORMAT_YUYV, ++ DRM_FORMAT_YVYU, ++ DRM_FORMAT_YUV411, ++ DRM_FORMAT_YUV420, ++ DRM_FORMAT_YUV422, ++ DRM_FORMAT_YVU411, ++ DRM_FORMAT_YVU420, ++ DRM_FORMAT_YVU422, ++}; ++ ++static const u32 sun8i_vi_layer_de3_formats[] = { + DRM_FORMAT_ABGR1555, ++ DRM_FORMAT_ABGR2101010, + DRM_FORMAT_ABGR4444, ++ DRM_FORMAT_ABGR8888, + DRM_FORMAT_ARGB1555, ++ DRM_FORMAT_ARGB2101010, + DRM_FORMAT_ARGB4444, ++ DRM_FORMAT_ARGB8888, + DRM_FORMAT_BGR565, + DRM_FORMAT_BGR888, ++ DRM_FORMAT_BGRA1010102, + DRM_FORMAT_BGRA5551, + DRM_FORMAT_BGRA4444, ++ DRM_FORMAT_BGRA8888, + DRM_FORMAT_BGRX8888, + DRM_FORMAT_RGB565, + DRM_FORMAT_RGB888, ++ DRM_FORMAT_RGBA1010102, + DRM_FORMAT_RGBA4444, + DRM_FORMAT_RGBA5551, ++ DRM_FORMAT_RGBA8888, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB8888, +@@ -424,6 +466,8 @@ static const u32 sun8i_vi_layer_formats[] = { + DRM_FORMAT_NV12, + DRM_FORMAT_NV21, + DRM_FORMAT_NV61, ++ DRM_FORMAT_P010, ++ DRM_FORMAT_P210, + DRM_FORMAT_UYVY, + DRM_FORMAT_VYUY, + DRM_FORMAT_YUYV, +@@ -431,11 +475,9 @@ static const u32 sun8i_vi_layer_formats[] = { + DRM_FORMAT_YUV411, + DRM_FORMAT_YUV420, + DRM_FORMAT_YUV422, +- DRM_FORMAT_YUV444, + DRM_FORMAT_YVU411, + DRM_FORMAT_YVU420, + DRM_FORMAT_YVU422, +- DRM_FORMAT_YVU444, + }; + + struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, +@@ -443,19 +485,27 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + int index) + { + u32 supported_encodings, supported_ranges; ++ unsigned int plane_cnt, format_count; + struct sun8i_vi_layer *layer; +- unsigned int plane_cnt; ++ const u32 *formats; + int ret; + + layer = devm_kzalloc(drm->dev, sizeof(*layer), GFP_KERNEL); + if (!layer) + return ERR_PTR(-ENOMEM); + ++ if (mixer->cfg->is_de3) { ++ formats = sun8i_vi_layer_de3_formats; ++ format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); ++ } else { ++ formats = sun8i_vi_layer_formats; ++ format_count = ARRAY_SIZE(sun8i_vi_layer_formats); ++ } ++ + /* possible crtcs are set later */ + ret = drm_universal_plane_init(drm, &layer->plane, 0, + &sun8i_vi_layer_funcs, +- sun8i_vi_layer_formats, +- ARRAY_SIZE(sun8i_vi_layer_formats), ++ formats, format_count, + NULL, DRM_PLANE_TYPE_OVERLAY, NULL); + if (ret) { + dev_err(drm->dev, "Couldn't initialize layer\n"); +diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c +index 09b526518f5a..8de93ccacaac 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_object.c ++++ b/drivers/gpu/drm/virtio/virtgpu_object.c +@@ -23,38 +23,44 @@ + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + ++#include ++ + #include + + #include "virtgpu_drv.h" + ++static int virtio_gpu_virglrenderer_workaround = 1; ++module_param_named(virglhack, virtio_gpu_virglrenderer_workaround, int, 0400); ++ + static int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, + uint32_t *resid) + { +-#if 0 +- int handle = ida_alloc(&vgdev->resource_ida, GFP_KERNEL); +- +- if (handle < 0) +- return handle; +-#else +- static int handle; +- +- /* +- * FIXME: dirty hack to avoid re-using IDs, virglrenderer +- * can't deal with that. Needs fixing in virglrenderer, also +- * should figure a better way to handle that in the guest. +- */ +- handle++; +-#endif +- +- *resid = handle + 1; ++ if (virtio_gpu_virglrenderer_workaround) { ++ /* ++ * Hack to avoid re-using resource IDs. ++ * ++ * virglrenderer versions up to (and including) 0.7.0 ++ * can't deal with that. virglrenderer commit ++ * "f91a9dd35715 Fix unlinking resources from hash ++ * table." (Feb 2019) fixes the bug. ++ */ ++ static atomic_t seqno = ATOMIC_INIT(0); ++ int handle = atomic_inc_return(&seqno); ++ *resid = handle + 1; ++ } else { ++ int handle = ida_alloc(&vgdev->resource_ida, GFP_KERNEL); ++ if (handle < 0) ++ return handle; ++ *resid = handle + 1; ++ } + return 0; + } + + static void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id) + { +-#if 0 +- ida_free(&vgdev->resource_ida, id - 1); +-#endif ++ if (!virtio_gpu_virglrenderer_workaround) { ++ ida_free(&vgdev->resource_ida, id - 1); ++ } + } + + static void virtio_gpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) +diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c +index 9632e2e3c4bb..319a0519ebdb 100644 +--- a/drivers/hwmon/adt7462.c ++++ b/drivers/hwmon/adt7462.c +@@ -413,7 +413,7 @@ static int ADT7462_REG_VOLT(struct adt7462_data *data, int which) + return 0x95; + break; + } +- return -ENODEV; ++ return 0; + } + + /* Provide labels for sysfs */ +diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c +index 5920c0085d35..319e4b4ae639 100644 +--- a/drivers/infiniband/core/cm.c ++++ b/drivers/infiniband/core/cm.c +@@ -1228,6 +1228,7 @@ struct ib_cm_id *ib_cm_insert_listen(struct ib_device *device, + /* Sharing an ib_cm_id with different handlers is not + * supported */ + spin_unlock_irqrestore(&cm.lock, flags); ++ ib_destroy_cm_id(cm_id); + return ERR_PTR(-EINVAL); + } + atomic_inc(&cm_id_priv->refcount); +diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c +index 9008937f8ed8..6c12da176981 100644 +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -3155,19 +3155,26 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, + int ret; + + id_priv = container_of(id, struct rdma_id_private, id); ++ memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); + if (id_priv->state == RDMA_CM_IDLE) { + ret = cma_bind_addr(id, src_addr, dst_addr); +- if (ret) ++ if (ret) { ++ memset(cma_dst_addr(id_priv), 0, ++ rdma_addr_size(dst_addr)); + return ret; ++ } + } + +- if (cma_family(id_priv) != dst_addr->sa_family) ++ if (cma_family(id_priv) != dst_addr->sa_family) { ++ memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); + return -EINVAL; ++ } + +- if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) ++ if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { ++ memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); + return -EINVAL; ++ } + +- memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); + if (cma_any_addr(dst_addr)) { + ret = cma_resolve_loopback(id_priv); + } else { +diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h +index 9b30773f2da0..86a17a87f181 100644 +--- a/drivers/infiniband/core/core_priv.h ++++ b/drivers/infiniband/core/core_priv.h +@@ -338,6 +338,21 @@ static inline struct ib_qp *_ib_create_qp(struct ib_device *dev, + qp->pd = pd; + qp->uobject = uobj; + qp->real_qp = qp; ++ ++ qp->qp_type = attr->qp_type; ++ qp->qp_context = attr->qp_context; ++ qp->rwq_ind_tbl = attr->rwq_ind_tbl; ++ qp->send_cq = attr->send_cq; ++ qp->recv_cq = attr->recv_cq; ++ qp->srq = attr->srq; ++ qp->rwq_ind_tbl = attr->rwq_ind_tbl; ++ qp->event_handler = attr->event_handler; ++ ++ atomic_set(&qp->usecnt, 0); ++ spin_lock_init(&qp->mr_lock); ++ INIT_LIST_HEAD(&qp->rdma_mrs); ++ INIT_LIST_HEAD(&qp->sig_mrs); ++ + /* + * We don't track XRC QPs for now, because they don't have PD + * and more importantly they are created internaly by driver, +diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c +index ade71823370f..da8adadf4755 100644 +--- a/drivers/infiniband/core/iwcm.c ++++ b/drivers/infiniband/core/iwcm.c +@@ -159,8 +159,10 @@ static void dealloc_work_entries(struct iwcm_id_private *cm_id_priv) + { + struct list_head *e, *tmp; + +- list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) ++ list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) { ++ list_del(e); + kfree(list_entry(e, struct iwcm_work, free_list)); ++ } + } + + static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count) +diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c +index c03af08b80e7..ad4301ecfa59 100644 +--- a/drivers/infiniband/core/nldev.c ++++ b/drivers/infiniband/core/nldev.c +@@ -1711,6 +1711,8 @@ static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh, + if (ret) + goto err_msg; + } else { ++ if (!tb[RDMA_NLDEV_ATTR_RES_LQPN]) ++ goto err_msg; + qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]); + if (tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]) { + cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]); +diff --git a/drivers/infiniband/core/rw.c b/drivers/infiniband/core/rw.c +index 5337393d4dfe..bb10cbfa0070 100644 +--- a/drivers/infiniband/core/rw.c ++++ b/drivers/infiniband/core/rw.c +@@ -268,6 +268,23 @@ static int rdma_rw_init_single_wr(struct rdma_rw_ctx *ctx, struct ib_qp *qp, + return 1; + } + ++static void rdma_rw_unmap_sg(struct ib_device *dev, struct scatterlist *sg, ++ u32 sg_cnt, enum dma_data_direction dir) ++{ ++ if (is_pci_p2pdma_page(sg_page(sg))) ++ pci_p2pdma_unmap_sg(dev->dma_device, sg, sg_cnt, dir); ++ else ++ ib_dma_unmap_sg(dev, sg, sg_cnt, dir); ++} ++ ++static int rdma_rw_map_sg(struct ib_device *dev, struct scatterlist *sg, ++ u32 sg_cnt, enum dma_data_direction dir) ++{ ++ if (is_pci_p2pdma_page(sg_page(sg))) ++ return pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir); ++ return ib_dma_map_sg(dev, sg, sg_cnt, dir); ++} ++ + /** + * rdma_rw_ctx_init - initialize a RDMA READ/WRITE context + * @ctx: context to initialize +@@ -290,11 +307,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num, + struct ib_device *dev = qp->pd->device; + int ret; + +- if (is_pci_p2pdma_page(sg_page(sg))) +- ret = pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir); +- else +- ret = ib_dma_map_sg(dev, sg, sg_cnt, dir); +- ++ ret = rdma_rw_map_sg(dev, sg, sg_cnt, dir); + if (!ret) + return -ENOMEM; + sg_cnt = ret; +@@ -333,7 +346,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num, + return ret; + + out_unmap_sg: +- ib_dma_unmap_sg(dev, sg, sg_cnt, dir); ++ rdma_rw_unmap_sg(dev, sg, sg_cnt, dir); + return ret; + } + EXPORT_SYMBOL(rdma_rw_ctx_init); +@@ -583,11 +596,7 @@ void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num, + break; + } + +- if (is_pci_p2pdma_page(sg_page(sg))) +- pci_p2pdma_unmap_sg(qp->pd->device->dma_device, sg, +- sg_cnt, dir); +- else +- ib_dma_unmap_sg(qp->pd->device, sg, sg_cnt, dir); ++ rdma_rw_unmap_sg(qp->pd->device, sg, sg_cnt, dir); + } + EXPORT_SYMBOL(rdma_rw_ctx_destroy); + +diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c +index 2b4d80393bd0..2d5608315dc8 100644 +--- a/drivers/infiniband/core/security.c ++++ b/drivers/infiniband/core/security.c +@@ -340,15 +340,19 @@ static struct ib_ports_pkeys *get_new_pps(const struct ib_qp *qp, + return NULL; + + if (qp_attr_mask & IB_QP_PORT) +- new_pps->main.port_num = +- (qp_pps) ? qp_pps->main.port_num : qp_attr->port_num; ++ new_pps->main.port_num = qp_attr->port_num; ++ else if (qp_pps) ++ new_pps->main.port_num = qp_pps->main.port_num; ++ + if (qp_attr_mask & IB_QP_PKEY_INDEX) +- new_pps->main.pkey_index = (qp_pps) ? qp_pps->main.pkey_index : +- qp_attr->pkey_index; ++ new_pps->main.pkey_index = qp_attr->pkey_index; ++ else if (qp_pps) ++ new_pps->main.pkey_index = qp_pps->main.pkey_index; ++ + if ((qp_attr_mask & IB_QP_PKEY_INDEX) && (qp_attr_mask & IB_QP_PORT)) + new_pps->main.state = IB_PORT_PKEY_VALID; + +- if (!(qp_attr_mask & (IB_QP_PKEY_INDEX || IB_QP_PORT)) && qp_pps) { ++ if (!(qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) && qp_pps) { + new_pps->main.port_num = qp_pps->main.port_num; + new_pps->main.pkey_index = qp_pps->main.pkey_index; + if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID) +diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c +index 300353c1e5f1..e2ddcb0dc4ee 100644 +--- a/drivers/infiniband/core/uverbs_cmd.c ++++ b/drivers/infiniband/core/uverbs_cmd.c +@@ -1431,17 +1431,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs, + if (ret) + goto err_cb; + +- qp->pd = pd; +- qp->send_cq = attr.send_cq; +- qp->recv_cq = attr.recv_cq; +- qp->srq = attr.srq; +- qp->rwq_ind_tbl = ind_tbl; +- qp->event_handler = attr.event_handler; +- qp->qp_context = attr.qp_context; +- qp->qp_type = attr.qp_type; +- atomic_set(&qp->usecnt, 0); + atomic_inc(&pd->usecnt); +- qp->port = 0; + if (attr.send_cq) + atomic_inc(&attr.send_cq->usecnt); + if (attr.recv_cq) +diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c +index 35c2841a569e..6c4093d0a91d 100644 +--- a/drivers/infiniband/core/verbs.c ++++ b/drivers/infiniband/core/verbs.c +@@ -1180,16 +1180,6 @@ struct ib_qp *ib_create_qp_user(struct ib_pd *pd, + if (ret) + goto err; + +- qp->qp_type = qp_init_attr->qp_type; +- qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl; +- +- atomic_set(&qp->usecnt, 0); +- qp->mrs_used = 0; +- spin_lock_init(&qp->mr_lock); +- INIT_LIST_HEAD(&qp->rdma_mrs); +- INIT_LIST_HEAD(&qp->sig_mrs); +- qp->port = 0; +- + if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { + struct ib_qp *xrc_qp = + create_xrc_qp_user(qp, qp_init_attr, udata); +diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c +index 089e201d7550..2f6323ad9c59 100644 +--- a/drivers/infiniband/hw/hfi1/verbs.c ++++ b/drivers/infiniband/hw/hfi1/verbs.c +@@ -515,10 +515,11 @@ static inline void hfi1_handle_packet(struct hfi1_packet *packet, + opa_get_lid(packet->dlid, 9B)); + if (!mcast) + goto drop; ++ rcu_read_lock(); + list_for_each_entry_rcu(p, &mcast->qp_list, list) { + packet->qp = p->qp; + if (hfi1_do_pkey_check(packet)) +- goto drop; ++ goto unlock_drop; + spin_lock_irqsave(&packet->qp->r_lock, flags); + packet_handler = qp_ok(packet); + if (likely(packet_handler)) +@@ -527,6 +528,7 @@ static inline void hfi1_handle_packet(struct hfi1_packet *packet, + ibp->rvp.n_pkt_drops++; + spin_unlock_irqrestore(&packet->qp->r_lock, flags); + } ++ rcu_read_unlock(); + /* + * Notify rvt_multicast_detach() if it is waiting for us + * to finish. +diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c +index 33778d451b82..5ef93f8f17a1 100644 +--- a/drivers/infiniband/hw/qib/qib_verbs.c ++++ b/drivers/infiniband/hw/qib/qib_verbs.c +@@ -329,8 +329,10 @@ void qib_ib_rcv(struct qib_ctxtdata *rcd, void *rhdr, void *data, u32 tlen) + if (mcast == NULL) + goto drop; + this_cpu_inc(ibp->pmastats->n_multicast_rcv); ++ rcu_read_lock(); + list_for_each_entry_rcu(p, &mcast->qp_list, list) + qib_qp_rcv(rcd, hdr, 1, data, tlen, p->qp); ++ rcu_read_unlock(); + /* + * Notify rvt_multicast_detach() if it is waiting for us + * to finish. +diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c +index fb01407a310f..130b1e31b978 100644 +--- a/drivers/infiniband/sw/siw/siw_main.c ++++ b/drivers/infiniband/sw/siw/siw_main.c +@@ -379,6 +379,9 @@ static struct siw_device *siw_device_create(struct net_device *netdev) + base_dev->dev.dma_ops = &dma_virt_ops; + base_dev->num_comp_vectors = num_possible_cpus(); + ++ xa_init_flags(&sdev->qp_xa, XA_FLAGS_ALLOC1); ++ xa_init_flags(&sdev->mem_xa, XA_FLAGS_ALLOC1); ++ + ib_set_device_ops(base_dev, &siw_device_ops); + rv = ib_device_set_netdev(base_dev, netdev, 1); + if (rv) +@@ -406,9 +409,6 @@ static struct siw_device *siw_device_create(struct net_device *netdev) + sdev->attrs.max_srq_wr = SIW_MAX_SRQ_WR; + sdev->attrs.max_srq_sge = SIW_MAX_SGE; + +- xa_init_flags(&sdev->qp_xa, XA_FLAGS_ALLOC1); +- xa_init_flags(&sdev->mem_xa, XA_FLAGS_ALLOC1); +- + INIT_LIST_HEAD(&sdev->cep_list); + INIT_LIST_HEAD(&sdev->qp_list); + +diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c +index d7cbca8bf2cd..b5ae9f7c0510 100644 +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -2533,6 +2533,7 @@ static int __init early_amd_iommu_init(void) + struct acpi_table_header *ivrs_base; + acpi_status status; + int i, remap_cache_sz, ret = 0; ++ u32 pci_id; + + if (!amd_iommu_detected) + return -ENODEV; +@@ -2620,6 +2621,16 @@ static int __init early_amd_iommu_init(void) + if (ret) + goto out; + ++ /* Disable IOMMU if there's Stoney Ridge graphics */ ++ for (i = 0; i < 32; i++) { ++ pci_id = read_pci_config(0, i, 0, 0); ++ if ((pci_id & 0xffff) == 0x1002 && (pci_id >> 16) == 0x98e4) { ++ pr_info("Disable IOMMU on Stoney Ridge\n"); ++ amd_iommu_disabled = true; ++ break; ++ } ++ } ++ + /* Disable any previously enabled IOMMUs */ + if (!is_kdump_kernel() || amd_iommu_disabled) + disable_iommus(); +@@ -2728,7 +2739,7 @@ static int __init state_next(void) + ret = early_amd_iommu_init(); + init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED; + if (init_state == IOMMU_ACPI_FINISHED && amd_iommu_disabled) { +- pr_info("AMD IOMMU disabled on kernel command-line\n"); ++ pr_info("AMD IOMMU disabled\n"); + init_state = IOMMU_CMDLINE_DISABLED; + ret = -EINVAL; + } +diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c +index 8346e6d1816c..f595e9867cbe 100644 +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -2867,8 +2867,8 @@ static void cache_postsuspend(struct dm_target *ti) + prevent_background_work(cache); + BUG_ON(atomic_read(&cache->nr_io_migrations)); + +- cancel_delayed_work(&cache->waker); +- flush_workqueue(cache->wq); ++ cancel_delayed_work_sync(&cache->waker); ++ drain_workqueue(cache->wq); + WARN_ON(cache->tracker.in_flight); + + /* +diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c +index dab4446fe7d8..57ac603f3741 100644 +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -199,17 +199,19 @@ struct dm_integrity_c { + __u8 log2_blocks_per_bitmap_bit; + + unsigned char mode; +- int suspending; + + int failed; + + struct crypto_shash *internal_hash; + ++ struct dm_target *ti; ++ + /* these variables are locked with endio_wait.lock */ + struct rb_root in_progress; + struct list_head wait_list; + wait_queue_head_t endio_wait; + struct workqueue_struct *wait_wq; ++ struct workqueue_struct *offload_wq; + + unsigned char commit_seq; + commit_id_t commit_ids[N_COMMIT_IDS]; +@@ -1434,7 +1436,7 @@ static void dec_in_flight(struct dm_integrity_io *dio) + dio->range.logical_sector += dio->range.n_sectors; + bio_advance(bio, dio->range.n_sectors << SECTOR_SHIFT); + INIT_WORK(&dio->work, integrity_bio_wait); +- queue_work(ic->wait_wq, &dio->work); ++ queue_work(ic->offload_wq, &dio->work); + return; + } + do_endio_flush(ic, dio); +@@ -1860,7 +1862,7 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map + + if (need_sync_io && from_map) { + INIT_WORK(&dio->work, integrity_bio_wait); +- queue_work(ic->metadata_wq, &dio->work); ++ queue_work(ic->offload_wq, &dio->work); + return; + } + +@@ -2310,7 +2312,7 @@ static void integrity_writer(struct work_struct *w) + unsigned prev_free_sectors; + + /* the following test is not needed, but it tests the replay code */ +- if (READ_ONCE(ic->suspending) && !ic->meta_dev) ++ if (unlikely(dm_suspended(ic->ti)) && !ic->meta_dev) + return; + + spin_lock_irq(&ic->endio_wait.lock); +@@ -2371,7 +2373,7 @@ static void integrity_recalc(struct work_struct *w) + + next_chunk: + +- if (unlikely(READ_ONCE(ic->suspending))) ++ if (unlikely(dm_suspended(ic->ti))) + goto unlock_ret; + + range.logical_sector = le64_to_cpu(ic->sb->recalc_sector); +@@ -2496,7 +2498,7 @@ static void bitmap_block_work(struct work_struct *w) + dio->range.n_sectors, BITMAP_OP_TEST_ALL_SET)) { + remove_range(ic, &dio->range); + INIT_WORK(&dio->work, integrity_bio_wait); +- queue_work(ic->wait_wq, &dio->work); ++ queue_work(ic->offload_wq, &dio->work); + } else { + block_bitmap_op(ic, ic->journal, dio->range.logical_sector, + dio->range.n_sectors, BITMAP_OP_SET); +@@ -2519,7 +2521,7 @@ static void bitmap_block_work(struct work_struct *w) + + remove_range(ic, &dio->range); + INIT_WORK(&dio->work, integrity_bio_wait); +- queue_work(ic->wait_wq, &dio->work); ++ queue_work(ic->offload_wq, &dio->work); + } + + queue_delayed_work(ic->commit_wq, &ic->bitmap_flush_work, ic->bitmap_flush_interval); +@@ -2799,8 +2801,6 @@ static void dm_integrity_postsuspend(struct dm_target *ti) + + del_timer_sync(&ic->autocommit_timer); + +- WRITE_ONCE(ic->suspending, 1); +- + if (ic->recalc_wq) + drain_workqueue(ic->recalc_wq); + +@@ -2829,8 +2829,6 @@ static void dm_integrity_postsuspend(struct dm_target *ti) + #endif + } + +- WRITE_ONCE(ic->suspending, 0); +- + BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress)); + + ic->journal_uptodate = true; +@@ -2883,17 +2881,24 @@ static void dm_integrity_resume(struct dm_target *ti) + } else { + replay_journal(ic); + if (ic->mode == 'B') { +- int mode; + ic->sb->flags |= cpu_to_le32(SB_FLAG_DIRTY_BITMAP); + ic->sb->log2_blocks_per_bitmap_bit = ic->log2_blocks_per_bitmap_bit; + r = sync_rw_sb(ic, REQ_OP_WRITE, REQ_FUA); + if (unlikely(r)) + dm_integrity_io_error(ic, "writing superblock", r); + +- mode = ic->recalculate_flag ? BITMAP_OP_SET : BITMAP_OP_CLEAR; +- block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, mode); +- block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, mode); +- block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, mode); ++ block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); ++ block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); ++ block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); ++ if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) && ++ le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors) { ++ block_bitmap_op(ic, ic->journal, le64_to_cpu(ic->sb->recalc_sector), ++ ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET); ++ block_bitmap_op(ic, ic->recalc_bitmap, le64_to_cpu(ic->sb->recalc_sector), ++ ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET); ++ block_bitmap_op(ic, ic->may_write_bitmap, le64_to_cpu(ic->sb->recalc_sector), ++ ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET); ++ } + rw_journal_sectors(ic, REQ_OP_WRITE, REQ_FUA | REQ_SYNC, 0, + ic->n_bitmap_blocks * (BITMAP_BLOCK_SIZE >> SECTOR_SHIFT), NULL); + } +@@ -2961,7 +2966,7 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type, + DMEMIT(" meta_device:%s", ic->meta_dev->name); + if (ic->sectors_per_block != 1) + DMEMIT(" block_size:%u", ic->sectors_per_block << SECTOR_SHIFT); +- if (ic->recalculate_flag) ++ if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) + DMEMIT(" recalculate"); + DMEMIT(" journal_sectors:%u", ic->initial_sectors - SB_SECTORS); + DMEMIT(" interleave_sectors:%u", 1U << ic->sb->log2_interleave_sectors); +@@ -3607,6 +3612,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) + } + ti->private = ic; + ti->per_io_data_size = sizeof(struct dm_integrity_io); ++ ic->ti = ti; + + ic->in_progress = RB_ROOT; + INIT_LIST_HEAD(&ic->wait_list); +@@ -3818,6 +3824,14 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) + goto bad; + } + ++ ic->offload_wq = alloc_workqueue("dm-integrity-offload", WQ_MEM_RECLAIM, ++ METADATA_WORKQUEUE_MAX_ACTIVE); ++ if (!ic->offload_wq) { ++ ti->error = "Cannot allocate workqueue"; ++ r = -ENOMEM; ++ goto bad; ++ } ++ + ic->commit_wq = alloc_workqueue("dm-integrity-commit", WQ_MEM_RECLAIM, 1); + if (!ic->commit_wq) { + ti->error = "Cannot allocate workqueue"; +@@ -4122,6 +4136,8 @@ static void dm_integrity_dtr(struct dm_target *ti) + destroy_workqueue(ic->metadata_wq); + if (ic->wait_wq) + destroy_workqueue(ic->wait_wq); ++ if (ic->offload_wq) ++ destroy_workqueue(ic->offload_wq); + if (ic->commit_wq) + destroy_workqueue(ic->commit_wq); + if (ic->writer_wq) +diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c +index 8bb723f1a569..4cd8868f8004 100644 +--- a/drivers/md/dm-thin-metadata.c ++++ b/drivers/md/dm-thin-metadata.c +@@ -960,9 +960,9 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd) + DMWARN("%s: __commit_transaction() failed, error = %d", + __func__, r); + } ++ pmd_write_unlock(pmd); + if (!pmd->fail_io) + __destroy_persistent_data_objects(pmd); +- pmd_write_unlock(pmd); + + kfree(pmd); + return 0; +diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c +index 07c1b0334f57..184dabce1bad 100644 +--- a/drivers/md/dm-writecache.c ++++ b/drivers/md/dm-writecache.c +@@ -625,6 +625,12 @@ static void writecache_add_to_freelist(struct dm_writecache *wc, struct wc_entry + wc->freelist_size++; + } + ++static inline void writecache_verify_watermark(struct dm_writecache *wc) ++{ ++ if (unlikely(wc->freelist_size + wc->writeback_size <= wc->freelist_high_watermark)) ++ queue_work(wc->writeback_wq, &wc->writeback_work); ++} ++ + static struct wc_entry *writecache_pop_from_freelist(struct dm_writecache *wc) + { + struct wc_entry *e; +@@ -646,8 +652,8 @@ static struct wc_entry *writecache_pop_from_freelist(struct dm_writecache *wc) + list_del(&e->lru); + } + wc->freelist_size--; +- if (unlikely(wc->freelist_size + wc->writeback_size <= wc->freelist_high_watermark)) +- queue_work(wc->writeback_wq, &wc->writeback_work); ++ ++ writecache_verify_watermark(wc); + + return e; + } +@@ -838,7 +844,7 @@ static void writecache_suspend(struct dm_target *ti) + } + wc_unlock(wc); + +- flush_workqueue(wc->writeback_wq); ++ drain_workqueue(wc->writeback_wq); + + wc_lock(wc); + if (flush_on_suspend) +@@ -961,6 +967,8 @@ erase_this: + writecache_commit_flushed(wc, false); + } + ++ writecache_verify_watermark(wc); ++ + wc_unlock(wc); + } + +diff --git a/drivers/md/dm-zoned-target.c b/drivers/md/dm-zoned-target.c +index 4574e0dedbd6..03267609b515 100644 +--- a/drivers/md/dm-zoned-target.c ++++ b/drivers/md/dm-zoned-target.c +@@ -533,8 +533,9 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio) + + /* Get the BIO chunk work. If one is not active yet, create one */ + cw = radix_tree_lookup(&dmz->chunk_rxtree, chunk); +- if (!cw) { +- ++ if (cw) { ++ dmz_get_chunk_work(cw); ++ } else { + /* Create a new chunk work */ + cw = kmalloc(sizeof(struct dm_chunk_work), GFP_NOIO); + if (unlikely(!cw)) { +@@ -543,7 +544,7 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio) + } + + INIT_WORK(&cw->work, dmz_chunk_work); +- refcount_set(&cw->refcount, 0); ++ refcount_set(&cw->refcount, 1); + cw->target = dmz; + cw->chunk = chunk; + bio_list_init(&cw->bio_list); +@@ -556,7 +557,6 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio) + } + + bio_list_add(&cw->bio_list, bio); +- dmz_get_chunk_work(cw); + + dmz_reclaim_bio_acc(dmz->reclaim); + if (queue_work(dmz->chunk_wq, &cw->work)) +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index 6d3cc235f842..cf71a2277d60 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1809,7 +1809,8 @@ static int dm_any_congested(void *congested_data, int bdi_bits) + * With request-based DM we only need to check the + * top-level queue for congestion. + */ +- r = md->queue->backing_dev_info->wb.state & bdi_bits; ++ struct backing_dev_info *bdi = md->queue->backing_dev_info; ++ r = bdi->wb.congested->state & bdi_bits; + } else { + map = dm_get_live_table_fast(md); + if (map) +@@ -1875,15 +1876,6 @@ static const struct dax_operations dm_dax_ops; + + static void dm_wq_work(struct work_struct *work); + +-static void dm_init_normal_md_queue(struct mapped_device *md) +-{ +- /* +- * Initialize aspects of queue that aren't relevant for blk-mq +- */ +- md->queue->backing_dev_info->congested_data = md; +- md->queue->backing_dev_info->congested_fn = dm_any_congested; +-} +- + static void cleanup_mapped_device(struct mapped_device *md) + { + if (md->wq) +@@ -2270,6 +2262,12 @@ struct queue_limits *dm_get_queue_limits(struct mapped_device *md) + } + EXPORT_SYMBOL_GPL(dm_get_queue_limits); + ++static void dm_init_congested_fn(struct mapped_device *md) ++{ ++ md->queue->backing_dev_info->congested_data = md; ++ md->queue->backing_dev_info->congested_fn = dm_any_congested; ++} ++ + /* + * Setup the DM device's queue based on md's type + */ +@@ -2286,11 +2284,12 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t) + DMERR("Cannot initialize queue for request-based dm-mq mapped device"); + return r; + } ++ dm_init_congested_fn(md); + break; + case DM_TYPE_BIO_BASED: + case DM_TYPE_DAX_BIO_BASED: + case DM_TYPE_NVME_BIO_BASED: +- dm_init_normal_md_queue(md); ++ dm_init_congested_fn(md); + break; + case DM_TYPE_NONE: + WARN_ON_ONCE(true); +@@ -2389,6 +2388,7 @@ static void __dm_destroy(struct mapped_device *md, bool wait) + map = dm_get_live_table(md, &srcu_idx); + if (!dm_suspended_md(md)) { + dm_table_presuspend_targets(map); ++ set_bit(DMF_SUSPENDED, &md->flags); + dm_table_postsuspend_targets(map); + } + /* dm_put_live_table must be before msleep, otherwise deadlock is possible */ +diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c +index 7c429ce98bae..668770e9f609 100644 +--- a/drivers/media/mc/mc-entity.c ++++ b/drivers/media/mc/mc-entity.c +@@ -639,9 +639,9 @@ int media_get_pad_index(struct media_entity *entity, bool is_sink, + return -EINVAL; + + for (i = 0; i < entity->num_pads; i++) { +- if (entity->pads[i].flags == MEDIA_PAD_FL_SINK) ++ if (entity->pads[i].flags & MEDIA_PAD_FL_SINK) + pad_is_sink = true; +- else if (entity->pads[i].flags == MEDIA_PAD_FL_SOURCE) ++ else if (entity->pads[i].flags & MEDIA_PAD_FL_SOURCE) + pad_is_sink = false; + else + continue; /* This is an error! */ +diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.c b/drivers/media/platform/vicodec/codec-v4l2-fwht.c +index 3c93d9232c3c..b6e39fbd8ad5 100644 +--- a/drivers/media/platform/vicodec/codec-v4l2-fwht.c ++++ b/drivers/media/platform/vicodec/codec-v4l2-fwht.c +@@ -27,17 +27,17 @@ static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = { + { V4L2_PIX_FMT_BGR24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_RGB24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_HSV24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, +- { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, +- { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, ++ { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, ++ { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_ABGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, +- { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, +- { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, ++ { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, ++ { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_ARGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, +- { V4L2_PIX_FMT_BGRX32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, ++ { V4L2_PIX_FMT_BGRX32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_BGRA32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, +- { V4L2_PIX_FMT_RGBX32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, ++ { V4L2_PIX_FMT_RGBX32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_RGBA32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, +- { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, ++ { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_HSV}, + { V4L2_PIX_FMT_GREY, 1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB}, + }; + +@@ -175,22 +175,14 @@ static int prepare_raw_frame(struct fwht_raw_frame *rf, + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_XRGB32: + case V4L2_PIX_FMT_HSV32: +- rf->cr = rf->luma + 1; +- rf->cb = rf->cr + 2; +- rf->luma += 2; +- break; +- case V4L2_PIX_FMT_BGR32: +- case V4L2_PIX_FMT_XBGR32: +- rf->cb = rf->luma; +- rf->cr = rf->cb + 2; +- rf->luma++; +- break; + case V4L2_PIX_FMT_ARGB32: + rf->alpha = rf->luma; + rf->cr = rf->luma + 1; + rf->cb = rf->cr + 2; + rf->luma += 2; + break; ++ case V4L2_PIX_FMT_BGR32: ++ case V4L2_PIX_FMT_XBGR32: + case V4L2_PIX_FMT_ABGR32: + rf->cb = rf->luma; + rf->cr = rf->cb + 2; +@@ -198,10 +190,6 @@ static int prepare_raw_frame(struct fwht_raw_frame *rf, + rf->alpha = rf->cr + 1; + break; + case V4L2_PIX_FMT_BGRX32: +- rf->cb = rf->luma + 1; +- rf->cr = rf->cb + 2; +- rf->luma += 2; +- break; + case V4L2_PIX_FMT_BGRA32: + rf->alpha = rf->luma; + rf->cb = rf->luma + 1; +@@ -209,10 +197,6 @@ static int prepare_raw_frame(struct fwht_raw_frame *rf, + rf->luma += 2; + break; + case V4L2_PIX_FMT_RGBX32: +- rf->cr = rf->luma; +- rf->cb = rf->cr + 2; +- rf->luma++; +- break; + case V4L2_PIX_FMT_RGBA32: + rf->alpha = rf->luma + 3; + rf->cr = rf->luma; +diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c +index 19937dd3c6f6..3d6a6306cec7 100644 +--- a/drivers/media/v4l2-core/v4l2-mem2mem.c ++++ b/drivers/media/v4l2-core/v4l2-mem2mem.c +@@ -809,12 +809,12 @@ int v4l2_m2m_register_media_controller(struct v4l2_m2m_dev *m2m_dev, + goto err_rel_entity1; + + /* Connect the three entities */ +- ret = media_create_pad_link(m2m_dev->source, 0, &m2m_dev->proc, 1, ++ ret = media_create_pad_link(m2m_dev->source, 0, &m2m_dev->proc, 0, + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + if (ret) + goto err_rel_entity2; + +- ret = media_create_pad_link(&m2m_dev->proc, 0, &m2m_dev->sink, 0, ++ ret = media_create_pad_link(&m2m_dev->proc, 1, &m2m_dev->sink, 0, + MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); + if (ret) + goto err_rm_links0; +diff --git a/drivers/misc/habanalabs/device.c b/drivers/misc/habanalabs/device.c +index 459fee70a597..a7a4fed4d899 100644 +--- a/drivers/misc/habanalabs/device.c ++++ b/drivers/misc/habanalabs/device.c +@@ -600,7 +600,9 @@ int hl_device_set_debug_mode(struct hl_device *hdev, bool enable) + goto out; + } + +- hdev->asic_funcs->halt_coresight(hdev); ++ if (!hdev->hard_reset_pending) ++ hdev->asic_funcs->halt_coresight(hdev); ++ + hdev->in_debug = 0; + + goto out; +@@ -1185,6 +1187,7 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass) + if (hdev->asic_funcs->get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) { + dev_info(hdev->dev, + "H/W state is dirty, must reset before initializing\n"); ++ hdev->asic_funcs->halt_engines(hdev, true); + hdev->asic_funcs->hw_fini(hdev, true); + } + +diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c +index fe3574a83b7c..13b39fd97429 100644 +--- a/drivers/misc/habanalabs/goya/goya.c ++++ b/drivers/misc/habanalabs/goya/goya.c +@@ -869,6 +869,11 @@ void goya_init_dma_qmans(struct hl_device *hdev) + */ + static void goya_disable_external_queues(struct hl_device *hdev) + { ++ struct goya_device *goya = hdev->asic_specific; ++ ++ if (!(goya->hw_cap_initialized & HW_CAP_DMA)) ++ return; ++ + WREG32(mmDMA_QM_0_GLBL_CFG0, 0); + WREG32(mmDMA_QM_1_GLBL_CFG0, 0); + WREG32(mmDMA_QM_2_GLBL_CFG0, 0); +@@ -930,6 +935,11 @@ static int goya_stop_external_queues(struct hl_device *hdev) + { + int rc, retval = 0; + ++ struct goya_device *goya = hdev->asic_specific; ++ ++ if (!(goya->hw_cap_initialized & HW_CAP_DMA)) ++ return retval; ++ + rc = goya_stop_queue(hdev, + mmDMA_QM_0_GLBL_CFG1, + mmDMA_QM_0_CP_STS, +@@ -1719,9 +1729,18 @@ void goya_init_tpc_qmans(struct hl_device *hdev) + */ + static void goya_disable_internal_queues(struct hl_device *hdev) + { ++ struct goya_device *goya = hdev->asic_specific; ++ ++ if (!(goya->hw_cap_initialized & HW_CAP_MME)) ++ goto disable_tpc; ++ + WREG32(mmMME_QM_GLBL_CFG0, 0); + WREG32(mmMME_CMDQ_GLBL_CFG0, 0); + ++disable_tpc: ++ if (!(goya->hw_cap_initialized & HW_CAP_TPC)) ++ return; ++ + WREG32(mmTPC0_QM_GLBL_CFG0, 0); + WREG32(mmTPC0_CMDQ_GLBL_CFG0, 0); + +@@ -1757,8 +1776,12 @@ static void goya_disable_internal_queues(struct hl_device *hdev) + */ + static int goya_stop_internal_queues(struct hl_device *hdev) + { ++ struct goya_device *goya = hdev->asic_specific; + int rc, retval = 0; + ++ if (!(goya->hw_cap_initialized & HW_CAP_MME)) ++ goto stop_tpc; ++ + /* + * Each queue (QMAN) is a separate H/W logic. That means that each + * QMAN can be stopped independently and failure to stop one does NOT +@@ -1785,6 +1808,10 @@ static int goya_stop_internal_queues(struct hl_device *hdev) + retval = -EIO; + } + ++stop_tpc: ++ if (!(goya->hw_cap_initialized & HW_CAP_TPC)) ++ return retval; ++ + rc = goya_stop_queue(hdev, + mmTPC0_QM_GLBL_CFG1, + mmTPC0_QM_CP_STS, +@@ -1950,6 +1977,11 @@ static int goya_stop_internal_queues(struct hl_device *hdev) + + static void goya_dma_stall(struct hl_device *hdev) + { ++ struct goya_device *goya = hdev->asic_specific; ++ ++ if (!(goya->hw_cap_initialized & HW_CAP_DMA)) ++ return; ++ + WREG32(mmDMA_QM_0_GLBL_CFG1, 1 << DMA_QM_0_GLBL_CFG1_DMA_STOP_SHIFT); + WREG32(mmDMA_QM_1_GLBL_CFG1, 1 << DMA_QM_1_GLBL_CFG1_DMA_STOP_SHIFT); + WREG32(mmDMA_QM_2_GLBL_CFG1, 1 << DMA_QM_2_GLBL_CFG1_DMA_STOP_SHIFT); +@@ -1959,6 +1991,11 @@ static void goya_dma_stall(struct hl_device *hdev) + + static void goya_tpc_stall(struct hl_device *hdev) + { ++ struct goya_device *goya = hdev->asic_specific; ++ ++ if (!(goya->hw_cap_initialized & HW_CAP_TPC)) ++ return; ++ + WREG32(mmTPC0_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT); + WREG32(mmTPC1_CFG_TPC_STALL, 1 << TPC1_CFG_TPC_STALL_V_SHIFT); + WREG32(mmTPC2_CFG_TPC_STALL, 1 << TPC2_CFG_TPC_STALL_V_SHIFT); +@@ -1971,6 +2008,11 @@ static void goya_tpc_stall(struct hl_device *hdev) + + static void goya_mme_stall(struct hl_device *hdev) + { ++ struct goya_device *goya = hdev->asic_specific; ++ ++ if (!(goya->hw_cap_initialized & HW_CAP_MME)) ++ return; ++ + WREG32(mmMME_STALL, 0xFFFFFFFF); + } + +@@ -4624,8 +4666,6 @@ static int goya_memset_device_memory(struct hl_device *hdev, u64 addr, u64 size, + + rc = goya_send_job_on_qman0(hdev, job); + +- hl_cb_put(job->patched_cb); +- + hl_debugfs_remove_job(hdev, job); + kfree(job); + cb->cs_cnt--; +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c +index fecd5e674e04..46dc913da852 100644 +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -69,8 +69,7 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) + /* Force link status for IMP port */ + reg = core_readl(priv, offset); + reg |= (MII_SW_OR | LINK_STS); +- if (priv->type == BCM7278_DEVICE_ID) +- reg |= GMII_SPEED_UP_2G; ++ reg &= ~GMII_SPEED_UP_2G; + core_writel(priv, reg, offset); + + /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */ +diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c +index 52646855495e..873f9865f0d1 100644 +--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c ++++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c +@@ -22,6 +22,7 @@ + #define HW_ATL_MIF_ADDR 0x0208U + #define HW_ATL_MIF_VAL 0x020CU + ++#define HW_ATL_MPI_RPC_ADDR 0x0334U + #define HW_ATL_RPC_CONTROL_ADR 0x0338U + #define HW_ATL_RPC_STATE_ADR 0x033CU + +@@ -48,15 +49,14 @@ + #define FORCE_FLASHLESS 0 + + static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual); +- + static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self, + enum hal_atl_utils_fw_state_e state); +- + static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self); + static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self); + static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self); + static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self); + static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self); ++static u32 aq_fw1x_rpc_get(struct aq_hw_s *self); + + int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops) + { +@@ -413,6 +413,10 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self, + self, self->mbox_addr, + self->mbox_addr != 0U, + 1000U, 10000U); ++ err = readx_poll_timeout_atomic(aq_fw1x_rpc_get, self, ++ self->rpc_addr, ++ self->rpc_addr != 0U, ++ 1000U, 100000U); + + return err; + } +@@ -469,6 +473,12 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self, + self, fw.val, + sw.tid == fw.tid, + 1000U, 100000U); ++ if (err < 0) ++ goto err_exit; ++ ++ err = aq_hw_err_from_flags(self); ++ if (err < 0) ++ goto err_exit; + + if (fw.len == 0xFFFFU) { + err = hw_atl_utils_fw_rpc_call(self, sw.len); +@@ -950,6 +960,11 @@ static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self) + return aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR); + } + ++static u32 aq_fw1x_rpc_get(struct aq_hw_s *self) ++{ ++ return aq_hw_read_reg(self, HW_ATL_MPI_RPC_ADDR); ++} ++ + const struct aq_fw_ops aq_fw_1x_ops = { + .init = hw_atl_utils_mpi_create, + .deinit = hw_atl_fw1x_deinit, +diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +index 6cc100e7d5c0..76ff42ec3ae5 100644 +--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c ++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +@@ -410,10 +410,19 @@ void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable) + lmac = &bgx->lmac[lmacid]; + + cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG); +- if (enable) ++ if (enable) { + cfg |= CMR_PKT_RX_EN | CMR_PKT_TX_EN; +- else ++ ++ /* enable TX FIFO Underflow interrupt */ ++ bgx_reg_modify(bgx, lmacid, BGX_GMP_GMI_TXX_INT_ENA_W1S, ++ GMI_TXX_INT_UNDFLW); ++ } else { + cfg &= ~(CMR_PKT_RX_EN | CMR_PKT_TX_EN); ++ ++ /* Disable TX FIFO Underflow interrupt */ ++ bgx_reg_modify(bgx, lmacid, BGX_GMP_GMI_TXX_INT_ENA_W1C, ++ GMI_TXX_INT_UNDFLW); ++ } + bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg); + + if (bgx->is_rgx) +@@ -1535,6 +1544,48 @@ static int bgx_init_phy(struct bgx *bgx) + return bgx_init_of_phy(bgx); + } + ++static irqreturn_t bgx_intr_handler(int irq, void *data) ++{ ++ struct bgx *bgx = (struct bgx *)data; ++ u64 status, val; ++ int lmac; ++ ++ for (lmac = 0; lmac < bgx->lmac_count; lmac++) { ++ status = bgx_reg_read(bgx, lmac, BGX_GMP_GMI_TXX_INT); ++ if (status & GMI_TXX_INT_UNDFLW) { ++ pci_err(bgx->pdev, "BGX%d lmac%d UNDFLW\n", ++ bgx->bgx_id, lmac); ++ val = bgx_reg_read(bgx, lmac, BGX_CMRX_CFG); ++ val &= ~CMR_EN; ++ bgx_reg_write(bgx, lmac, BGX_CMRX_CFG, val); ++ val |= CMR_EN; ++ bgx_reg_write(bgx, lmac, BGX_CMRX_CFG, val); ++ } ++ /* clear interrupts */ ++ bgx_reg_write(bgx, lmac, BGX_GMP_GMI_TXX_INT, status); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static void bgx_register_intr(struct pci_dev *pdev) ++{ ++ struct bgx *bgx = pci_get_drvdata(pdev); ++ int ret; ++ ++ ret = pci_alloc_irq_vectors(pdev, BGX_LMAC_VEC_OFFSET, ++ BGX_LMAC_VEC_OFFSET, PCI_IRQ_ALL_TYPES); ++ if (ret < 0) { ++ pci_err(pdev, "Req for #%d msix vectors failed\n", ++ BGX_LMAC_VEC_OFFSET); ++ return; ++ } ++ ret = pci_request_irq(pdev, GMPX_GMI_TX_INT, bgx_intr_handler, NULL, ++ bgx, "BGX%d", bgx->bgx_id); ++ if (ret) ++ pci_free_irq(pdev, GMPX_GMI_TX_INT, bgx); ++} ++ + static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + { + int err; +@@ -1550,7 +1601,7 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + + pci_set_drvdata(pdev, bgx); + +- err = pci_enable_device(pdev); ++ err = pcim_enable_device(pdev); + if (err) { + dev_err(dev, "Failed to enable PCI device\n"); + pci_set_drvdata(pdev, NULL); +@@ -1604,6 +1655,8 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + + bgx_init_hw(bgx); + ++ bgx_register_intr(pdev); ++ + /* Enable all LMACs */ + for (lmac = 0; lmac < bgx->lmac_count; lmac++) { + err = bgx_lmac_enable(bgx, lmac); +@@ -1620,6 +1673,7 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + + err_enable: + bgx_vnic[bgx->bgx_id] = NULL; ++ pci_free_irq(pdev, GMPX_GMI_TX_INT, bgx); + err_release_regions: + pci_release_regions(pdev); + err_disable_device: +@@ -1637,6 +1691,8 @@ static void bgx_remove(struct pci_dev *pdev) + for (lmac = 0; lmac < bgx->lmac_count; lmac++) + bgx_lmac_disable(bgx, lmac); + ++ pci_free_irq(pdev, GMPX_GMI_TX_INT, bgx); ++ + bgx_vnic[bgx->bgx_id] = NULL; + pci_release_regions(pdev); + pci_disable_device(pdev); +diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h +index 25888706bdcd..cdea49392185 100644 +--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h ++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h +@@ -180,6 +180,15 @@ + #define BGX_GMP_GMI_TXX_BURST 0x38228 + #define BGX_GMP_GMI_TXX_MIN_PKT 0x38240 + #define BGX_GMP_GMI_TXX_SGMII_CTL 0x38300 ++#define BGX_GMP_GMI_TXX_INT 0x38500 ++#define BGX_GMP_GMI_TXX_INT_W1S 0x38508 ++#define BGX_GMP_GMI_TXX_INT_ENA_W1C 0x38510 ++#define BGX_GMP_GMI_TXX_INT_ENA_W1S 0x38518 ++#define GMI_TXX_INT_PTP_LOST BIT_ULL(4) ++#define GMI_TXX_INT_LATE_COL BIT_ULL(3) ++#define GMI_TXX_INT_XSDEF BIT_ULL(2) ++#define GMI_TXX_INT_XSCOL BIT_ULL(1) ++#define GMI_TXX_INT_UNDFLW BIT_ULL(0) + + #define BGX_MSIX_VEC_0_29_ADDR 0x400000 /* +(0..29) << 4 */ + #define BGX_MSIX_VEC_0_29_CTL 0x400008 +diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c +index cce90b5925d9..70060c51854f 100644 +--- a/drivers/net/ethernet/davicom/dm9000.c ++++ b/drivers/net/ethernet/davicom/dm9000.c +@@ -1405,6 +1405,8 @@ static struct dm9000_plat_data *dm9000_parse_dt(struct device *dev) + mac_addr = of_get_mac_address(np); + if (!IS_ERR(mac_addr)) + ether_addr_copy(pdata->dev_addr, mac_addr); ++ else if (PTR_ERR(mac_addr) == -EPROBE_DEFER) ++ return ERR_CAST(mac_addr); + + return pdata; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c +index 1fe9f6050635..62673e27af0e 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c ++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c +@@ -2916,13 +2916,6 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) + else + return -EINVAL; + +- /* Tell the OS link is going down, the link will go back up when fw +- * says it is ready asynchronously +- */ +- ice_print_link_msg(vsi, false); +- netif_carrier_off(netdev); +- netif_tx_stop_all_queues(netdev); +- + /* Set the FC mode and only restart AN if link is up */ + status = ice_set_fc(pi, &aq_failures, link_up); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c +index 2739ed2a2911..841abe75652c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c +@@ -2257,7 +2257,9 @@ static int dr_ste_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, + struct mlx5dr_cmd_vport_cap *vport_cap; + struct mlx5dr_domain *dmn = sb->dmn; + struct mlx5dr_cmd_caps *caps; ++ u8 *bit_mask = sb->bit_mask; + u8 *tag = hw_ste->tag; ++ bool source_gvmi_set; + + DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn); + +@@ -2278,7 +2280,8 @@ static int dr_ste_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, + if (!vport_cap) + return -EINVAL; + +- if (vport_cap->vport_gvmi) ++ source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi); ++ if (vport_cap->vport_gvmi && source_gvmi_set) + MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi); + + misc->source_eswitch_owner_vhca_id = 0; +diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c +index a41a90c589db..1c9e70c8cc30 100644 +--- a/drivers/net/ethernet/micrel/ks8851_mll.c ++++ b/drivers/net/ethernet/micrel/ks8851_mll.c +@@ -156,24 +156,6 @@ static int msg_enable; + * chip is busy transferring packet data (RX/TX FIFO accesses). + */ + +-/** +- * ks_rdreg8 - read 8 bit register from device +- * @ks : The chip information +- * @offset: The register address +- * +- * Read a 8bit register from the chip, returning the result +- */ +-static u8 ks_rdreg8(struct ks_net *ks, int offset) +-{ +- u16 data; +- u8 shift_bit = offset & 0x03; +- u8 shift_data = (offset & 1) << 3; +- ks->cmd_reg_cache = (u16) offset | (u16)(BE0 << shift_bit); +- iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); +- data = ioread16(ks->hw_addr); +- return (u8)(data >> shift_data); +-} +- + /** + * ks_rdreg16 - read 16 bit register from device + * @ks : The chip information +@@ -184,27 +166,11 @@ static u8 ks_rdreg8(struct ks_net *ks, int offset) + + static u16 ks_rdreg16(struct ks_net *ks, int offset) + { +- ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02)); ++ ks->cmd_reg_cache = (u16)offset | ((BE3 | BE2) >> (offset & 0x02)); + iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); + return ioread16(ks->hw_addr); + } + +-/** +- * ks_wrreg8 - write 8bit register value to chip +- * @ks: The chip information +- * @offset: The register address +- * @value: The value to write +- * +- */ +-static void ks_wrreg8(struct ks_net *ks, int offset, u8 value) +-{ +- u8 shift_bit = (offset & 0x03); +- u16 value_write = (u16)(value << ((offset & 1) << 3)); +- ks->cmd_reg_cache = (u16)offset | (BE0 << shift_bit); +- iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); +- iowrite16(value_write, ks->hw_addr); +-} +- + /** + * ks_wrreg16 - write 16bit register value to chip + * @ks: The chip information +@@ -215,7 +181,7 @@ static void ks_wrreg8(struct ks_net *ks, int offset, u8 value) + + static void ks_wrreg16(struct ks_net *ks, int offset, u16 value) + { +- ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02)); ++ ks->cmd_reg_cache = (u16)offset | ((BE3 | BE2) >> (offset & 0x02)); + iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); + iowrite16(value, ks->hw_addr); + } +@@ -231,7 +197,7 @@ static inline void ks_inblk(struct ks_net *ks, u16 *wptr, u32 len) + { + len >>= 1; + while (len--) +- *wptr++ = (u16)ioread16(ks->hw_addr); ++ *wptr++ = be16_to_cpu(ioread16(ks->hw_addr)); + } + + /** +@@ -245,7 +211,7 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len) + { + len >>= 1; + while (len--) +- iowrite16(*wptr++, ks->hw_addr); ++ iowrite16(cpu_to_be16(*wptr++), ks->hw_addr); + } + + static void ks_disable_int(struct ks_net *ks) +@@ -324,8 +290,7 @@ static void ks_read_config(struct ks_net *ks) + u16 reg_data = 0; + + /* Regardless of bus width, 8 bit read should always work.*/ +- reg_data = ks_rdreg8(ks, KS_CCR) & 0x00FF; +- reg_data |= ks_rdreg8(ks, KS_CCR+1) << 8; ++ reg_data = ks_rdreg16(ks, KS_CCR); + + /* addr/data bus are multiplexed */ + ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED; +@@ -429,7 +394,7 @@ static inline void ks_read_qmu(struct ks_net *ks, u16 *buf, u32 len) + + /* 1. set sudo DMA mode */ + ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI); +- ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff); ++ ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); + + /* 2. read prepend data */ + /** +@@ -446,7 +411,7 @@ static inline void ks_read_qmu(struct ks_net *ks, u16 *buf, u32 len) + ks_inblk(ks, buf, ALIGN(len, 4)); + + /* 4. reset sudo DMA Mode */ +- ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr); ++ ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); + } + + /** +@@ -679,13 +644,13 @@ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) + ks->txh.txw[1] = cpu_to_le16(len); + + /* 1. set sudo-DMA mode */ +- ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff); ++ ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); + /* 2. write status/lenth info */ + ks_outblk(ks, ks->txh.txw, 4); + /* 3. write pkt data */ + ks_outblk(ks, (u16 *)pdata, ALIGN(len, 4)); + /* 4. reset sudo-DMA mode */ +- ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr); ++ ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); + /* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */ + ks_wrreg16(ks, KS_TXQCR, TXQCR_METFE); + /* 6. wait until TXQCR_METFE is auto-cleared */ +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 582176d869c3..89a6ae2b17e3 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -4208,6 +4208,8 @@ static void stmmac_init_fs(struct net_device *dev) + { + struct stmmac_priv *priv = netdev_priv(dev); + ++ rtnl_lock(); ++ + /* Create per netdev entries */ + priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir); + +@@ -4219,14 +4221,13 @@ static void stmmac_init_fs(struct net_device *dev) + debugfs_create_file("dma_cap", 0444, priv->dbgfs_dir, dev, + &stmmac_dma_cap_fops); + +- register_netdevice_notifier(&stmmac_notifier); ++ rtnl_unlock(); + } + + static void stmmac_exit_fs(struct net_device *dev) + { + struct stmmac_priv *priv = netdev_priv(dev); + +- unregister_netdevice_notifier(&stmmac_notifier); + debugfs_remove_recursive(priv->dbgfs_dir); + } + #endif /* CONFIG_DEBUG_FS */ +@@ -4728,14 +4729,14 @@ int stmmac_dvr_remove(struct device *dev) + + netdev_info(priv->dev, "%s: removing driver", __func__); + +-#ifdef CONFIG_DEBUG_FS +- stmmac_exit_fs(ndev); +-#endif + stmmac_stop_all_dma(priv); + + stmmac_mac_set(priv, priv->ioaddr, false); + netif_carrier_off(ndev); + unregister_netdev(ndev); ++#ifdef CONFIG_DEBUG_FS ++ stmmac_exit_fs(ndev); ++#endif + phylink_destroy(priv->phylink); + if (priv->plat->stmmac_rst) + reset_control_assert(priv->plat->stmmac_rst); +@@ -4955,6 +4956,7 @@ static int __init stmmac_init(void) + /* Create debugfs main directory if it doesn't exist yet */ + if (!stmmac_fs_dir) + stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); ++ register_netdevice_notifier(&stmmac_notifier); + #endif + + return 0; +@@ -4963,6 +4965,7 @@ static int __init stmmac_init(void) + static void __exit stmmac_exit(void) + { + #ifdef CONFIG_DEBUG_FS ++ unregister_netdevice_notifier(&stmmac_notifier); + debugfs_remove_recursive(stmmac_fs_dir); + #endif + } +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 7dacfd102a99..b8fe42f4b3c5 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -1161,8 +1161,8 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, + static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid, + unsigned int dword11, void *buffer, size_t buflen, u32 *result) + { ++ union nvme_result res = { 0 }; + struct nvme_command c; +- union nvme_result res; + int ret; + + memset(&c, 0, sizeof(c)); +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 570c75c92e29..cd64ddb129e5 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -2753,6 +2753,18 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) + (dmi_match(DMI_BOARD_NAME, "PRIME B350M-A") || + dmi_match(DMI_BOARD_NAME, "PRIME Z370-A"))) + return NVME_QUIRK_NO_APST; ++ } else if ((pdev->vendor == 0x144d && (pdev->device == 0xa801 || ++ pdev->device == 0xa808 || pdev->device == 0xa809)) || ++ (pdev->vendor == 0x1e0f && pdev->device == 0x0001)) { ++ /* ++ * Forcing to use host managed nvme power settings for ++ * lowest idle power with quick resume latency on ++ * Samsung and Toshiba SSDs based on suspend behavior ++ * on Coffee Lake board for LENOVO C640 ++ */ ++ if ((dmi_match(DMI_BOARD_VENDOR, "LENOVO")) && ++ dmi_match(DMI_BOARD_NAME, "LNVNB161216")) ++ return NVME_QUIRK_SIMPLE_SUSPEND; + } + + return 0; +@@ -3114,7 +3126,8 @@ static const struct pci_device_id nvme_id_table[] = { + .driver_data = NVME_QUIRK_NO_DEEPEST_PS | + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, +- { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001), ++ .driver_data = NVME_QUIRK_SINGLE_VECTOR }, + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) }, + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005), + .driver_data = NVME_QUIRK_SINGLE_VECTOR | +diff --git a/drivers/phy/motorola/phy-mapphone-mdm6600.c b/drivers/phy/motorola/phy-mapphone-mdm6600.c +index f20524f0c21d..94a34cf75eb3 100644 +--- a/drivers/phy/motorola/phy-mapphone-mdm6600.c ++++ b/drivers/phy/motorola/phy-mapphone-mdm6600.c +@@ -20,6 +20,7 @@ + + #define PHY_MDM6600_PHY_DELAY_MS 4000 /* PHY enable 2.2s to 3.5s */ + #define PHY_MDM6600_ENABLED_DELAY_MS 8000 /* 8s more total for MDM6600 */ ++#define PHY_MDM6600_WAKE_KICK_MS 600 /* time on after GPIO toggle */ + #define MDM6600_MODEM_IDLE_DELAY_MS 1000 /* modem after USB suspend */ + #define MDM6600_MODEM_WAKE_DELAY_MS 200 /* modem response after idle */ + +@@ -243,10 +244,24 @@ static irqreturn_t phy_mdm6600_wakeirq_thread(int irq, void *data) + { + struct phy_mdm6600 *ddata = data; + struct gpio_desc *mode_gpio1; ++ int error, wakeup; + + mode_gpio1 = ddata->mode_gpios->desc[PHY_MDM6600_MODE1]; +- dev_dbg(ddata->dev, "OOB wake on mode_gpio1: %i\n", +- gpiod_get_value(mode_gpio1)); ++ wakeup = gpiod_get_value(mode_gpio1); ++ if (!wakeup) ++ return IRQ_NONE; ++ ++ dev_dbg(ddata->dev, "OOB wake on mode_gpio1: %i\n", wakeup); ++ error = pm_runtime_get_sync(ddata->dev); ++ if (error < 0) { ++ pm_runtime_put_noidle(ddata->dev); ++ ++ return IRQ_NONE; ++ } ++ ++ /* Just wake-up and kick the autosuspend timer */ ++ pm_runtime_mark_last_busy(ddata->dev); ++ pm_runtime_put_autosuspend(ddata->dev); + + return IRQ_HANDLED; + } +@@ -496,8 +511,14 @@ static void phy_mdm6600_modem_wake(struct work_struct *work) + + ddata = container_of(work, struct phy_mdm6600, modem_wake_work.work); + phy_mdm6600_wake_modem(ddata); ++ ++ /* ++ * The modem does not always stay awake 1.2 seconds after toggling ++ * the wake GPIO, and sometimes it idles after about some 600 ms ++ * making writes time out. ++ */ + schedule_delayed_work(&ddata->modem_wake_work, +- msecs_to_jiffies(MDM6600_MODEM_IDLE_DELAY_MS)); ++ msecs_to_jiffies(PHY_MDM6600_WAKE_KICK_MS)); + } + + static int __maybe_unused phy_mdm6600_runtime_suspend(struct device *dev) +diff --git a/drivers/regulator/stm32-vrefbuf.c b/drivers/regulator/stm32-vrefbuf.c +index 8919a5130bec..25f24df9aa82 100644 +--- a/drivers/regulator/stm32-vrefbuf.c ++++ b/drivers/regulator/stm32-vrefbuf.c +@@ -88,7 +88,7 @@ static int stm32_vrefbuf_disable(struct regulator_dev *rdev) + } + + val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); +- val = (val & ~STM32_ENVR) | STM32_HIZ; ++ val &= ~STM32_ENVR; + writel_relaxed(val, priv->base + STM32_VREFBUF_CSR); + + pm_runtime_mark_last_busy(priv->dev); +@@ -175,6 +175,7 @@ static const struct regulator_desc stm32_vrefbuf_regu = { + .volt_table = stm32_vrefbuf_voltages, + .n_voltages = ARRAY_SIZE(stm32_vrefbuf_voltages), + .ops = &stm32_vrefbuf_volt_ops, ++ .off_on_delay = 1000, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }; +diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c +index 2a3f874a21d5..9cebff8e8d74 100644 +--- a/drivers/s390/cio/blacklist.c ++++ b/drivers/s390/cio/blacklist.c +@@ -303,8 +303,10 @@ static void * + cio_ignore_proc_seq_next(struct seq_file *s, void *it, loff_t *offset) + { + struct ccwdev_iter *iter; ++ loff_t p = *offset; + +- if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) ++ (*offset)++; ++ if (p >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) + return NULL; + iter = it; + if (iter->devno == __MAX_SUBCHANNEL) { +@@ -314,7 +316,6 @@ cio_ignore_proc_seq_next(struct seq_file *s, void *it, loff_t *offset) + return NULL; + } else + iter->devno++; +- (*offset)++; + return iter; + } + +diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c +index cd164886132f..ee0b3c586211 100644 +--- a/drivers/s390/cio/qdio_setup.c ++++ b/drivers/s390/cio/qdio_setup.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + + #include "cio.h" +@@ -207,7 +208,7 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, + + /* fill in sl */ + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) +- q->sl->element[j].sbal = (unsigned long)q->sbal[j]; ++ q->sl->element[j].sbal = virt_to_phys(q->sbal[j]); + } + + static void setup_queues(struct qdio_irq *irq_ptr, +diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c +index 23852888eb2c..b727d1e34523 100644 +--- a/drivers/s390/net/qeth_core_main.c ++++ b/drivers/s390/net/qeth_core_main.c +@@ -4716,10 +4716,10 @@ static void qeth_qdio_establish_cq(struct qeth_card *card, + if (card->options.cq == QETH_CQ_ENABLED) { + int offset = QDIO_MAX_BUFFERS_PER_Q * + (card->qdio.no_in_queues - 1); +- for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) { +- in_sbal_ptrs[offset + i] = (struct qdio_buffer *) +- virt_to_phys(card->qdio.c_q->bufs[i].buffer); +- } ++ ++ for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) ++ in_sbal_ptrs[offset + i] = ++ card->qdio.c_q->bufs[i].buffer; + + queue_start_poll[card->qdio.no_in_queues - 1] = NULL; + } +@@ -4753,10 +4753,9 @@ static int qeth_qdio_establish(struct qeth_card *card) + rc = -ENOMEM; + goto out_free_qib_param; + } +- for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) { +- in_sbal_ptrs[i] = (struct qdio_buffer *) +- virt_to_phys(card->qdio.in_q->bufs[i].buffer); +- } ++ ++ for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) ++ in_sbal_ptrs[i] = card->qdio.in_q->bufs[i].buffer; + + queue_start_poll = kcalloc(card->qdio.no_in_queues, sizeof(void *), + GFP_KERNEL); +@@ -4777,11 +4776,11 @@ static int qeth_qdio_establish(struct qeth_card *card) + rc = -ENOMEM; + goto out_free_queue_start_poll; + } ++ + for (i = 0, k = 0; i < card->qdio.no_out_queues; ++i) +- for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j, ++k) { +- out_sbal_ptrs[k] = (struct qdio_buffer *)virt_to_phys( +- card->qdio.out_qs[i]->bufs[j]->buffer); +- } ++ for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++, k++) ++ out_sbal_ptrs[k] = ++ card->qdio.out_qs[i]->bufs[j]->buffer; + + memset(&init_data, 0, sizeof(struct qdio_initialize)); + init_data.cdev = CARD_DDEV(card); +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 46bc062d873e..d86838801805 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -594,7 +594,8 @@ retry_alloc: + + fusion->io_request_frames = + dma_pool_alloc(fusion->io_request_frames_pool, +- GFP_KERNEL, &fusion->io_request_frames_phys); ++ GFP_KERNEL | __GFP_NOWARN, ++ &fusion->io_request_frames_phys); + if (!fusion->io_request_frames) { + if (instance->max_fw_cmds >= (MEGASAS_REDUCE_QD_COUNT * 2)) { + instance->max_fw_cmds -= MEGASAS_REDUCE_QD_COUNT; +@@ -632,7 +633,7 @@ retry_alloc: + + fusion->io_request_frames = + dma_pool_alloc(fusion->io_request_frames_pool, +- GFP_KERNEL, ++ GFP_KERNEL | __GFP_NOWARN, + &fusion->io_request_frames_phys); + + if (!fusion->io_request_frames) { +diff --git a/drivers/soc/imx/soc-imx-scu.c b/drivers/soc/imx/soc-imx-scu.c +index c68882eb80f7..f638e7790470 100644 +--- a/drivers/soc/imx/soc-imx-scu.c ++++ b/drivers/soc/imx/soc-imx-scu.c +@@ -25,7 +25,7 @@ struct imx_sc_msg_misc_get_soc_id { + u32 id; + } resp; + } data; +-} __packed; ++} __packed __aligned(4); + + struct imx_sc_msg_misc_get_soc_uid { + struct imx_sc_rpc_msg hdr; +diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c +index fd8007ebb145..13def7f78b9e 100644 +--- a/drivers/spi/atmel-quadspi.c ++++ b/drivers/spi/atmel-quadspi.c +@@ -149,6 +149,7 @@ struct atmel_qspi { + struct clk *qspick; + struct platform_device *pdev; + const struct atmel_qspi_caps *caps; ++ resource_size_t mmap_size; + u32 pending; + u32 mr; + u32 scr; +@@ -329,6 +330,14 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) + u32 sr, offset; + int err; + ++ /* ++ * Check if the address exceeds the MMIO window size. An improvement ++ * would be to add support for regular SPI mode and fall back to it ++ * when the flash memories overrun the controller's memory space. ++ */ ++ if (op->addr.val + op->data.nbytes > aq->mmap_size) ++ return -ENOTSUPP; ++ + err = atmel_qspi_set_cfg(aq, op, &offset); + if (err) + return err; +@@ -480,6 +489,8 @@ static int atmel_qspi_probe(struct platform_device *pdev) + goto exit; + } + ++ aq->mmap_size = resource_size(res); ++ + /* Get the peripheral clock */ + aq->pclk = devm_clk_get(&pdev->dev, "pclk"); + if (IS_ERR(aq->pclk)) +diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c +index c6836a931dbf..36f7eb8ab2df 100644 +--- a/drivers/spi/spi-bcm63xx-hsspi.c ++++ b/drivers/spi/spi-bcm63xx-hsspi.c +@@ -367,7 +367,6 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) + goto out_disable_clk; + + rate = clk_get_rate(pll_clk); +- clk_disable_unprepare(pll_clk); + if (!rate) { + ret = -EINVAL; + goto out_disable_pll_clk; +diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c +index 3ea9d8a3e6e8..ab2c3848f5bf 100644 +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -394,6 +394,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + else + retval = get_user(tmp, (u32 __user *)arg); + if (retval == 0) { ++ struct spi_controller *ctlr = spi->controller; + u32 save = spi->mode; + + if (tmp & ~SPI_MODE_MASK) { +@@ -401,6 +402,10 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + break; + } + ++ if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && ++ ctlr->cs_gpiods[spi->chip_select]) ++ tmp |= SPI_CS_HIGH; ++ + tmp |= spi->mode & ~SPI_MODE_MASK; + spi->mode = (u16)tmp; + retval = spi_setup(spi); +diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c +index 6d9d41170832..32e5966ba5c5 100644 +--- a/drivers/staging/media/hantro/hantro_drv.c ++++ b/drivers/staging/media/hantro/hantro_drv.c +@@ -553,13 +553,13 @@ static int hantro_attach_func(struct hantro_dev *vpu, + goto err_rel_entity1; + + /* Connect the three entities */ +- ret = media_create_pad_link(&func->vdev.entity, 0, &func->proc, 1, ++ ret = media_create_pad_link(&func->vdev.entity, 0, &func->proc, 0, + MEDIA_LNK_FL_IMMUTABLE | + MEDIA_LNK_FL_ENABLED); + if (ret) + goto err_rel_entity2; + +- ret = media_create_pad_link(&func->proc, 0, &func->sink, 0, ++ ret = media_create_pad_link(&func->proc, 1, &func->sink, 0, + MEDIA_LNK_FL_IMMUTABLE | + MEDIA_LNK_FL_ENABLED); + if (ret) +diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c +index a8b4d0c5ab7e..032f3264fba1 100644 +--- a/drivers/staging/speakup/selection.c ++++ b/drivers/staging/speakup/selection.c +@@ -51,9 +51,7 @@ static void __speakup_set_selection(struct work_struct *work) + goto unref; + } + +- console_lock(); + set_selection_kernel(&sel, tty); +- console_unlock(); + + unref: + tty_kref_put(tty); +diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c +index 597eb9d16f21..e1268646ee56 100644 +--- a/drivers/tty/serial/8250/8250_exar.c ++++ b/drivers/tty/serial/8250/8250_exar.c +@@ -25,6 +25,14 @@ + + #include "8250.h" + ++#define PCI_DEVICE_ID_ACCES_COM_2S 0x1052 ++#define PCI_DEVICE_ID_ACCES_COM_4S 0x105d ++#define PCI_DEVICE_ID_ACCES_COM_8S 0x106c ++#define PCI_DEVICE_ID_ACCES_COM232_8 0x10a8 ++#define PCI_DEVICE_ID_ACCES_COM_2SM 0x10d2 ++#define PCI_DEVICE_ID_ACCES_COM_4SM 0x10db ++#define PCI_DEVICE_ID_ACCES_COM_8SM 0x10ea ++ + #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 + #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 + #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a +@@ -658,6 +666,22 @@ static int __maybe_unused exar_resume(struct device *dev) + + static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume); + ++static const struct exar8250_board acces_com_2x = { ++ .num_ports = 2, ++ .setup = pci_xr17c154_setup, ++}; ++ ++static const struct exar8250_board acces_com_4x = { ++ .num_ports = 4, ++ .setup = pci_xr17c154_setup, ++}; ++ ++static const struct exar8250_board acces_com_8x = { ++ .num_ports = 8, ++ .setup = pci_xr17c154_setup, ++}; ++ ++ + static const struct exar8250_board pbn_fastcom335_2 = { + .num_ports = 2, + .setup = pci_fastcom335_setup, +@@ -726,6 +750,15 @@ static const struct exar8250_board pbn_exar_XR17V8358 = { + } + + static const struct pci_device_id exar_pci_tbl[] = { ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_2S, acces_com_2x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_4S, acces_com_4x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_8S, acces_com_8x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM232_8, acces_com_8x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_2SM, acces_com_2x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_4SM, acces_com_4x), ++ EXAR_DEVICE(ACCESSIO, ACCES_COM_8SM, acces_com_8x), ++ ++ + CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect), + CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect), + CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect), +diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c +index 3bdd56a1021b..ea12f10610b6 100644 +--- a/drivers/tty/serial/ar933x_uart.c ++++ b/drivers/tty/serial/ar933x_uart.c +@@ -286,6 +286,10 @@ static void ar933x_uart_set_termios(struct uart_port *port, + ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, + AR933X_UART_CS_HOST_INT_EN); + ++ /* enable RX and TX ready overide */ ++ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, ++ AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE); ++ + /* reenable the UART */ + ar933x_uart_rmw(up, AR933X_UART_CS_REG, + AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S, +@@ -418,6 +422,10 @@ static int ar933x_uart_startup(struct uart_port *port) + ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, + AR933X_UART_CS_HOST_INT_EN); + ++ /* enable RX and TX ready overide */ ++ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, ++ AR933X_UART_CS_TX_READY_ORIDE | AR933X_UART_CS_RX_READY_ORIDE); ++ + /* Enable RX interrupts */ + up->ier = AR933X_UART_INT_RX_VALID; + ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); +diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c +index 3f64b08f50ef..d2fc050a3445 100644 +--- a/drivers/tty/serial/fsl_lpuart.c ++++ b/drivers/tty/serial/fsl_lpuart.c +@@ -268,6 +268,7 @@ struct lpuart_port { + int rx_dma_rng_buf_len; + unsigned int dma_tx_nents; + wait_queue_head_t dma_wait; ++ bool id_allocated; + }; + + struct lpuart_soc_data { +@@ -2382,19 +2383,6 @@ static int lpuart_probe(struct platform_device *pdev) + if (!sport) + return -ENOMEM; + +- ret = of_alias_get_id(np, "serial"); +- if (ret < 0) { +- ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL); +- if (ret < 0) { +- dev_err(&pdev->dev, "port line is full, add device failed\n"); +- return ret; +- } +- } +- if (ret >= ARRAY_SIZE(lpuart_ports)) { +- dev_err(&pdev->dev, "serial%d out of range\n", ret); +- return -EINVAL; +- } +- sport->port.line = ret; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + sport->port.membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(sport->port.membase)) +@@ -2435,9 +2423,25 @@ static int lpuart_probe(struct platform_device *pdev) + } + } + ++ ret = of_alias_get_id(np, "serial"); ++ if (ret < 0) { ++ ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "port line is full, add device failed\n"); ++ return ret; ++ } ++ sport->id_allocated = true; ++ } ++ if (ret >= ARRAY_SIZE(lpuart_ports)) { ++ dev_err(&pdev->dev, "serial%d out of range\n", ret); ++ ret = -EINVAL; ++ goto failed_out_of_range; ++ } ++ sport->port.line = ret; ++ + ret = lpuart_enable_clks(sport); + if (ret) +- return ret; ++ goto failed_clock_enable; + sport->port.uartclk = lpuart_get_baud_clk_rate(sport); + + lpuart_ports[sport->port.line] = sport; +@@ -2487,6 +2491,10 @@ static int lpuart_probe(struct platform_device *pdev) + failed_attach_port: + failed_irq_request: + lpuart_disable_clks(sport); ++failed_clock_enable: ++failed_out_of_range: ++ if (sport->id_allocated) ++ ida_simple_remove(&fsl_lpuart_ida, sport->port.line); + return ret; + } + +@@ -2496,7 +2504,8 @@ static int lpuart_remove(struct platform_device *pdev) + + uart_remove_one_port(&lpuart_reg, &sport->port); + +- ida_simple_remove(&fsl_lpuart_ida, sport->port.line); ++ if (sport->id_allocated) ++ ida_simple_remove(&fsl_lpuart_ida, sport->port.line); + + lpuart_disable_clks(sport); + +diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c +index c12a12556339..4e9a590712cb 100644 +--- a/drivers/tty/serial/mvebu-uart.c ++++ b/drivers/tty/serial/mvebu-uart.c +@@ -851,7 +851,7 @@ static int mvebu_uart_probe(struct platform_device *pdev) + + port->membase = devm_ioremap_resource(&pdev->dev, reg); + if (IS_ERR(port->membase)) +- return -PTR_ERR(port->membase); ++ return PTR_ERR(port->membase); + + mvuart = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_uart), + GFP_KERNEL); +diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c +index 44d974d4159f..d7d2e4b844bc 100644 +--- a/drivers/tty/vt/selection.c ++++ b/drivers/tty/vt/selection.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -45,6 +46,7 @@ static volatile int sel_start = -1; /* cleared by clear_selection */ + static int sel_end; + static int sel_buffer_lth; + static char *sel_buffer; ++static DEFINE_MUTEX(sel_lock); + + /* clear_selection, highlight and highlight_pointer can be called + from interrupt (via scrollback/front) */ +@@ -179,14 +181,14 @@ int set_selection_user(const struct tiocl_selection __user *sel, + return set_selection_kernel(&v, tty); + } + +-int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) ++static int __set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) + { + struct vc_data *vc = vc_cons[fg_console].d; + int new_sel_start, new_sel_end, spc; + char *bp, *obp; + int i, ps, pe, multiplier; + u32 c; +- int mode; ++ int mode, ret = 0; + + poke_blanked_console(); + +@@ -334,7 +336,21 @@ int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) + } + } + sel_buffer_lth = bp - sel_buffer; +- return 0; ++ ++ return ret; ++} ++ ++int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) ++{ ++ int ret; ++ ++ mutex_lock(&sel_lock); ++ console_lock(); ++ ret = __set_selection_kernel(v, tty); ++ console_unlock(); ++ mutex_unlock(&sel_lock); ++ ++ return ret; + } + EXPORT_SYMBOL_GPL(set_selection_kernel); + +@@ -364,6 +380,7 @@ int paste_selection(struct tty_struct *tty) + tty_buffer_lock_exclusive(&vc->port); + + add_wait_queue(&vc->paste_wait, &wait); ++ mutex_lock(&sel_lock); + while (sel_buffer && sel_buffer_lth > pasted) { + set_current_state(TASK_INTERRUPTIBLE); + if (signal_pending(current)) { +@@ -371,7 +388,9 @@ int paste_selection(struct tty_struct *tty) + break; + } + if (tty_throttled(tty)) { ++ mutex_unlock(&sel_lock); + schedule(); ++ mutex_lock(&sel_lock); + continue; + } + __set_current_state(TASK_RUNNING); +@@ -380,6 +399,7 @@ int paste_selection(struct tty_struct *tty) + count); + pasted += count; + } ++ mutex_unlock(&sel_lock); + remove_wait_queue(&vc->paste_wait, &wait); + __set_current_state(TASK_RUNNING); + +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index 3b4ccc2a30c1..e9e27ba69d5d 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -3046,10 +3046,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) + switch (type) + { + case TIOCL_SETSEL: +- console_lock(); + ret = set_selection_user((struct tiocl_selection + __user *)(p+1), tty); +- console_unlock(); + break; + case TIOCL_PASTESEL: + ret = paste_selection(tty); +diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c +index 02f6ca2cb1ba..f624cc87cbab 100644 +--- a/drivers/usb/cdns3/gadget.c ++++ b/drivers/usb/cdns3/gadget.c +@@ -2107,7 +2107,7 @@ found: + /* Update ring only if removed request is on pending_req_list list */ + if (req_on_hw_ring) { + link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma + +- (priv_req->start_trb * TRB_SIZE)); ++ ((priv_req->end_trb + 1) * TRB_SIZE)); + link_trb->control = (link_trb->control & TRB_CYCLE) | + TRB_TYPE(TRB_LINK) | TRB_CHAIN; + +@@ -2152,11 +2152,21 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep) + { + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + struct usb_request *request; ++ struct cdns3_request *priv_req; ++ struct cdns3_trb *trb = NULL; + int ret; + int val; + + trace_cdns3_halt(priv_ep, 0, 0); + ++ request = cdns3_next_request(&priv_ep->pending_req_list); ++ if (request) { ++ priv_req = to_cdns3_request(request); ++ trb = priv_req->trb; ++ if (trb) ++ trb->control = trb->control ^ TRB_CYCLE; ++ } ++ + writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); + + /* wait for EPRST cleared */ +@@ -2167,10 +2177,11 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep) + + priv_ep->flags &= ~(EP_STALLED | EP_STALL_PENDING); + +- request = cdns3_next_request(&priv_ep->pending_req_list); +- +- if (request) ++ if (request) { ++ if (trb) ++ trb->control = trb->control ^ TRB_CYCLE; + cdns3_rearm_transfer(priv_ep, 1); ++ } + + cdns3_start_all_request(priv_dev, priv_ep); + return ret; +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index f381faa10f15..243577656177 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -987,13 +987,17 @@ int usb_remove_device(struct usb_device *udev) + { + struct usb_hub *hub; + struct usb_interface *intf; ++ int ret; + + if (!udev->parent) /* Can't remove a root hub */ + return -EINVAL; + hub = usb_hub_to_struct_hub(udev->parent); + intf = to_usb_interface(hub->intfdev); + +- usb_autopm_get_interface(intf); ++ ret = usb_autopm_get_interface(intf); ++ if (ret < 0) ++ return ret; ++ + set_bit(udev->portnum, hub->removed_bits); + hub_port_logical_disconnect(hub, udev->portnum); + usb_autopm_put_interface(intf); +@@ -1865,7 +1869,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) + + if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) { + hub->quirk_disable_autosuspend = 1; +- usb_autopm_get_interface(intf); ++ usb_autopm_get_interface_no_resume(intf); + } + + if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) +diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c +index bbbb35fa639f..235a7c645503 100644 +--- a/drivers/usb/core/port.c ++++ b/drivers/usb/core/port.c +@@ -213,7 +213,10 @@ static int usb_port_runtime_resume(struct device *dev) + if (!port_dev->is_superspeed && peer) + pm_runtime_get_sync(&peer->dev); + +- usb_autopm_get_interface(intf); ++ retval = usb_autopm_get_interface(intf); ++ if (retval < 0) ++ return retval; ++ + retval = usb_hub_set_port_power(hdev, hub, port1, true); + msleep(hub_power_on_good_delay(hub)); + if (udev && !retval) { +@@ -266,7 +269,10 @@ static int usb_port_runtime_suspend(struct device *dev) + if (usb_port_block_power_off) + return -EBUSY; + +- usb_autopm_get_interface(intf); ++ retval = usb_autopm_get_interface(intf); ++ if (retval < 0) ++ return retval; ++ + retval = usb_hub_set_port_power(hdev, hub, port1, false); + usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION); + if (!port_dev->is_superspeed) +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 2b24336a72e5..2dac3e7cdd97 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -231,6 +231,9 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Logitech PTZ Pro Camera */ + { USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT }, + ++ /* Logitech Screen Share */ ++ { USB_DEVICE(0x046d, 0x086c), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* Logitech Quickcam Fusion */ + { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index e0cb1c2d5675..6ac02ba5e4a1 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1068,7 +1068,14 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, + unsigned int rem = length % maxp; + unsigned chain = true; + +- if (sg_is_last(s)) ++ /* ++ * IOMMU driver is coalescing the list of sgs which shares a ++ * page boundary into one and giving it to USB driver. With ++ * this the number of sgs mapped is not equal to the number of ++ * sgs passed. So mark the chain bit to false if it isthe last ++ * mapped sg. ++ */ ++ if (i == remaining - 1) + chain = false; + + if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) { +diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c +index 0d45d7a4f949..d7871636fced 100644 +--- a/drivers/usb/gadget/composite.c ++++ b/drivers/usb/gadget/composite.c +@@ -438,9 +438,13 @@ static u8 encode_bMaxPower(enum usb_device_speed speed, + if (!val) + return 0; + if (speed < USB_SPEED_SUPER) +- return DIV_ROUND_UP(val, 2); ++ return min(val, 500U) / 2; + else +- return DIV_ROUND_UP(val, 8); ++ /* ++ * USB 3.x supports up to 900mA, but since 900 isn't divisible ++ * by 8 the integral division will effectively cap to 896mA. ++ */ ++ return min(val, 900U) / 8; + } + + static int config_buf(struct usb_configuration *config, +@@ -852,6 +856,10 @@ static int set_config(struct usb_composite_dev *cdev, + + /* when we return, be sure our power usage is valid */ + power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; ++ if (gadget->speed < USB_SPEED_SUPER) ++ power = min(power, 500U); ++ else ++ power = min(power, 900U); + done: + usb_gadget_vbus_draw(gadget, power); + if (result >= 0 && cdev->delayed_status) +@@ -2278,7 +2286,7 @@ void composite_resume(struct usb_gadget *gadget) + { + struct usb_composite_dev *cdev = get_gadget_data(gadget); + struct usb_function *f; +- u16 maxpower; ++ unsigned maxpower; + + /* REVISIT: should we have config level + * suspend/resume callbacks? +@@ -2292,10 +2300,14 @@ void composite_resume(struct usb_gadget *gadget) + f->resume(f); + } + +- maxpower = cdev->config->MaxPower; ++ maxpower = cdev->config->MaxPower ? ++ cdev->config->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; ++ if (gadget->speed < USB_SPEED_SUPER) ++ maxpower = min(maxpower, 500U); ++ else ++ maxpower = min(maxpower, 900U); + +- usb_gadget_vbus_draw(gadget, maxpower ? +- maxpower : CONFIG_USB_GADGET_VBUS_DRAW); ++ usb_gadget_vbus_draw(gadget, maxpower); + } + + cdev->suspended = 0; +diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c +index ced2581cf99f..a9a711e04614 100644 +--- a/drivers/usb/gadget/function/f_fs.c ++++ b/drivers/usb/gadget/function/f_fs.c +@@ -1162,18 +1162,19 @@ static int ffs_aio_cancel(struct kiocb *kiocb) + { + struct ffs_io_data *io_data = kiocb->private; + struct ffs_epfile *epfile = kiocb->ki_filp->private_data; ++ unsigned long flags; + int value; + + ENTER(); + +- spin_lock_irq(&epfile->ffs->eps_lock); ++ spin_lock_irqsave(&epfile->ffs->eps_lock, flags); + + if (likely(io_data && io_data->ep && io_data->req)) + value = usb_ep_dequeue(io_data->ep, io_data->req); + else + value = -EINVAL; + +- spin_unlock_irq(&epfile->ffs->eps_lock); ++ spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags); + + return value; + } +diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c +index bb1e2e1d0076..038c445a4e9b 100644 +--- a/drivers/usb/gadget/function/u_serial.c ++++ b/drivers/usb/gadget/function/u_serial.c +@@ -560,8 +560,10 @@ static int gs_start_io(struct gs_port *port) + port->n_read = 0; + started = gs_start_rx(port); + +- /* unblock any pending writes into our circular buffer */ + if (started) { ++ gs_start_tx(port); ++ /* Unblock any pending writes into our circular buffer, in case ++ * we didn't in gs_start_tx() */ + tty_wakeup(port->port.tty); + } else { + gs_free_requests(ep, head, &port->read_allocated); +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 1cd9b6305b06..1880f3e13f57 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1258,6 +1258,12 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, + USB_SC_RBC, USB_PR_BULK, NULL, + 0 ), + ++UNUSUAL_DEV(0x090c, 0x1000, 0x1100, 0x1100, ++ "Samsung", ++ "Flash Drive FIT", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_MAX_SECTORS_64), ++ + /* aeb */ + UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, + "Feiya", +diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c +index c6b3bdbbdbc9..bfaa9ec4bc1f 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -1316,6 +1316,9 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font) + static int vgacon_resize(struct vc_data *c, unsigned int width, + unsigned int height, unsigned int user) + { ++ if ((width << 1) * height > vga_vram_size) ++ return -EINVAL; ++ + if (width % 2 || width > screen_info.orig_video_cols || + height > (screen_info.orig_video_lines * vga_default_font_height)/ + c->vc_font.height) +diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c +index e149e66a6ea9..e92f38fcb7a4 100644 +--- a/drivers/watchdog/da9062_wdt.c ++++ b/drivers/watchdog/da9062_wdt.c +@@ -94,13 +94,6 @@ static int da9062_wdt_stop(struct watchdog_device *wdd) + struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd); + int ret; + +- ret = da9062_reset_watchdog_timer(wdt); +- if (ret) { +- dev_err(wdt->hw->dev, "Failed to ping the watchdog (err = %d)\n", +- ret); +- return ret; +- } +- + ret = regmap_update_bits(wdt->hw->regmap, + DA9062AA_CONTROL_D, + DA9062AA_TWDSCALE_MASK, +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 50feb01f27f3..c056d12cbb3c 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -8426,6 +8426,7 @@ static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode, + { + struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); + struct btrfs_io_bio *orig_io_bio = btrfs_io_bio(dip->orig_bio); ++ u16 csum_size; + blk_status_t ret; + + /* +@@ -8445,7 +8446,8 @@ static inline blk_status_t btrfs_lookup_and_bind_dio_csum(struct inode *inode, + + file_offset -= dip->logical_offset; + file_offset >>= inode->i_sb->s_blocksize_bits; +- io_bio->csum = (u8 *)(((u32 *)orig_io_bio->csum) + file_offset); ++ csum_size = btrfs_super_csum_size(btrfs_sb(inode->i_sb)->super_copy); ++ io_bio->csum = orig_io_bio->csum + csum_size * file_offset; + + return 0; + } +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 53611d7e9d28..f9cbdfc1591b 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -1229,6 +1229,7 @@ struct cifs_fid { + __u64 volatile_fid; /* volatile file id for smb2 */ + __u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for smb2 */ + __u8 create_guid[16]; ++ __u32 access; + struct cifs_pending_open *pending_open; + unsigned int epoch; + #ifdef CONFIG_CIFS_DEBUG2 +@@ -1700,6 +1701,12 @@ static inline bool is_retryable_error(int error) + return false; + } + ++ ++/* cifs_get_writable_file() flags */ ++#define FIND_WR_ANY 0 ++#define FIND_WR_FSUID_ONLY 1 ++#define FIND_WR_WITH_DELETE 2 ++ + #define MID_FREE 0 + #define MID_REQUEST_ALLOCATED 1 + #define MID_REQUEST_SUBMITTED 2 +diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h +index fe597d3d5208..f18da99a6b55 100644 +--- a/fs/cifs/cifsproto.h ++++ b/fs/cifs/cifsproto.h +@@ -133,11 +133,12 @@ extern bool backup_cred(struct cifs_sb_info *); + extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); + extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, + unsigned int bytes_written); +-extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); ++extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int); + extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, +- bool fsuid_only, ++ int flags, + struct cifsFileInfo **ret_file); + extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name, ++ int flags, + struct cifsFileInfo **ret_file); + extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); + extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c +index 4f554f019a98..c8494fa5e19d 100644 +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -1489,6 +1489,7 @@ openRetry: + *oplock = rsp->OplockLevel; + /* cifs fid stays in le */ + oparms->fid->netfid = rsp->Fid; ++ oparms->fid->access = desired_access; + + /* Let caller know file was created so we can set the mode. */ + /* Do we care about the CreateAction in any other cases? */ +@@ -2112,7 +2113,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata) + wdata2->tailsz = tailsz; + wdata2->bytes = cur_len; + +- rc = cifs_get_writable_file(CIFS_I(inode), false, ++ rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY, + &wdata2->cfile); + if (!wdata2->cfile) { + cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n", +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index 969543034b4d..0dbe47e89720 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -1916,7 +1916,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, + + /* Return -EBADF if no handle is found and general rc otherwise */ + int +-cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only, ++cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, + struct cifsFileInfo **ret_file) + { + struct cifsFileInfo *open_file, *inv_file = NULL; +@@ -1924,7 +1924,8 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only, + bool any_available = false; + int rc = -EBADF; + unsigned int refind = 0; +- ++ bool fsuid_only = flags & FIND_WR_FSUID_ONLY; ++ bool with_delete = flags & FIND_WR_WITH_DELETE; + *ret_file = NULL; + + /* +@@ -1956,6 +1957,8 @@ refind_writable: + continue; + if (fsuid_only && !uid_eq(open_file->uid, current_fsuid())) + continue; ++ if (with_delete && !(open_file->fid.access & DELETE)) ++ continue; + if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { + if (!open_file->invalidHandle) { + /* found a good writable file */ +@@ -2003,12 +2006,12 @@ refind_writable: + } + + struct cifsFileInfo * +-find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only) ++find_writable_file(struct cifsInodeInfo *cifs_inode, int flags) + { + struct cifsFileInfo *cfile; + int rc; + +- rc = cifs_get_writable_file(cifs_inode, fsuid_only, &cfile); ++ rc = cifs_get_writable_file(cifs_inode, flags, &cfile); + if (rc) + cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc); + +@@ -2017,6 +2020,7 @@ find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only) + + int + cifs_get_writable_path(struct cifs_tcon *tcon, const char *name, ++ int flags, + struct cifsFileInfo **ret_file) + { + struct list_head *tmp; +@@ -2043,7 +2047,7 @@ cifs_get_writable_path(struct cifs_tcon *tcon, const char *name, + kfree(full_path); + cinode = CIFS_I(d_inode(cfile->dentry)); + spin_unlock(&tcon->open_file_lock); +- return cifs_get_writable_file(cinode, 0, ret_file); ++ return cifs_get_writable_file(cinode, flags, ret_file); + } + + spin_unlock(&tcon->open_file_lock); +@@ -2120,7 +2124,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) + if (mapping->host->i_size - offset < (loff_t)to) + to = (unsigned)(mapping->host->i_size - offset); + +- rc = cifs_get_writable_file(CIFS_I(mapping->host), false, &open_file); ++ rc = cifs_get_writable_file(CIFS_I(mapping->host), FIND_WR_ANY, ++ &open_file); + if (!rc) { + bytes_written = cifs_write(open_file, open_file->pid, + write_data, to - from, &offset); +@@ -2313,7 +2318,7 @@ retry: + if (cfile) + cifsFileInfo_put(cfile); + +- rc = cifs_get_writable_file(CIFS_I(inode), false, &cfile); ++ rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY, &cfile); + + /* in case of an error store it to return later */ + if (rc) +diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c +index aafcd79c4772..7c5e983fe385 100644 +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -2011,6 +2011,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry) + struct inode *inode = d_inode(dentry); + struct super_block *sb = dentry->d_sb; + char *full_path = NULL; ++ int count = 0; + + if (inode == NULL) + return -ENOENT; +@@ -2032,15 +2033,18 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry) + full_path, inode, inode->i_count.counter, + dentry, cifs_get_time(dentry), jiffies); + ++again: + if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) + rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); + else + rc = cifs_get_inode_info(&inode, full_path, NULL, sb, + xid, NULL); +- ++ if (rc == -EAGAIN && count++ < 10) ++ goto again; + out: + kfree(full_path); + free_xid(xid); ++ + return rc; + } + +@@ -2216,7 +2220,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, + * writebehind data than the SMB timeout for the SetPathInfo + * request would allow + */ +- open_file = find_writable_file(cifsInode, true); ++ open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY); + if (open_file) { + tcon = tlink_tcon(open_file->tlink); + server = tcon->ses->server; +@@ -2366,7 +2370,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) + args->ctime = NO_CHANGE_64; + + args->device = 0; +- open_file = find_writable_file(cifsInode, true); ++ open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY); + if (open_file) { + u16 nfid = open_file->fid.netfid; + u32 npid = open_file->pid; +@@ -2469,7 +2473,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) + rc = 0; + + if (attrs->ia_valid & ATTR_MTIME) { +- rc = cifs_get_writable_file(cifsInode, false, &wfile); ++ rc = cifs_get_writable_file(cifsInode, FIND_WR_ANY, &wfile); + if (!rc) { + tcon = tlink_tcon(wfile->tlink); + rc = tcon->ses->server->ops->flush(xid, tcon, &wfile->fid); +diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c +index 514810694c0f..195766221a7a 100644 +--- a/fs/cifs/smb1ops.c ++++ b/fs/cifs/smb1ops.c +@@ -767,7 +767,7 @@ smb_set_file_info(struct inode *inode, const char *full_path, + struct cifs_tcon *tcon; + + /* if the file is already open for write, just use that fileid */ +- open_file = find_writable_file(cinode, true); ++ open_file = find_writable_file(cinode, FIND_WR_FSUID_ONLY); + if (open_file) { + fid.netfid = open_file->fid.netfid; + netpid = open_file->pid; +diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c +index 4121ac1163ca..f2a6f7f28340 100644 +--- a/fs/cifs/smb2inode.c ++++ b/fs/cifs/smb2inode.c +@@ -525,7 +525,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name, + cifs_i = CIFS_I(inode); + dosattrs = cifs_i->cifsAttrs | ATTR_READONLY; + data.Attributes = cpu_to_le32(dosattrs); +- cifs_get_writable_path(tcon, name, &cfile); ++ cifs_get_writable_path(tcon, name, FIND_WR_ANY, &cfile); + tmprc = smb2_compound_op(xid, tcon, cifs_sb, name, + FILE_WRITE_ATTRIBUTES, FILE_CREATE, + CREATE_NOT_FILE, ACL_NO_MODE, +@@ -581,7 +581,7 @@ smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, + { + struct cifsFileInfo *cfile; + +- cifs_get_writable_path(tcon, from_name, &cfile); ++ cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile); + + return smb2_set_path_attr(xid, tcon, from_name, to_name, + cifs_sb, DELETE, SMB2_OP_RENAME, cfile); +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index b75d208d4b2b..99420608d2ec 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -1338,6 +1338,7 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) + + cfile->fid.persistent_fid = fid->persistent_fid; + cfile->fid.volatile_fid = fid->volatile_fid; ++ cfile->fid.access = fid->access; + #ifdef CONFIG_CIFS_DEBUG2 + cfile->fid.mid = fid->mid; + #endif /* CIFS_DEBUG2 */ +@@ -3162,7 +3163,7 @@ static loff_t smb3_llseek(struct file *file, struct cifs_tcon *tcon, loff_t offs + * some servers (Windows2016) will not reflect recent writes in + * QUERY_ALLOCATED_RANGES until SMB2_flush is called. + */ +- wrcfile = find_writable_file(cifsi, false); ++ wrcfile = find_writable_file(cifsi, FIND_WR_ANY); + if (wrcfile) { + filemap_write_and_wait(inode->i_mapping); + smb2_flush_file(xid, tcon, &wrcfile->fid); +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index c6fc6582ee7b..c8f304cae3f3 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -2650,6 +2650,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, + atomic_inc(&tcon->num_remote_opens); + oparms->fid->persistent_fid = rsp->PersistentFileId; + oparms->fid->volatile_fid = rsp->VolatileFileId; ++ oparms->fid->access = oparms->desired_access; + #ifdef CONFIG_CIFS_DEBUG2 + oparms->fid->mid = le64_to_cpu(rsp->sync_hdr.MessageId); + #endif /* CIFS_DEBUG2 */ +diff --git a/fs/fat/inode.c b/fs/fat/inode.c +index 5f04c5c810fb..d40cbad16659 100644 +--- a/fs/fat/inode.c ++++ b/fs/fat/inode.c +@@ -749,6 +749,13 @@ static struct inode *fat_alloc_inode(struct super_block *sb) + return NULL; + + init_rwsem(&ei->truncate_lock); ++ /* Zeroing to allow iput() even if partial initialized inode. */ ++ ei->mmu_private = 0; ++ ei->i_start = 0; ++ ei->i_logstart = 0; ++ ei->i_attrs = 0; ++ ei->i_pos = 0; ++ + return &ei->vfs_inode; + } + +@@ -1373,16 +1380,6 @@ out: + return 0; + } + +-static void fat_dummy_inode_init(struct inode *inode) +-{ +- /* Initialize this dummy inode to work as no-op. */ +- MSDOS_I(inode)->mmu_private = 0; +- MSDOS_I(inode)->i_start = 0; +- MSDOS_I(inode)->i_logstart = 0; +- MSDOS_I(inode)->i_attrs = 0; +- MSDOS_I(inode)->i_pos = 0; +-} +- + static int fat_read_root(struct inode *inode) + { + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); +@@ -1843,13 +1840,11 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, + fat_inode = new_inode(sb); + if (!fat_inode) + goto out_fail; +- fat_dummy_inode_init(fat_inode); + sbi->fat_inode = fat_inode; + + fsinfo_inode = new_inode(sb); + if (!fsinfo_inode) + goto out_fail; +- fat_dummy_inode_init(fsinfo_inode); + fsinfo_inode->i_ino = MSDOS_FSINFO_INO; + sbi->fsinfo_inode = fsinfo_inode; + insert_inode_hash(fsinfo_inode); +diff --git a/include/linux/mm.h b/include/linux/mm.h +index b249d2e033aa..afa77b683a04 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -2695,6 +2695,10 @@ static inline bool debug_pagealloc_enabled_static(void) + #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_ARCH_HAS_SET_DIRECT_MAP) + extern void __kernel_map_pages(struct page *page, int numpages, int enable); + ++/* ++ * When called in DEBUG_PAGEALLOC context, the call should most likely be ++ * guarded by debug_pagealloc_enabled() or debug_pagealloc_enabled_static() ++ */ + static inline void + kernel_map_pages(struct page *page, int numpages, int enable) + { +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index 34e28b236d68..2625c241ac00 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -612,6 +612,18 @@ void wait_for_kprobe_optimizer(void) + mutex_unlock(&kprobe_mutex); + } + ++static bool optprobe_queued_unopt(struct optimized_kprobe *op) ++{ ++ struct optimized_kprobe *_op; ++ ++ list_for_each_entry(_op, &unoptimizing_list, list) { ++ if (op == _op) ++ return true; ++ } ++ ++ return false; ++} ++ + /* Optimize kprobe if p is ready to be optimized */ + static void optimize_kprobe(struct kprobe *p) + { +@@ -633,17 +645,21 @@ static void optimize_kprobe(struct kprobe *p) + return; + + /* Check if it is already optimized. */ +- if (op->kp.flags & KPROBE_FLAG_OPTIMIZED) ++ if (op->kp.flags & KPROBE_FLAG_OPTIMIZED) { ++ if (optprobe_queued_unopt(op)) { ++ /* This is under unoptimizing. Just dequeue the probe */ ++ list_del_init(&op->list); ++ } + return; ++ } + op->kp.flags |= KPROBE_FLAG_OPTIMIZED; + +- if (!list_empty(&op->list)) +- /* This is under unoptimizing. Just dequeue the probe */ +- list_del_init(&op->list); +- else { +- list_add(&op->list, &optimizing_list); +- kick_kprobe_optimizer(); +- } ++ /* On unoptimizing/optimizing_list, op must have OPTIMIZED flag */ ++ if (WARN_ON_ONCE(!list_empty(&op->list))) ++ return; ++ ++ list_add(&op->list, &optimizing_list); ++ kick_kprobe_optimizer(); + } + + /* Short cut to direct unoptimizing */ +@@ -665,30 +681,33 @@ static void unoptimize_kprobe(struct kprobe *p, bool force) + return; /* This is not an optprobe nor optimized */ + + op = container_of(p, struct optimized_kprobe, kp); +- if (!kprobe_optimized(p)) { +- /* Unoptimized or unoptimizing case */ +- if (force && !list_empty(&op->list)) { +- /* +- * Only if this is unoptimizing kprobe and forced, +- * forcibly unoptimize it. (No need to unoptimize +- * unoptimized kprobe again :) +- */ +- list_del_init(&op->list); +- force_unoptimize_kprobe(op); +- } ++ if (!kprobe_optimized(p)) + return; +- } + + if (!list_empty(&op->list)) { +- /* Dequeue from the optimization queue */ +- list_del_init(&op->list); ++ if (optprobe_queued_unopt(op)) { ++ /* Queued in unoptimizing queue */ ++ if (force) { ++ /* ++ * Forcibly unoptimize the kprobe here, and queue it ++ * in the freeing list for release afterwards. ++ */ ++ force_unoptimize_kprobe(op); ++ list_move(&op->list, &freeing_list); ++ } ++ } else { ++ /* Dequeue from the optimizing queue */ ++ list_del_init(&op->list); ++ op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; ++ } + return; + } ++ + /* Optimized kprobe case */ +- if (force) ++ if (force) { + /* Forcibly update the code: this is a special case */ + force_unoptimize_kprobe(op); +- else { ++ } else { + list_add(&op->list, &unoptimizing_list); + kick_kprobe_optimizer(); + } +diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c +index 4b2ad374167b..e7e483cdbea6 100644 +--- a/kernel/trace/blktrace.c ++++ b/kernel/trace/blktrace.c +@@ -1888,8 +1888,11 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, + } + + ret = 0; +- if (bt == NULL) ++ if (bt == NULL) { + ret = blk_trace_setup_queue(q, bdev); ++ bt = rcu_dereference_protected(q->blk_trace, ++ lockdep_is_held(&q->blk_trace_mutex)); ++ } + + if (ret == 0) { + if (attr == &dev_attr_act_mask) +diff --git a/mm/huge_memory.c b/mm/huge_memory.c +index 6c9689281c07..0d96831b6ded 100644 +--- a/mm/huge_memory.c ++++ b/mm/huge_memory.c +@@ -3032,8 +3032,7 @@ void set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw, + return; + + flush_cache_range(vma, address, address + HPAGE_PMD_SIZE); +- pmdval = *pvmw->pmd; +- pmdp_invalidate(vma, address, pvmw->pmd); ++ pmdval = pmdp_invalidate(vma, address, pvmw->pmd); + if (pmd_dirty(pmdval)) + set_page_dirty(page); + entry = make_migration_entry(page, pmd_write(pmdval)); +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index 0aa154be3a52..c054945a9a74 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -598,7 +598,13 @@ EXPORT_SYMBOL_GPL(__online_page_free); + + static void generic_online_page(struct page *page, unsigned int order) + { +- kernel_map_pages(page, 1 << order, 1); ++ /* ++ * Freeing the page with debug_pagealloc enabled will try to unmap it, ++ * so we should map it first. This is better than introducing a special ++ * case in page freeing fast path. ++ */ ++ if (debug_pagealloc_enabled_static()) ++ kernel_map_pages(page, 1 << order, 1); + __free_pages_core(page, order); + totalram_pages_add(1UL << order); + #ifdef CONFIG_HIGHMEM +diff --git a/mm/mprotect.c b/mm/mprotect.c +index 7967825f6d33..95dee88f782b 100644 +--- a/mm/mprotect.c ++++ b/mm/mprotect.c +@@ -161,6 +161,31 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, + return pages; + } + ++/* ++ * Used when setting automatic NUMA hinting protection where it is ++ * critical that a numa hinting PMD is not confused with a bad PMD. ++ */ ++static inline int pmd_none_or_clear_bad_unless_trans_huge(pmd_t *pmd) ++{ ++ pmd_t pmdval = pmd_read_atomic(pmd); ++ ++ /* See pmd_none_or_trans_huge_or_clear_bad for info on barrier */ ++#ifdef CONFIG_TRANSPARENT_HUGEPAGE ++ barrier(); ++#endif ++ ++ if (pmd_none(pmdval)) ++ return 1; ++ if (pmd_trans_huge(pmdval)) ++ return 0; ++ if (unlikely(pmd_bad(pmdval))) { ++ pmd_clear_bad(pmd); ++ return 1; ++ } ++ ++ return 0; ++} ++ + static inline unsigned long change_pmd_range(struct vm_area_struct *vma, + pud_t *pud, unsigned long addr, unsigned long end, + pgprot_t newprot, int dirty_accountable, int prot_numa) +@@ -178,8 +203,17 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma, + unsigned long this_pages; + + next = pmd_addr_end(addr, end); +- if (!is_swap_pmd(*pmd) && !pmd_trans_huge(*pmd) && !pmd_devmap(*pmd) +- && pmd_none_or_clear_bad(pmd)) ++ ++ /* ++ * Automatic NUMA balancing walks the tables with mmap_sem ++ * held for read. It's possible a parallel update to occur ++ * between pmd_trans_huge() and a pmd_none_or_clear_bad() ++ * check leading to a false positive and clearing. ++ * Hence, it's necessary to atomically read the PMD value ++ * for all the checks. ++ */ ++ if (!is_swap_pmd(*pmd) && !pmd_devmap(*pmd) && ++ pmd_none_or_clear_bad_unless_trans_huge(pmd)) + goto next; + + /* invoke the mmu notifier if the pmd is populated */ +diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c +index 81b19c52832b..020fc7a11ef0 100644 +--- a/security/integrity/platform_certs/load_uefi.c ++++ b/security/integrity/platform_certs/load_uefi.c +@@ -39,16 +39,18 @@ static __init bool uefi_check_ignore_db(void) + * Get a certificate list blob from the named EFI variable. + */ + static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, +- unsigned long *size) ++ unsigned long *size, efi_status_t *status) + { +- efi_status_t status; + unsigned long lsize = 4; + unsigned long tmpdb[4]; + void *db; + +- status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); +- if (status != EFI_BUFFER_TOO_SMALL) { +- pr_err("Couldn't get size: 0x%lx\n", status); ++ *status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); ++ if (*status == EFI_NOT_FOUND) ++ return NULL; ++ ++ if (*status != EFI_BUFFER_TOO_SMALL) { ++ pr_err("Couldn't get size: 0x%lx\n", *status); + return NULL; + } + +@@ -56,10 +58,10 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, + if (!db) + return NULL; + +- status = efi.get_variable(name, guid, NULL, &lsize, db); +- if (status != EFI_SUCCESS) { ++ *status = efi.get_variable(name, guid, NULL, &lsize, db); ++ if (*status != EFI_SUCCESS) { + kfree(db); +- pr_err("Error reading db var: 0x%lx\n", status); ++ pr_err("Error reading db var: 0x%lx\n", *status); + return NULL; + } + +@@ -144,6 +146,7 @@ static int __init load_uefi_certs(void) + efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; + void *db = NULL, *dbx = NULL, *mok = NULL; + unsigned long dbsize = 0, dbxsize = 0, moksize = 0; ++ efi_status_t status; + int rc = 0; + + if (!efi.get_variable) +@@ -153,9 +156,12 @@ static int __init load_uefi_certs(void) + * an error if we can't get them. + */ + if (!uefi_check_ignore_db()) { +- db = get_cert_list(L"db", &secure_var, &dbsize); ++ db = get_cert_list(L"db", &secure_var, &dbsize, &status); + if (!db) { +- pr_err("MODSIGN: Couldn't get UEFI db list\n"); ++ if (status == EFI_NOT_FOUND) ++ pr_debug("MODSIGN: db variable wasn't found\n"); ++ else ++ pr_err("MODSIGN: Couldn't get UEFI db list\n"); + } else { + rc = parse_efi_signature_list("UEFI:db", + db, dbsize, get_handler_for_db); +@@ -166,9 +172,12 @@ static int __init load_uefi_certs(void) + } + } + +- mok = get_cert_list(L"MokListRT", &mok_var, &moksize); ++ mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status); + if (!mok) { +- pr_info("Couldn't get UEFI MokListRT\n"); ++ if (status == EFI_NOT_FOUND) ++ pr_debug("MokListRT variable wasn't found\n"); ++ else ++ pr_info("Couldn't get UEFI MokListRT\n"); + } else { + rc = parse_efi_signature_list("UEFI:MokListRT", + mok, moksize, get_handler_for_db); +@@ -177,9 +186,12 @@ static int __init load_uefi_certs(void) + kfree(mok); + } + +- dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); ++ dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status); + if (!dbx) { +- pr_info("Couldn't get UEFI dbx list\n"); ++ if (status == EFI_NOT_FOUND) ++ pr_debug("dbx variable wasn't found\n"); ++ else ++ pr_info("Couldn't get UEFI dbx list\n"); + } else { + rc = parse_efi_signature_list("UEFI:dbx", + dbx, dbxsize, +diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c +index cfab60d88c92..09ff209df4a3 100644 +--- a/sound/hda/ext/hdac_ext_controller.c ++++ b/sound/hda/ext/hdac_ext_controller.c +@@ -254,6 +254,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all); + int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, + struct hdac_ext_link *link) + { ++ unsigned long codec_mask; + int ret = 0; + + mutex_lock(&bus->lock); +@@ -280,9 +281,11 @@ int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, + * HDA spec section 4.3 - Codec Discovery + */ + udelay(521); +- bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS); +- dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask); +- snd_hdac_chip_writew(bus, STATESTS, bus->codec_mask); ++ codec_mask = snd_hdac_chip_readw(bus, STATESTS); ++ dev_dbg(bus->dev, "codec_mask = 0x%lx\n", codec_mask); ++ snd_hdac_chip_writew(bus, STATESTS, codec_mask); ++ if (!bus->codec_mask) ++ bus->codec_mask = codec_mask; + } + + mutex_unlock(&bus->lock); +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 4f78b40831d8..b6b837a5bdaf 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -2447,6 +2447,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { + SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), + SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), ++ SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950), + SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950), + SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950), + SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950), +@@ -5920,7 +5921,8 @@ enum { + ALC289_FIXUP_DUAL_SPK, + ALC294_FIXUP_SPK2_TO_DAC1, + ALC294_FIXUP_ASUS_DUAL_SPK, +- ++ ALC285_FIXUP_THINKPAD_HEADSET_JACK, ++ ALC294_FIXUP_ASUS_HPE, + }; + + static const struct hda_fixup alc269_fixups[] = { +@@ -6684,6 +6686,8 @@ static const struct hda_fixup alc269_fixups[] = { + [ALC285_FIXUP_SPEAKER2_TO_DAC1] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_speaker2_to_dac1, ++ .chained = true, ++ .chain_id = ALC269_FIXUP_THINKPAD_ACPI + }, + [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = { + .type = HDA_FIXUP_PINS, +@@ -7040,7 +7044,23 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC294_FIXUP_SPK2_TO_DAC1 + }, +- ++ [ALC285_FIXUP_THINKPAD_HEADSET_JACK] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc_fixup_headset_jack, ++ .chained = true, ++ .chain_id = ALC285_FIXUP_SPEAKER2_TO_DAC1 ++ }, ++ [ALC294_FIXUP_ASUS_HPE] = { ++ .type = HDA_FIXUP_VERBS, ++ .v.verbs = (const struct hda_verb[]) { ++ /* Set EAPD high */ ++ { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f }, ++ { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 }, ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -7115,6 +7135,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), + SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK), + SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK), ++ SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE), ++ SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), +@@ -7204,6 +7226,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), + SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK), + SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), + SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC), + SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), +@@ -7274,8 +7297,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), + SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), +- SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1), +- SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1), ++ SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), ++ SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), + SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), + SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), + SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), +diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c +index 861210f6bf4f..4cbef9affffd 100644 +--- a/sound/soc/codecs/pcm512x.c ++++ b/sound/soc/codecs/pcm512x.c +@@ -1564,13 +1564,15 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap) + } + + pcm512x->sclk = devm_clk_get(dev, NULL); +- if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) +- return -EPROBE_DEFER; ++ if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) { ++ ret = -EPROBE_DEFER; ++ goto err; ++ } + if (!IS_ERR(pcm512x->sclk)) { + ret = clk_prepare_enable(pcm512x->sclk); + if (ret != 0) { + dev_err(dev, "Failed to enable SCLK: %d\n", ret); +- return ret; ++ goto err; + } + } + +diff --git a/sound/soc/intel/skylake/skl-debug.c b/sound/soc/intel/skylake/skl-debug.c +index 3466675f2678..a15aa2ffa681 100644 +--- a/sound/soc/intel/skylake/skl-debug.c ++++ b/sound/soc/intel/skylake/skl-debug.c +@@ -34,8 +34,8 @@ static ssize_t skl_print_pins(struct skl_module_pin *m_pin, char *buf, + int i; + ssize_t ret = 0; + +- for (i = 0; i < max_pin; i++) +- ret += snprintf(buf + size, MOD_BUF - size, ++ for (i = 0; i < max_pin; i++) { ++ ret += scnprintf(buf + size, MOD_BUF - size, + "%s %d\n\tModule %d\n\tInstance %d\n\t" + "In-used %s\n\tType %s\n" + "\tState %d\n\tIndex %d\n", +@@ -45,13 +45,15 @@ static ssize_t skl_print_pins(struct skl_module_pin *m_pin, char *buf, + m_pin[i].in_use ? "Used" : "Unused", + m_pin[i].is_dynamic ? "Dynamic" : "Static", + m_pin[i].pin_state, i); ++ size += ret; ++ } + return ret; + } + + static ssize_t skl_print_fmt(struct skl_module_fmt *fmt, char *buf, + ssize_t size, bool direction) + { +- return snprintf(buf + size, MOD_BUF - size, ++ return scnprintf(buf + size, MOD_BUF - size, + "%s\n\tCh %d\n\tFreq %d\n\tBit depth %d\n\t" + "Valid bit depth %d\n\tCh config %#x\n\tInterleaving %d\n\t" + "Sample Type %d\n\tCh Map %#x\n", +@@ -75,16 +77,16 @@ static ssize_t module_read(struct file *file, char __user *user_buf, + if (!buf) + return -ENOMEM; + +- ret = snprintf(buf, MOD_BUF, "Module:\n\tUUID %pUL\n\tModule id %d\n" ++ ret = scnprintf(buf, MOD_BUF, "Module:\n\tUUID %pUL\n\tModule id %d\n" + "\tInstance id %d\n\tPvt_id %d\n", mconfig->guid, + mconfig->id.module_id, mconfig->id.instance_id, + mconfig->id.pvt_id); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "Resources:\n\tCPC %#x\n\tIBS %#x\n\tOBS %#x\t\n", + res->cpc, res->ibs, res->obs); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "Module data:\n\tCore %d\n\tIn queue %d\n\t" + "Out queue %d\n\tType %s\n", + mconfig->core_id, mconfig->max_in_queue, +@@ -94,38 +96,38 @@ static ssize_t module_read(struct file *file, char __user *user_buf, + ret += skl_print_fmt(mconfig->in_fmt, buf, ret, true); + ret += skl_print_fmt(mconfig->out_fmt, buf, ret, false); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "Fixup:\n\tParams %#x\n\tConverter %#x\n", + mconfig->params_fixup, mconfig->converter); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "Module Gateway:\n\tType %#x\n\tVbus %#x\n\tHW conn %#x\n\tSlot %#x\n", + mconfig->dev_type, mconfig->vbus_id, + mconfig->hw_conn_type, mconfig->time_slot); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "Pipeline:\n\tID %d\n\tPriority %d\n\tConn Type %d\n\t" + "Pages %#x\n", mconfig->pipe->ppl_id, + mconfig->pipe->pipe_priority, mconfig->pipe->conn_type, + mconfig->pipe->memory_pages); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "\tParams:\n\t\tHost DMA %d\n\t\tLink DMA %d\n", + mconfig->pipe->p_params->host_dma_id, + mconfig->pipe->p_params->link_dma_id); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "\tPCM params:\n\t\tCh %d\n\t\tFreq %d\n\t\tFormat %d\n", + mconfig->pipe->p_params->ch, + mconfig->pipe->p_params->s_freq, + mconfig->pipe->p_params->s_fmt); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "\tLink %#x\n\tStream %#x\n", + mconfig->pipe->p_params->linktype, + mconfig->pipe->p_params->stream); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "\tState %d\n\tPassthru %s\n", + mconfig->pipe->state, + mconfig->pipe->passthru ? "true" : "false"); +@@ -135,7 +137,7 @@ static ssize_t module_read(struct file *file, char __user *user_buf, + ret += skl_print_pins(mconfig->m_out_pin, buf, + mconfig->max_out_queue, ret, false); + +- ret += snprintf(buf + ret, MOD_BUF - ret, ++ ret += scnprintf(buf + ret, MOD_BUF - ret, + "Other:\n\tDomain %d\n\tHomogeneous Input %s\n\t" + "Homogeneous Output %s\n\tIn Queue Mask %d\n\t" + "Out Queue Mask %d\n\tDMA ID %d\n\tMem Pages %d\n\t" +@@ -191,7 +193,7 @@ static ssize_t fw_softreg_read(struct file *file, char __user *user_buf, + __ioread32_copy(d->fw_read_buff, fw_reg_addr, w0_stat_sz >> 2); + + for (offset = 0; offset < FW_REG_SIZE; offset += 16) { +- ret += snprintf(tmp + ret, FW_REG_BUF - ret, "%#.4x: ", offset); ++ ret += scnprintf(tmp + ret, FW_REG_BUF - ret, "%#.4x: ", offset); + hex_dump_to_buffer(d->fw_read_buff + offset, 16, 16, 4, + tmp + ret, FW_REG_BUF - ret, 0); + ret += strlen(tmp + ret); +diff --git a/sound/soc/intel/skylake/skl-ssp-clk.c b/sound/soc/intel/skylake/skl-ssp-clk.c +index 1c0e5226cb5b..bd43885f3805 100644 +--- a/sound/soc/intel/skylake/skl-ssp-clk.c ++++ b/sound/soc/intel/skylake/skl-ssp-clk.c +@@ -384,9 +384,11 @@ static int skl_clk_dev_probe(struct platform_device *pdev) + &clks[i], clk_pdata, i); + + if (IS_ERR(data->clk[data->avail_clk_cnt])) { +- ret = PTR_ERR(data->clk[data->avail_clk_cnt++]); ++ ret = PTR_ERR(data->clk[data->avail_clk_cnt]); + goto err_unreg_skl_clk; + } ++ ++ data->avail_clk_cnt++; + } + + platform_set_drvdata(pdev, data); +diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c +index 935b5375ecc5..ebd785f9aa46 100644 +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -4749,7 +4749,7 @@ static void soc_dapm_shutdown_dapm(struct snd_soc_dapm_context *dapm) + continue; + if (w->power) { + dapm_seq_insert(w, &down_list, false); +- w->power = 0; ++ w->new_power = 0; + powerdown = 1; + } + } +diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c +index 8712a91e0e3e..d978df95c5c6 100644 +--- a/sound/soc/soc-pcm.c ++++ b/sound/soc/soc-pcm.c +@@ -3169,16 +3169,16 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, + unsigned long flags; + + /* FE state */ +- offset += snprintf(buf + offset, size - offset, ++ offset += scnprintf(buf + offset, size - offset, + "[%s - %s]\n", fe->dai_link->name, + stream ? "Capture" : "Playback"); + +- offset += snprintf(buf + offset, size - offset, "State: %s\n", ++ offset += scnprintf(buf + offset, size - offset, "State: %s\n", + dpcm_state_string(fe->dpcm[stream].state)); + + if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && + (fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) +- offset += snprintf(buf + offset, size - offset, ++ offset += scnprintf(buf + offset, size - offset, + "Hardware Params: " + "Format = %s, Channels = %d, Rate = %d\n", + snd_pcm_format_name(params_format(params)), +@@ -3186,10 +3186,10 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, + params_rate(params)); + + /* BEs state */ +- offset += snprintf(buf + offset, size - offset, "Backends:\n"); ++ offset += scnprintf(buf + offset, size - offset, "Backends:\n"); + + if (list_empty(&fe->dpcm[stream].be_clients)) { +- offset += snprintf(buf + offset, size - offset, ++ offset += scnprintf(buf + offset, size - offset, + " No active DSP links\n"); + goto out; + } +@@ -3199,16 +3199,16 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe, + struct snd_soc_pcm_runtime *be = dpcm->be; + params = &dpcm->hw_params; + +- offset += snprintf(buf + offset, size - offset, ++ offset += scnprintf(buf + offset, size - offset, + "- %s\n", be->dai_link->name); + +- offset += snprintf(buf + offset, size - offset, ++ offset += scnprintf(buf + offset, size - offset, + " State: %s\n", + dpcm_state_string(be->dpcm[stream].state)); + + if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && + (be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) +- offset += snprintf(buf + offset, size - offset, ++ offset += scnprintf(buf + offset, size - offset, + " Hardware Params: " + "Format = %s, Channels = %d, Rate = %d\n", + snd_pcm_format_name(params_format(params)), +diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c +index d00203ef8305..b19ecaf0febf 100644 +--- a/sound/soc/soc-topology.c ++++ b/sound/soc/soc-topology.c +@@ -2320,8 +2320,11 @@ static int soc_tplg_link_elems_load(struct soc_tplg *tplg, + } + + ret = soc_tplg_link_config(tplg, _link); +- if (ret < 0) ++ if (ret < 0) { ++ if (!abi_match) ++ kfree(_link); + return ret; ++ } + + /* offset by version-specific struct size and + * real priv data size +@@ -2485,7 +2488,7 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, + { + struct snd_soc_tplg_manifest *manifest, *_manifest; + bool abi_match; +- int err; ++ int ret = 0; + + if (tplg->pass != SOC_TPLG_PASS_MANIFEST) + return 0; +@@ -2498,19 +2501,19 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, + _manifest = manifest; + } else { + abi_match = false; +- err = manifest_new_ver(tplg, manifest, &_manifest); +- if (err < 0) +- return err; ++ ret = manifest_new_ver(tplg, manifest, &_manifest); ++ if (ret < 0) ++ return ret; + } + + /* pass control to component driver for optional further init */ + if (tplg->comp && tplg->ops && tplg->ops->manifest) +- return tplg->ops->manifest(tplg->comp, tplg->index, _manifest); ++ ret = tplg->ops->manifest(tplg->comp, tplg->index, _manifest); + + if (!abi_match) /* free the duplicated one */ + kfree(_manifest); + +- return 0; ++ return ret; + } + + /* validate header magic, size and type */ +diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c +index 8984d965037d..e7b1a80e2a14 100644 +--- a/sound/soc/sof/ipc.c ++++ b/sound/soc/sof/ipc.c +@@ -497,7 +497,7 @@ int snd_sof_ipc_stream_posn(struct snd_sof_dev *sdev, + + /* send IPC to the DSP */ + err = sof_ipc_tx_message(sdev->ipc, +- stream.hdr.cmd, &stream, sizeof(stream), &posn, ++ stream.hdr.cmd, &stream, sizeof(stream), posn, + sizeof(*posn)); + if (err < 0) { + dev_err(sdev->dev, "error: failed to get stream %d position\n", +diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c +index ede040cf82ad..20e9a189ad92 100644 +--- a/tools/perf/arch/arm/util/cs-etm.c ++++ b/tools/perf/arch/arm/util/cs-etm.c +@@ -865,9 +865,12 @@ static int cs_etm_read_finish(struct auxtrace_record *itr, int idx) + struct evsel *evsel; + + evlist__for_each_entry(ptr->evlist, evsel) { +- if (evsel->core.attr.type == ptr->cs_etm_pmu->type) ++ if (evsel->core.attr.type == ptr->cs_etm_pmu->type) { ++ if (evsel->disabled) ++ return 0; + return perf_evlist__enable_event_idx(ptr->evlist, + evsel, idx); ++ } + } + + return -EINVAL; +diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c +index eba6541ec0f1..1d993c27242b 100644 +--- a/tools/perf/arch/arm64/util/arm-spe.c ++++ b/tools/perf/arch/arm64/util/arm-spe.c +@@ -165,9 +165,12 @@ static int arm_spe_read_finish(struct auxtrace_record *itr, int idx) + struct evsel *evsel; + + evlist__for_each_entry(sper->evlist, evsel) { +- if (evsel->core.attr.type == sper->arm_spe_pmu->type) ++ if (evsel->core.attr.type == sper->arm_spe_pmu->type) { ++ if (evsel->disabled) ++ return 0; + return perf_evlist__enable_event_idx(sper->evlist, + evsel, idx); ++ } + } + return -EINVAL; + } +diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c +index f7f68a50a5cd..85799b5fa01d 100644 +--- a/tools/perf/arch/x86/util/intel-bts.c ++++ b/tools/perf/arch/x86/util/intel-bts.c +@@ -415,9 +415,12 @@ static int intel_bts_read_finish(struct auxtrace_record *itr, int idx) + struct evsel *evsel; + + evlist__for_each_entry(btsr->evlist, evsel) { +- if (evsel->core.attr.type == btsr->intel_bts_pmu->type) ++ if (evsel->core.attr.type == btsr->intel_bts_pmu->type) { ++ if (evsel->disabled) ++ return 0; + return perf_evlist__enable_event_idx(btsr->evlist, + evsel, idx); ++ } + } + return -EINVAL; + } +diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c +index d6d26256915f..d43f9dec6998 100644 +--- a/tools/perf/arch/x86/util/intel-pt.c ++++ b/tools/perf/arch/x86/util/intel-pt.c +@@ -1099,9 +1099,12 @@ static int intel_pt_read_finish(struct auxtrace_record *itr, int idx) + struct evsel *evsel; + + evlist__for_each_entry(ptr->evlist, evsel) { +- if (evsel->core.attr.type == ptr->intel_pt_pmu->type) ++ if (evsel->core.attr.type == ptr->intel_pt_pmu->type) { ++ if (evsel->disabled) ++ return 0; + return perf_evlist__enable_event_idx(ptr->evlist, evsel, + idx); ++ } + } + return -EINVAL; + } +diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk +index 1c8a1963d03f..3ed0134a764d 100644 +--- a/tools/testing/selftests/lib.mk ++++ b/tools/testing/selftests/lib.mk +@@ -83,17 +83,20 @@ else + $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_PROGS)) + endif + ++define INSTALL_SINGLE_RULE ++ $(if $(INSTALL_LIST),@mkdir -p $(INSTALL_PATH)) ++ $(if $(INSTALL_LIST),@echo rsync -a $(INSTALL_LIST) $(INSTALL_PATH)/) ++ $(if $(INSTALL_LIST),@rsync -a $(INSTALL_LIST) $(INSTALL_PATH)/) ++endef ++ + define INSTALL_RULE +- @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \ +- mkdir -p ${INSTALL_PATH}; \ +- echo "rsync -a $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/"; \ +- rsync -a $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/; \ +- fi +- @if [ "X$(TEST_GEN_PROGS)$(TEST_CUSTOM_PROGS)$(TEST_GEN_PROGS_EXTENDED)$(TEST_GEN_FILES)" != "X" ]; then \ +- mkdir -p ${INSTALL_PATH}; \ +- echo "rsync -a $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(INSTALL_PATH)/"; \ +- rsync -a $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(INSTALL_PATH)/; \ +- fi ++ $(eval INSTALL_LIST = $(TEST_PROGS)) $(INSTALL_SINGLE_RULE) ++ $(eval INSTALL_LIST = $(TEST_PROGS_EXTENDED)) $(INSTALL_SINGLE_RULE) ++ $(eval INSTALL_LIST = $(TEST_FILES)) $(INSTALL_SINGLE_RULE) ++ $(eval INSTALL_LIST = $(TEST_GEN_PROGS)) $(INSTALL_SINGLE_RULE) ++ $(eval INSTALL_LIST = $(TEST_CUSTOM_PROGS)) $(INSTALL_SINGLE_RULE) ++ $(eval INSTALL_LIST = $(TEST_GEN_PROGS_EXTENDED)) $(INSTALL_SINGLE_RULE) ++ $(eval INSTALL_LIST = $(TEST_GEN_FILES)) $(INSTALL_SINGLE_RULE) + endef + + install: all +diff --git a/tools/testing/selftests/net/forwarding/mirror_gre.sh b/tools/testing/selftests/net/forwarding/mirror_gre.sh +index e6fd7a18c655..0266443601bc 100755 +--- a/tools/testing/selftests/net/forwarding/mirror_gre.sh ++++ b/tools/testing/selftests/net/forwarding/mirror_gre.sh +@@ -63,22 +63,23 @@ test_span_gre_mac() + { + local tundev=$1; shift + local direction=$1; shift +- local prot=$1; shift + local what=$1; shift + +- local swp3mac=$(mac_get $swp3) +- local h3mac=$(mac_get $h3) ++ case "$direction" in ++ ingress) local src_mac=$(mac_get $h1); local dst_mac=$(mac_get $h2) ++ ;; ++ egress) local src_mac=$(mac_get $h2); local dst_mac=$(mac_get $h1) ++ ;; ++ esac + + RET=0 + + mirror_install $swp1 $direction $tundev "matchall $tcflags" +- tc filter add dev $h3 ingress pref 77 prot $prot \ +- flower ip_proto 0x2f src_mac $swp3mac dst_mac $h3mac \ +- action pass ++ icmp_capture_install h3-${tundev} "src_mac $src_mac dst_mac $dst_mac" + +- mirror_test v$h1 192.0.2.1 192.0.2.2 $h3 77 10 ++ mirror_test v$h1 192.0.2.1 192.0.2.2 h3-${tundev} 100 10 + +- tc filter del dev $h3 ingress pref 77 ++ icmp_capture_uninstall h3-${tundev} + mirror_uninstall $swp1 $direction + + log_test "$direction $what: envelope MAC ($tcflags)" +@@ -120,14 +121,14 @@ test_ip6gretap() + + test_gretap_mac() + { +- test_span_gre_mac gt4 ingress ip "mirror to gretap" +- test_span_gre_mac gt4 egress ip "mirror to gretap" ++ test_span_gre_mac gt4 ingress "mirror to gretap" ++ test_span_gre_mac gt4 egress "mirror to gretap" + } + + test_ip6gretap_mac() + { +- test_span_gre_mac gt6 ingress ipv6 "mirror to ip6gretap" +- test_span_gre_mac gt6 egress ipv6 "mirror to ip6gretap" ++ test_span_gre_mac gt6 ingress "mirror to ip6gretap" ++ test_span_gre_mac gt6 egress "mirror to ip6gretap" + } + + test_all() +diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +index bb10e33690b2..ce6bea9675c0 100755 +--- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh ++++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +@@ -516,9 +516,9 @@ test_tos() + RET=0 + + tc filter add dev v1 egress pref 77 prot ip \ +- flower ip_tos 0x40 action pass +- vxlan_ping_test $h1 192.0.2.3 "-Q 0x40" v1 egress 77 10 +- vxlan_ping_test $h1 192.0.2.3 "-Q 0x30" v1 egress 77 0 ++ flower ip_tos 0x14 action pass ++ vxlan_ping_test $h1 192.0.2.3 "-Q 0x14" v1 egress 77 10 ++ vxlan_ping_test $h1 192.0.2.3 "-Q 0x18" v1 egress 77 0 + tc filter del dev v1 egress pref 77 prot ip + + log_test "VXLAN: envelope TOS inheritance" +diff --git a/usr/include/Makefile b/usr/include/Makefile +index 47cb91d3a51d..e2840579156a 100644 +--- a/usr/include/Makefile ++++ b/usr/include/Makefile +@@ -99,7 +99,7 @@ endif + # asm-generic/*.h is used by asm/*.h, and should not be included directly + header-test- += asm-generic/% + +-extra-y := $(patsubst $(obj)/%.h,%.hdrtest, $(shell find $(obj) -name '*.h')) ++extra-y := $(patsubst $(obj)/%.h,%.hdrtest, $(shell find $(obj) -name '*.h' 2>/dev/null)) + + quiet_cmd_hdrtest = HDRTEST $< + cmd_hdrtest = \ diff --git a/patch/kernel/odroidxu4-current/03-patch-5.4.25-26.patch b/patch/kernel/odroidxu4-current/03-patch-5.4.25-26.patch new file mode 100644 index 0000000000..aac88a712f --- /dev/null +++ b/patch/kernel/odroidxu4-current/03-patch-5.4.25-26.patch @@ -0,0 +1,4156 @@ +diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst +index f18506083ced..26c093969573 100644 +--- a/Documentation/filesystems/porting.rst ++++ b/Documentation/filesystems/porting.rst +@@ -850,3 +850,11 @@ business doing so. + d_alloc_pseudo() is internal-only; uses outside of alloc_file_pseudo() are + very suspect (and won't work in modules). Such uses are very likely to + be misspelled d_alloc_anon(). ++ ++--- ++ ++**mandatory** ++ ++[should've been added in 2016] stale comment in finish_open() nonwithstanding, ++failure exits in ->atomic_open() instances should *NOT* fput() the file, ++no matter what. Everything is handled by the caller. +diff --git a/Makefile b/Makefile +index 85e41313f078..2250b1bb8aa9 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 25 ++SUBLEVEL = 26 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arc/include/asm/linkage.h b/arch/arc/include/asm/linkage.h +index d9ee43c6b7db..fe19f1d412e7 100644 +--- a/arch/arc/include/asm/linkage.h ++++ b/arch/arc/include/asm/linkage.h +@@ -29,6 +29,8 @@ + .endm + + #define ASM_NL ` /* use '`' to mark new line in macro */ ++#define __ALIGN .align 4 ++#define __ALIGN_STR __stringify(__ALIGN) + + /* annotation for data we want in DCCM - if enabled in .config */ + .macro ARCFP_DATA nm +diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c +index a6ea07f2aa84..4d867a752f0e 100644 +--- a/arch/x86/events/amd/uncore.c ++++ b/arch/x86/events/amd/uncore.c +@@ -190,15 +190,12 @@ static int amd_uncore_event_init(struct perf_event *event) + + /* + * NB and Last level cache counters (MSRs) are shared across all cores +- * that share the same NB / Last level cache. Interrupts can be directed +- * to a single target core, however, event counts generated by processes +- * running on other cores cannot be masked out. So we do not support +- * sampling and per-thread events. ++ * that share the same NB / Last level cache. On family 16h and below, ++ * Interrupts can be directed to a single target core, however, event ++ * counts generated by processes running on other cores cannot be masked ++ * out. So we do not support sampling and per-thread events via ++ * CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts: + */ +- if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) +- return -EINVAL; +- +- /* and we do not enable counter overflow interrupts */ + hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; + hwc->idx = -1; + +@@ -306,7 +303,7 @@ static struct pmu amd_nb_pmu = { + .start = amd_uncore_start, + .stop = amd_uncore_stop, + .read = amd_uncore_read, +- .capabilities = PERF_PMU_CAP_NO_EXCLUDE, ++ .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, + }; + + static struct pmu amd_llc_pmu = { +@@ -317,7 +314,7 @@ static struct pmu amd_llc_pmu = { + .start = amd_uncore_start, + .stop = amd_uncore_stop, + .read = amd_uncore_read, +- .capabilities = PERF_PMU_CAP_NO_EXCLUDE, ++ .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, + }; + + static struct amd_uncore *amd_uncore_alloc(unsigned int cpu) +diff --git a/arch/x86/kernel/cpu/mce/intel.c b/arch/x86/kernel/cpu/mce/intel.c +index 88cd9598fa57..f2350967a898 100644 +--- a/arch/x86/kernel/cpu/mce/intel.c ++++ b/arch/x86/kernel/cpu/mce/intel.c +@@ -489,17 +489,18 @@ static void intel_ppin_init(struct cpuinfo_x86 *c) + return; + + if ((val & 3UL) == 1UL) { +- /* PPIN available but disabled: */ ++ /* PPIN locked in disabled mode */ + return; + } + +- /* If PPIN is disabled, but not locked, try to enable: */ +- if (!(val & 3UL)) { ++ /* If PPIN is disabled, try to enable */ ++ if (!(val & 2UL)) { + wrmsrl_safe(MSR_PPIN_CTL, val | 2UL); + rdmsrl_safe(MSR_PPIN_CTL, &val); + } + +- if ((val & 3UL) == 2UL) ++ /* Is the enable bit set? */ ++ if (val & 2UL) + set_cpu_cap(c, X86_FEATURE_INTEL_PPIN); + } + } +diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c +index 37aa9ce29b33..128d3ad46e96 100644 +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -5197,6 +5197,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) + ctxt->fetch.ptr = ctxt->fetch.data; + ctxt->fetch.end = ctxt->fetch.data + insn_len; + ctxt->opcode_len = 1; ++ ctxt->intercept = x86_intercept_none; + if (insn_len > 0) + memcpy(ctxt->fetch.data, insn, insn_len); + else { +diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c +index e1d8062ef12e..2b44554baf28 100644 +--- a/arch/x86/kvm/vmx/nested.c ++++ b/arch/x86/kvm/vmx/nested.c +@@ -223,7 +223,7 @@ static inline void nested_release_evmcs(struct kvm_vcpu *vcpu) + return; + + kvm_vcpu_unmap(vcpu, &vmx->nested.hv_evmcs_map, true); +- vmx->nested.hv_evmcs_vmptr = -1ull; ++ vmx->nested.hv_evmcs_vmptr = 0; + vmx->nested.hv_evmcs = NULL; + } + +@@ -1828,7 +1828,8 @@ static int nested_vmx_handle_enlightened_vmptrld(struct kvm_vcpu *vcpu, + if (!nested_enlightened_vmentry(vcpu, &evmcs_gpa)) + return 1; + +- if (unlikely(evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) { ++ if (unlikely(!vmx->nested.hv_evmcs || ++ evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) { + if (!vmx->nested.hv_evmcs) + vmx->nested.current_vmptr = -1ull; + +diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c +index a39dcdb5ae34..2db3b7c4de16 100644 +--- a/arch/x86/mm/ioremap.c ++++ b/arch/x86/mm/ioremap.c +@@ -106,6 +106,19 @@ static unsigned int __ioremap_check_encrypted(struct resource *res) + return 0; + } + ++/* ++ * The EFI runtime services data area is not covered by walk_mem_res(), but must ++ * be mapped encrypted when SEV is active. ++ */ ++static void __ioremap_check_other(resource_size_t addr, struct ioremap_desc *desc) ++{ ++ if (!sev_active()) ++ return; ++ ++ if (efi_mem_type(addr) == EFI_RUNTIME_SERVICES_DATA) ++ desc->flags |= IORES_MAP_ENCRYPTED; ++} ++ + static int __ioremap_collect_map_flags(struct resource *res, void *arg) + { + struct ioremap_desc *desc = arg; +@@ -124,6 +137,9 @@ static int __ioremap_collect_map_flags(struct resource *res, void *arg) + * To avoid multiple resource walks, this function walks resources marked as + * IORESOURCE_MEM and IORESOURCE_BUSY and looking for system RAM and/or a + * resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES). ++ * ++ * After that, deal with misc other ranges in __ioremap_check_other() which do ++ * not fall into the above category. + */ + static void __ioremap_check_mem(resource_size_t addr, unsigned long size, + struct ioremap_desc *desc) +@@ -135,6 +151,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size, + memset(desc, 0, sizeof(struct ioremap_desc)); + + walk_mem_res(start, end, desc, __ioremap_collect_map_flags); ++ ++ __ioremap_check_other(addr, desc); + } + + /* +diff --git a/block/blk-iocost.c b/block/blk-iocost.c +index 27ca68621137..9a599cc28c29 100644 +--- a/block/blk-iocost.c ++++ b/block/blk-iocost.c +@@ -1318,7 +1318,7 @@ static bool iocg_is_idle(struct ioc_gq *iocg) + return false; + + /* is something in flight? */ +- if (atomic64_read(&iocg->done_vtime) < atomic64_read(&iocg->vtime)) ++ if (atomic64_read(&iocg->done_vtime) != atomic64_read(&iocg->vtime)) + return false; + + return true; +diff --git a/drivers/base/platform.c b/drivers/base/platform.c +index 60386a32208f..604a461848c9 100644 +--- a/drivers/base/platform.c ++++ b/drivers/base/platform.c +@@ -335,10 +335,10 @@ static void setup_pdev_dma_masks(struct platform_device *pdev) + { + if (!pdev->dev.coherent_dma_mask) + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +- if (!pdev->dma_mask) +- pdev->dma_mask = DMA_BIT_MASK(32); +- if (!pdev->dev.dma_mask) +- pdev->dev.dma_mask = &pdev->dma_mask; ++ if (!pdev->dev.dma_mask) { ++ pdev->platform_dma_mask = DMA_BIT_MASK(32); ++ pdev->dev.dma_mask = &pdev->platform_dma_mask; ++ } + }; + + /** +@@ -634,20 +634,8 @@ struct platform_device *platform_device_register_full( + pdev->dev.of_node_reused = pdevinfo->of_node_reused; + + if (pdevinfo->dma_mask) { +- /* +- * This memory isn't freed when the device is put, +- * I don't have a nice idea for that though. Conceptually +- * dma_mask in struct device should not be a pointer. +- * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 +- */ +- pdev->dev.dma_mask = +- kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); +- if (!pdev->dev.dma_mask) +- goto err; +- +- kmemleak_ignore(pdev->dev.dma_mask); +- +- *pdev->dev.dma_mask = pdevinfo->dma_mask; ++ pdev->platform_dma_mask = pdevinfo->dma_mask; ++ pdev->dev.dma_mask = &pdev->platform_dma_mask; + pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; + } + +@@ -672,7 +660,6 @@ struct platform_device *platform_device_register_full( + if (ret) { + err: + ACPI_COMPANION_SET(&pdev->dev, NULL); +- kfree(pdev->dev.dma_mask); + platform_device_put(pdev); + return ERR_PTR(ret); + } +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index 7ffd719d89de..c2ed3e9128e3 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -339,10 +339,12 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, + err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num); + if (err) { + virtqueue_kick(vblk->vqs[qid].vq); +- blk_mq_stop_hw_queue(hctx); ++ /* Don't stop the queue if -ENOMEM: we may have failed to ++ * bounce the buffer due to global resource outage. ++ */ ++ if (err == -ENOSPC) ++ blk_mq_stop_hw_queue(hctx); + spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); +- /* Out of mem doesn't actually happen, since we fall back +- * to direct descriptors */ + if (err == -ENOMEM || err == -ENOSPC) + return BLK_STS_DEV_RESOURCE; + return BLK_STS_IOERR; +diff --git a/drivers/char/ipmi/ipmi_si_platform.c b/drivers/char/ipmi/ipmi_si_platform.c +index c78127ccbc0d..638c693e17ad 100644 +--- a/drivers/char/ipmi/ipmi_si_platform.c ++++ b/drivers/char/ipmi/ipmi_si_platform.c +@@ -194,7 +194,7 @@ static int platform_ipmi_probe(struct platform_device *pdev) + else + io.slave_addr = slave_addr; + +- io.irq = platform_get_irq(pdev, 0); ++ io.irq = platform_get_irq_optional(pdev, 0); + if (io.irq > 0) + io.irq_setup = ipmi_std_irq_setup; + else +@@ -378,7 +378,7 @@ static int acpi_ipmi_probe(struct platform_device *pdev) + io.irq = tmp; + io.irq_setup = acpi_gpe_irq_setup; + } else { +- int irq = platform_get_irq(pdev, 0); ++ int irq = platform_get_irq_optional(pdev, 0); + + if (irq > 0) { + io.irq = irq; +diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c +index 7576450c8254..aff3dfb4d7ba 100644 +--- a/drivers/firmware/efi/efivars.c ++++ b/drivers/firmware/efi/efivars.c +@@ -83,13 +83,16 @@ static ssize_t + efivar_attr_read(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; ++ unsigned long size = sizeof(var->Data); + char *str = buf; ++ int ret; + + if (!entry || !buf) + return -EINVAL; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); ++ var->DataSize = size; ++ if (ret) + return -EIO; + + if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) +@@ -116,13 +119,16 @@ static ssize_t + efivar_size_read(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; ++ unsigned long size = sizeof(var->Data); + char *str = buf; ++ int ret; + + if (!entry || !buf) + return -EINVAL; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); ++ var->DataSize = size; ++ if (ret) + return -EIO; + + str += sprintf(str, "0x%lx\n", var->DataSize); +@@ -133,12 +139,15 @@ static ssize_t + efivar_data_read(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; ++ unsigned long size = sizeof(var->Data); ++ int ret; + + if (!entry || !buf) + return -EINVAL; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); ++ var->DataSize = size; ++ if (ret) + return -EIO; + + memcpy(buf, var->Data, var->DataSize); +@@ -199,6 +208,9 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) + u8 *data; + int err; + ++ if (!entry || !buf) ++ return -EINVAL; ++ + if (in_compat_syscall()) { + struct compat_efi_variable *compat; + +@@ -250,14 +262,16 @@ efivar_show_raw(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; + struct compat_efi_variable *compat; ++ unsigned long datasize = sizeof(var->Data); + size_t size; ++ int ret; + + if (!entry || !buf) + return 0; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &entry->var.Attributes, +- &entry->var.DataSize, entry->var.Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data); ++ var->DataSize = datasize; ++ if (ret) + return -EIO; + + if (in_compat_syscall()) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +index f2f40f05fa5c..c687432da426 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +@@ -365,8 +365,7 @@ bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device * + router.ddc_valid = false; + router.cd_valid = false; + for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) { +- uint8_t grph_obj_type= +- grph_obj_type = ++ uint8_t grph_obj_type = + (le16_to_cpu(path->usGraphicObjIds[j]) & + OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + +diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +index e635e1e5f4d3..bd4e41380777 100644 +--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +@@ -439,7 +439,8 @@ eb_validate_vma(struct i915_execbuffer *eb, + if (unlikely(entry->flags & eb->invalid_flags)) + return -EINVAL; + +- if (unlikely(entry->alignment && !is_power_of_2(entry->alignment))) ++ if (unlikely(entry->alignment && ++ !is_power_of_2_u64(entry->alignment))) + return -EINVAL; + + /* +diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c +index e1c313da6c00..a62bdf9be682 100644 +--- a/drivers/gpu/drm/i915/gvt/display.c ++++ b/drivers/gpu/drm/i915/gvt/display.c +@@ -457,7 +457,8 @@ void intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected) + struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; + + /* TODO: add more platforms support */ +- if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { ++ if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) || ++ IS_COFFEELAKE(dev_priv)) { + if (connected) { + vgpu_vreg_t(vgpu, SFUSE_STRAP) |= + SFUSE_STRAP_DDID_DETECTED; +diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c +index b232965b45b5..32e57635709a 100644 +--- a/drivers/gpu/drm/i915/gvt/vgpu.c ++++ b/drivers/gpu/drm/i915/gvt/vgpu.c +@@ -272,10 +272,17 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) + { + struct intel_gvt *gvt = vgpu->gvt; + +- mutex_lock(&vgpu->vgpu_lock); +- + WARN(vgpu->active, "vGPU is still active!\n"); + ++ /* ++ * remove idr first so later clean can judge if need to stop ++ * service if no active vgpu. ++ */ ++ mutex_lock(&gvt->lock); ++ idr_remove(&gvt->vgpu_idr, vgpu->id); ++ mutex_unlock(&gvt->lock); ++ ++ mutex_lock(&vgpu->vgpu_lock); + intel_gvt_debugfs_remove_vgpu(vgpu); + intel_vgpu_clean_sched_policy(vgpu); + intel_vgpu_clean_submission(vgpu); +@@ -290,7 +297,6 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) + mutex_unlock(&vgpu->vgpu_lock); + + mutex_lock(&gvt->lock); +- idr_remove(&gvt->vgpu_idr, vgpu->id); + if (idr_is_empty(&gvt->vgpu_idr)) + intel_gvt_clean_irq(gvt); + intel_gvt_update_vgpu_types(gvt); +diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c +index 1c5506822dc7..0d39038898d4 100644 +--- a/drivers/gpu/drm/i915/i915_request.c ++++ b/drivers/gpu/drm/i915/i915_request.c +@@ -560,19 +560,31 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) + return NOTIFY_DONE; + } + ++static void irq_semaphore_cb(struct irq_work *wrk) ++{ ++ struct i915_request *rq = ++ container_of(wrk, typeof(*rq), semaphore_work); ++ ++ i915_schedule_bump_priority(rq, I915_PRIORITY_NOSEMAPHORE); ++ i915_request_put(rq); ++} ++ + static int __i915_sw_fence_call + semaphore_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) + { +- struct i915_request *request = +- container_of(fence, typeof(*request), semaphore); ++ struct i915_request *rq = container_of(fence, typeof(*rq), semaphore); + + switch (state) { + case FENCE_COMPLETE: +- i915_schedule_bump_priority(request, I915_PRIORITY_NOSEMAPHORE); ++ if (!(READ_ONCE(rq->sched.attr.priority) & I915_PRIORITY_NOSEMAPHORE)) { ++ i915_request_get(rq); ++ init_irq_work(&rq->semaphore_work, irq_semaphore_cb); ++ irq_work_queue(&rq->semaphore_work); ++ } + break; + + case FENCE_FREE: +- i915_request_put(request); ++ i915_request_put(rq); + break; + } + +@@ -1215,9 +1227,9 @@ void __i915_request_queue(struct i915_request *rq, + * decide whether to preempt the entire chain so that it is ready to + * run at the earliest possible convenience. + */ +- i915_sw_fence_commit(&rq->semaphore); + if (attr && rq->engine->schedule) + rq->engine->schedule(rq, attr); ++ i915_sw_fence_commit(&rq->semaphore); + i915_sw_fence_commit(&rq->submit); + } + +diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h +index e4dd013761e8..3a3e7bbf19ff 100644 +--- a/drivers/gpu/drm/i915/i915_request.h ++++ b/drivers/gpu/drm/i915/i915_request.h +@@ -26,6 +26,7 @@ + #define I915_REQUEST_H + + #include ++#include + #include + + #include "gt/intel_context_types.h" +@@ -147,6 +148,7 @@ struct i915_request { + }; + struct list_head execute_cb; + struct i915_sw_fence semaphore; ++ struct irq_work semaphore_work; + + /* + * A list of everyone we wait upon, and everyone who waits upon us. +diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h +index 562f756da421..5b1622a40baa 100644 +--- a/drivers/gpu/drm/i915/i915_utils.h ++++ b/drivers/gpu/drm/i915/i915_utils.h +@@ -233,6 +233,11 @@ static inline u64 ptr_to_u64(const void *ptr) + __idx; \ + }) + ++static inline bool is_power_of_2_u64(u64 n) ++{ ++ return (n != 0 && ((n & (n - 1)) == 0)); ++} ++ + static inline void __list_del_many(struct list_head *head, + struct list_head *first) + { +diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c +index 050adda7c1bd..05b35ac33ce3 100644 +--- a/drivers/i2c/busses/i2c-designware-pcidrv.c ++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c +@@ -313,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev) + pm_runtime_get_noresume(&pdev->dev); + + i2c_del_adapter(&dev->adapter); ++ devm_free_irq(&pdev->dev, dev->irq, dev); + pci_free_irq_vectors(pdev); + } + +diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c +index 3a9e840a3546..a4a6825c8758 100644 +--- a/drivers/i2c/busses/i2c-gpio.c ++++ b/drivers/i2c/busses/i2c-gpio.c +@@ -348,7 +348,7 @@ static struct gpio_desc *i2c_gpio_get_desc(struct device *dev, + if (ret == -ENOENT) + retdesc = ERR_PTR(-EPROBE_DEFER); + +- if (ret != -EPROBE_DEFER) ++ if (PTR_ERR(retdesc) != -EPROBE_DEFER) + dev_err(dev, "error trying to get descriptor: %d\n", ret); + + return retdesc; +diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c +index 62a1c92ab803..ce70b5288472 100644 +--- a/drivers/i2c/i2c-core-acpi.c ++++ b/drivers/i2c/i2c-core-acpi.c +@@ -394,9 +394,17 @@ EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle); + static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) + { + struct device *dev; ++ struct i2c_client *client; + + dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); +- return dev ? i2c_verify_client(dev) : NULL; ++ if (!dev) ++ return NULL; ++ ++ client = i2c_verify_client(dev); ++ if (!client) ++ put_device(dev); ++ ++ return client; + } + + static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, +diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c +index 8bd5d608a82c..bc7771498342 100644 +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -4421,7 +4421,7 @@ int amd_iommu_activate_guest_mode(void *data) + entry->lo.fields_vapic.ga_tag = ir_data->ga_tag; + + return modify_irte_ga(ir_data->irq_2_irte.devid, +- ir_data->irq_2_irte.index, entry, NULL); ++ ir_data->irq_2_irte.index, entry, ir_data); + } + EXPORT_SYMBOL(amd_iommu_activate_guest_mode); + +@@ -4447,7 +4447,7 @@ int amd_iommu_deactivate_guest_mode(void *data) + APICID_TO_IRTE_DEST_HI(cfg->dest_apicid); + + return modify_irte_ga(ir_data->irq_2_irte.devid, +- ir_data->irq_2_irte.index, entry, NULL); ++ ir_data->irq_2_irte.index, entry, ir_data); + } + EXPORT_SYMBOL(amd_iommu_deactivate_guest_mode); + +diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c +index c68a1f072c31..76bd2309e023 100644 +--- a/drivers/iommu/dma-iommu.c ++++ b/drivers/iommu/dma-iommu.c +@@ -176,15 +176,15 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie, + start -= iova_offset(iovad, start); + num_pages = iova_align(iovad, end - start) >> iova_shift(iovad); + +- msi_page = kcalloc(num_pages, sizeof(*msi_page), GFP_KERNEL); +- if (!msi_page) +- return -ENOMEM; +- + for (i = 0; i < num_pages; i++) { +- msi_page[i].phys = start; +- msi_page[i].iova = start; +- INIT_LIST_HEAD(&msi_page[i].list); +- list_add(&msi_page[i].list, &cookie->msi_page_list); ++ msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL); ++ if (!msi_page) ++ return -ENOMEM; ++ ++ msi_page->phys = start; ++ msi_page->iova = start; ++ INIT_LIST_HEAD(&msi_page->list); ++ list_add(&msi_page->list, &cookie->msi_page_list); + start += iovad->granule; + } + +diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c +index 7196cabafb25..6a9a1b987520 100644 +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -128,6 +129,13 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) + + BUG_ON(dev->is_virtfn); + ++ /* ++ * Ignore devices that have a domain number higher than what can ++ * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000 ++ */ ++ if (pci_domain_nr(dev->bus) > U16_MAX) ++ return NULL; ++ + /* Only generate path[] for device addition event */ + if (event == BUS_NOTIFY_ADD_DEVICE) + for (tmp = dev; tmp; tmp = tmp->bus->self) +@@ -440,12 +448,13 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header, + + /* Check for NUL termination within the designated length */ + if (strnlen(andd->device_name, header->length - 8) == header->length - 8) { +- WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, ++ pr_warn(FW_BUG + "Your BIOS is broken; ANDD object name is not NUL-terminated\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + return -EINVAL; + } + pr_info("ANDD device: %x name: %s\n", andd->device_number, +@@ -471,14 +480,14 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg) + return 0; + } + } +- WARN_TAINT( +- 1, TAINT_FIRMWARE_WORKAROUND, ++ pr_warn(FW_BUG + "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", +- drhd->reg_base_addr, ++ rhsa->base_address, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + + return 0; + } +@@ -827,14 +836,14 @@ int __init dmar_table_init(void) + + static void warn_invalid_dmar(u64 addr, const char *message) + { +- WARN_TAINT_ONCE( +- 1, TAINT_FIRMWARE_WORKAROUND, ++ pr_warn_once(FW_BUG + "Your BIOS is broken; DMAR reported at address %llx%s!\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + addr, message, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + } + + static int __ref +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index 760a242d0801..1c2b3e78056f 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -4129,10 +4129,11 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev) + + /* we know that the this iommu should be at offset 0xa000 from vtbar */ + drhd = dmar_find_matched_drhd_unit(pdev); +- if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000, +- TAINT_FIRMWARE_WORKAROUND, +- "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n")) ++ if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) { ++ pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; ++ } + } + DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu); + +@@ -5023,6 +5024,7 @@ int __init intel_iommu_init(void) + + init_iommu_pm_ops(); + ++ down_read(&dmar_global_lock); + for_each_active_iommu(iommu, drhd) { + iommu_device_sysfs_add(&iommu->iommu, NULL, + intel_iommu_groups, +@@ -5030,6 +5032,7 @@ int __init intel_iommu_init(void) + iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); + iommu_device_register(&iommu->iommu); + } ++ up_read(&dmar_global_lock); + + bus_set_iommu(&pci_bus_type, &intel_iommu_ops); + if (si_domain && !hw_pass_through) +@@ -5040,7 +5043,6 @@ int __init intel_iommu_init(void) + down_read(&dmar_global_lock); + if (probe_acpi_namespace_devices()) + pr_warn("ACPI name space devices didn't probe correctly\n"); +- up_read(&dmar_global_lock); + + /* Finally, we enable the DMA remapping hardware. */ + for_each_iommu(iommu, drhd) { +@@ -5049,6 +5051,8 @@ int __init intel_iommu_init(void) + + iommu_disable_protect_mem_regions(iommu); + } ++ up_read(&dmar_global_lock); ++ + pr_info("Intel(R) Virtualization Technology for Directed I/O\n"); + + intel_iommu_enabled = 1; +@@ -5523,8 +5527,10 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, + u64 phys = 0; + + pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level); +- if (pte) +- phys = dma_pte_addr(pte); ++ if (pte && dma_pte_present(pte)) ++ phys = dma_pte_addr(pte) + ++ (iova & (BIT_MASK(level_to_offset_bits(level) + ++ VTD_PAGE_SHIFT) - 1)); + + return phys; + } +diff --git a/drivers/macintosh/windfarm_ad7417_sensor.c b/drivers/macintosh/windfarm_ad7417_sensor.c +index 125605987b44..e7dec328c7cf 100644 +--- a/drivers/macintosh/windfarm_ad7417_sensor.c ++++ b/drivers/macintosh/windfarm_ad7417_sensor.c +@@ -312,9 +312,16 @@ static const struct i2c_device_id wf_ad7417_id[] = { + }; + MODULE_DEVICE_TABLE(i2c, wf_ad7417_id); + ++static const struct of_device_id wf_ad7417_of_id[] = { ++ { .compatible = "ad7417", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_ad7417_of_id); ++ + static struct i2c_driver wf_ad7417_driver = { + .driver = { + .name = "wf_ad7417", ++ .of_match_table = wf_ad7417_of_id, + }, + .probe = wf_ad7417_probe, + .remove = wf_ad7417_remove, +diff --git a/drivers/macintosh/windfarm_fcu_controls.c b/drivers/macintosh/windfarm_fcu_controls.c +index 3c971297b6dc..89b48e8ac6ef 100644 +--- a/drivers/macintosh/windfarm_fcu_controls.c ++++ b/drivers/macintosh/windfarm_fcu_controls.c +@@ -582,9 +582,16 @@ static const struct i2c_device_id wf_fcu_id[] = { + }; + MODULE_DEVICE_TABLE(i2c, wf_fcu_id); + ++static const struct of_device_id wf_fcu_of_id[] = { ++ { .compatible = "fcu", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_fcu_of_id); ++ + static struct i2c_driver wf_fcu_driver = { + .driver = { + .name = "wf_fcu", ++ .of_match_table = wf_fcu_of_id, + }, + .probe = wf_fcu_probe, + .remove = wf_fcu_remove, +diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c +index 282c28a17ea1..1e5fa09845e7 100644 +--- a/drivers/macintosh/windfarm_lm75_sensor.c ++++ b/drivers/macintosh/windfarm_lm75_sensor.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -91,9 +92,14 @@ static int wf_lm75_probe(struct i2c_client *client, + const struct i2c_device_id *id) + { + struct wf_lm75_sensor *lm; +- int rc, ds1775 = id->driver_data; ++ int rc, ds1775; + const char *name, *loc; + ++ if (id) ++ ds1775 = id->driver_data; ++ else ++ ds1775 = !!of_device_get_match_data(&client->dev); ++ + DBG("wf_lm75: creating %s device at address 0x%02x\n", + ds1775 ? "ds1775" : "lm75", client->addr); + +@@ -164,9 +170,17 @@ static const struct i2c_device_id wf_lm75_id[] = { + }; + MODULE_DEVICE_TABLE(i2c, wf_lm75_id); + ++static const struct of_device_id wf_lm75_of_id[] = { ++ { .compatible = "lm75", .data = (void *)0}, ++ { .compatible = "ds1775", .data = (void *)1 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_lm75_of_id); ++ + static struct i2c_driver wf_lm75_driver = { + .driver = { + .name = "wf_lm75", ++ .of_match_table = wf_lm75_of_id, + }, + .probe = wf_lm75_probe, + .remove = wf_lm75_remove, +diff --git a/drivers/macintosh/windfarm_lm87_sensor.c b/drivers/macintosh/windfarm_lm87_sensor.c +index e44525b19071..1a1f8f3f0abc 100644 +--- a/drivers/macintosh/windfarm_lm87_sensor.c ++++ b/drivers/macintosh/windfarm_lm87_sensor.c +@@ -166,9 +166,16 @@ static const struct i2c_device_id wf_lm87_id[] = { + }; + MODULE_DEVICE_TABLE(i2c, wf_lm87_id); + ++static const struct of_device_id wf_lm87_of_id[] = { ++ { .compatible = "lm87cimt", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_lm87_of_id); ++ + static struct i2c_driver wf_lm87_driver = { + .driver = { + .name = "wf_lm87", ++ .of_match_table = wf_lm87_of_id, + }, + .probe = wf_lm87_probe, + .remove = wf_lm87_remove, +diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c +index e666cc020683..1e7b03d44ad9 100644 +--- a/drivers/macintosh/windfarm_max6690_sensor.c ++++ b/drivers/macintosh/windfarm_max6690_sensor.c +@@ -120,9 +120,16 @@ static const struct i2c_device_id wf_max6690_id[] = { + }; + MODULE_DEVICE_TABLE(i2c, wf_max6690_id); + ++static const struct of_device_id wf_max6690_of_id[] = { ++ { .compatible = "max6690", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_max6690_of_id); ++ + static struct i2c_driver wf_max6690_driver = { + .driver = { + .name = "wf_max6690", ++ .of_match_table = wf_max6690_of_id, + }, + .probe = wf_max6690_probe, + .remove = wf_max6690_remove, +diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c +index c84ec49c3741..cb75dc035616 100644 +--- a/drivers/macintosh/windfarm_smu_sat.c ++++ b/drivers/macintosh/windfarm_smu_sat.c +@@ -341,9 +341,16 @@ static const struct i2c_device_id wf_sat_id[] = { + }; + MODULE_DEVICE_TABLE(i2c, wf_sat_id); + ++static const struct of_device_id wf_sat_of_id[] = { ++ { .compatible = "smu-sat", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, wf_sat_of_id); ++ + static struct i2c_driver wf_sat_driver = { + .driver = { + .name = "wf_smu_sat", ++ .of_match_table = wf_sat_of_id, + }, + .probe = wf_sat_probe, + .remove = wf_sat_remove, +diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c +index 5eea8d70a85d..ce15a05f23d4 100644 +--- a/drivers/mmc/host/sdhci-pci-gli.c ++++ b/drivers/mmc/host/sdhci-pci-gli.c +@@ -262,10 +262,26 @@ static int gl9750_execute_tuning(struct sdhci_host *host, u32 opcode) + return 0; + } + ++static void gli_pcie_enable_msi(struct sdhci_pci_slot *slot) ++{ ++ int ret; ++ ++ ret = pci_alloc_irq_vectors(slot->chip->pdev, 1, 1, ++ PCI_IRQ_MSI | PCI_IRQ_MSIX); ++ if (ret < 0) { ++ pr_warn("%s: enable PCI MSI failed, error=%d\n", ++ mmc_hostname(slot->host->mmc), ret); ++ return; ++ } ++ ++ slot->host->irq = pci_irq_vector(slot->chip->pdev, 0); ++} ++ + static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot) + { + struct sdhci_host *host = slot->host; + ++ gli_pcie_enable_msi(slot); + slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; + sdhci_enable_v4_mode(host); + +@@ -276,6 +292,7 @@ static int gli_probe_slot_gl9755(struct sdhci_pci_slot *slot) + { + struct sdhci_host *host = slot->host; + ++ gli_pcie_enable_msi(slot); + slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; + sdhci_enable_v4_mode(host); + +diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c +index 1cc2cd894f87..c81698550e5a 100644 +--- a/drivers/net/bonding/bond_alb.c ++++ b/drivers/net/bonding/bond_alb.c +@@ -50,11 +50,6 @@ struct arp_pkt { + }; + #pragma pack() + +-static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb) +-{ +- return (struct arp_pkt *)skb_network_header(skb); +-} +- + /* Forward declaration */ + static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], + bool strict_match); +@@ -553,10 +548,11 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) + spin_unlock(&bond->mode_lock); + } + +-static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond) ++static struct slave *rlb_choose_channel(struct sk_buff *skb, ++ struct bonding *bond, ++ const struct arp_pkt *arp) + { + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); +- struct arp_pkt *arp = arp_pkt(skb); + struct slave *assigned_slave, *curr_active_slave; + struct rlb_client_info *client_info; + u32 hash_index = 0; +@@ -653,8 +649,12 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon + */ + static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) + { +- struct arp_pkt *arp = arp_pkt(skb); + struct slave *tx_slave = NULL; ++ struct arp_pkt *arp; ++ ++ if (!pskb_network_may_pull(skb, sizeof(*arp))) ++ return NULL; ++ arp = (struct arp_pkt *)skb_network_header(skb); + + /* Don't modify or load balance ARPs that do not originate locally + * (e.g.,arrive via a bridge). +@@ -664,7 +664,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) + + if (arp->op_code == htons(ARPOP_REPLY)) { + /* the arp must be sent on the selected rx channel */ +- tx_slave = rlb_choose_channel(skb, bond); ++ tx_slave = rlb_choose_channel(skb, bond, arp); + if (tx_slave) + bond_hw_addr_copy(arp->mac_src, tx_slave->dev->dev_addr, + tx_slave->dev->addr_len); +@@ -676,7 +676,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) + * When the arp reply is received the entry will be updated + * with the correct unicast address of the client. + */ +- tx_slave = rlb_choose_channel(skb, bond); ++ tx_slave = rlb_choose_channel(skb, bond, arp); + + /* The ARP reply packets must be delayed so that + * they can cancel out the influence of the ARP request. +diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c +index 1c88c361938c..3a33fb503400 100644 +--- a/drivers/net/can/dev.c ++++ b/drivers/net/can/dev.c +@@ -884,6 +884,7 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { + = { .len = sizeof(struct can_bittiming) }, + [IFLA_CAN_DATA_BITTIMING_CONST] + = { .len = sizeof(struct can_bittiming_const) }, ++ [IFLA_CAN_TERMINATION] = { .type = NLA_U16 }, + }; + + static int can_validate(struct nlattr *tb[], struct nlattr *data[], +diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c +index bdbb72fc20ed..6240976679e1 100644 +--- a/drivers/net/dsa/mv88e6xxx/global2.c ++++ b/drivers/net/dsa/mv88e6xxx/global2.c +@@ -1083,6 +1083,13 @@ int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip) + { + int err, irq, virq; + ++ chip->g2_irq.masked = ~0; ++ mv88e6xxx_reg_lock(chip); ++ err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked); ++ mv88e6xxx_reg_unlock(chip); ++ if (err) ++ return err; ++ + chip->g2_irq.domain = irq_domain_add_simple( + chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip); + if (!chip->g2_irq.domain) +@@ -1092,7 +1099,6 @@ int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip) + irq_create_mapping(chip->g2_irq.domain, irq); + + chip->g2_irq.chip = mv88e6xxx_g2_irq_chip; +- chip->g2_irq.masked = ~0; + + chip->device_irq = irq_find_mapping(chip->g1_irq.domain, + MV88E6XXX_G1_STS_IRQ_DEVICE); +diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c +index 4a27577e137b..ad86a186ddc5 100644 +--- a/drivers/net/ethernet/broadcom/bcmsysport.c ++++ b/drivers/net/ethernet/broadcom/bcmsysport.c +@@ -2135,7 +2135,7 @@ static int bcm_sysport_rule_set(struct bcm_sysport_priv *priv, + return -ENOSPC; + + index = find_first_zero_bit(priv->filters, RXCHK_BRCM_TAG_MAX); +- if (index > RXCHK_BRCM_TAG_MAX) ++ if (index >= RXCHK_BRCM_TAG_MAX) + return -ENOSPC; + + /* Location is the classification ID, and index is the position +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 374e11a91790..57c88e157f86 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -10891,13 +10891,13 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu) + struct bnxt *bp = netdev_priv(dev); + + if (netif_running(dev)) +- bnxt_close_nic(bp, false, false); ++ bnxt_close_nic(bp, true, false); + + dev->mtu = new_mtu; + bnxt_set_ring_params(bp); + + if (netif_running(dev)) +- return bnxt_open_nic(bp, false, false); ++ return bnxt_open_nic(bp, true, false); + + return 0; + } +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +index ece70f61c89a..cfa647d5b44d 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +@@ -2005,8 +2005,8 @@ static int bnxt_flash_package_from_file(struct net_device *dev, + struct hwrm_nvm_install_update_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_nvm_install_update_input install = {0}; + const struct firmware *fw; +- int rc, hwrm_err = 0; + u32 item_len; ++ int rc = 0; + u16 index; + + bnxt_hwrm_fw_set_time(bp); +@@ -2050,15 +2050,14 @@ static int bnxt_flash_package_from_file(struct net_device *dev, + memcpy(kmem, fw->data, fw->size); + modify.host_src_addr = cpu_to_le64(dma_handle); + +- hwrm_err = hwrm_send_message(bp, &modify, +- sizeof(modify), +- FLASH_PACKAGE_TIMEOUT); ++ rc = hwrm_send_message(bp, &modify, sizeof(modify), ++ FLASH_PACKAGE_TIMEOUT); + dma_free_coherent(&bp->pdev->dev, fw->size, kmem, + dma_handle); + } + } + release_firmware(fw); +- if (rc || hwrm_err) ++ if (rc) + goto err_exit; + + if ((install_type & 0xffff) == 0) +@@ -2067,20 +2066,19 @@ static int bnxt_flash_package_from_file(struct net_device *dev, + install.install_type = cpu_to_le32(install_type); + + mutex_lock(&bp->hwrm_cmd_lock); +- hwrm_err = _hwrm_send_message(bp, &install, sizeof(install), +- INSTALL_PACKAGE_TIMEOUT); +- if (hwrm_err) { ++ rc = _hwrm_send_message(bp, &install, sizeof(install), ++ INSTALL_PACKAGE_TIMEOUT); ++ if (rc) { + u8 error_code = ((struct hwrm_err_output *)resp)->cmd_err; + + if (resp->error_code && error_code == + NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { + install.flags |= cpu_to_le16( + NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); +- hwrm_err = _hwrm_send_message(bp, &install, +- sizeof(install), +- INSTALL_PACKAGE_TIMEOUT); ++ rc = _hwrm_send_message(bp, &install, sizeof(install), ++ INSTALL_PACKAGE_TIMEOUT); + } +- if (hwrm_err) ++ if (rc) + goto flash_pkg_exit; + } + +@@ -2092,7 +2090,7 @@ static int bnxt_flash_package_from_file(struct net_device *dev, + flash_pkg_exit: + mutex_unlock(&bp->hwrm_cmd_lock); + err_exit: +- if (hwrm_err == -EACCES) ++ if (rc == -EACCES) + bnxt_print_admin_err(bp); + return rc; + } +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 8336f4cbaf95..3fc8a66e4f41 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -2529,15 +2529,15 @@ fec_enet_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec) + return -EINVAL; + } + +- cycle = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr); ++ cycle = fec_enet_us_to_itr_clock(ndev, ec->rx_coalesce_usecs); + if (cycle > 0xFFFF) { + dev_err(dev, "Rx coalesced usec exceed hardware limitation\n"); + return -EINVAL; + } + +- cycle = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr); ++ cycle = fec_enet_us_to_itr_clock(ndev, ec->tx_coalesce_usecs); + if (cycle > 0xFFFF) { +- dev_err(dev, "Rx coalesced usec exceed hardware limitation\n"); ++ dev_err(dev, "Tx coalesced usec exceed hardware limitation\n"); + return -EINVAL; + } + +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +index c01cf8ef69df..d4652dea4569 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -2417,10 +2417,12 @@ static int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed, + + int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex) + { ++ struct hclge_mac *mac = &hdev->hw.mac; + int ret; + + duplex = hclge_check_speed_dup(duplex, speed); +- if (hdev->hw.mac.speed == speed && hdev->hw.mac.duplex == duplex) ++ if (!mac->support_autoneg && mac->speed == speed && ++ mac->duplex == duplex) + return 0; + + ret = hclge_cfg_mac_speed_dup_hw(hdev, speed, duplex); +diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c +index 2fef7402233e..82391abbd42b 100644 +--- a/drivers/net/ethernet/sfc/efx.c ++++ b/drivers/net/ethernet/sfc/efx.c +@@ -519,6 +519,7 @@ efx_copy_channel(const struct efx_channel *old_channel) + if (tx_queue->channel) + tx_queue->channel = channel; + tx_queue->buffer = NULL; ++ tx_queue->cb_page = NULL; + memset(&tx_queue->txd, 0, sizeof(tx_queue->txd)); + } + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +index 3d69da112625..43a785f86c69 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +@@ -24,6 +24,7 @@ + static void dwmac1000_core_init(struct mac_device_info *hw, + struct net_device *dev) + { ++ struct stmmac_priv *priv = netdev_priv(dev); + void __iomem *ioaddr = hw->pcsr; + u32 value = readl(ioaddr + GMAC_CONTROL); + int mtu = dev->mtu; +@@ -35,7 +36,7 @@ static void dwmac1000_core_init(struct mac_device_info *hw, + * Broadcom tags can look like invalid LLC/SNAP packets and cause the + * hardware to truncate packets on reception. + */ +- if (netdev_uses_dsa(dev)) ++ if (netdev_uses_dsa(dev) || !priv->plat->enh_desc) + value &= ~GMAC_CONTROL_ACS; + + if (mtu > 1500) +diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c +index 30cd0c4f0be0..8801d093135c 100644 +--- a/drivers/net/ipvlan/ipvlan_core.c ++++ b/drivers/net/ipvlan/ipvlan_core.c +@@ -293,6 +293,7 @@ void ipvlan_process_multicast(struct work_struct *work) + } + if (dev) + dev_put(dev); ++ cond_resched(); + } + } + +@@ -498,19 +499,21 @@ static int ipvlan_process_outbound(struct sk_buff *skb) + struct ethhdr *ethh = eth_hdr(skb); + int ret = NET_XMIT_DROP; + +- /* In this mode we dont care about multicast and broadcast traffic */ +- if (is_multicast_ether_addr(ethh->h_dest)) { +- pr_debug_ratelimited("Dropped {multi|broad}cast of type=[%x]\n", +- ntohs(skb->protocol)); +- kfree_skb(skb); +- goto out; +- } +- + /* The ipvlan is a pseudo-L2 device, so the packets that we receive + * will have L2; which need to discarded and processed further + * in the net-ns of the main-device. + */ + if (skb_mac_header_was_set(skb)) { ++ /* In this mode we dont care about ++ * multicast and broadcast traffic */ ++ if (is_multicast_ether_addr(ethh->h_dest)) { ++ pr_debug_ratelimited( ++ "Dropped {multi|broad}cast of type=[%x]\n", ++ ntohs(skb->protocol)); ++ kfree_skb(skb); ++ goto out; ++ } ++ + skb_pull(skb, sizeof(*ethh)); + skb->mac_header = (typeof(skb->mac_header))~0U; + skb_reset_network_header(skb); +diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c +index ba3dfac1d904..b805abc9ec3b 100644 +--- a/drivers/net/ipvlan/ipvlan_main.c ++++ b/drivers/net/ipvlan/ipvlan_main.c +@@ -164,7 +164,6 @@ static void ipvlan_uninit(struct net_device *dev) + static int ipvlan_open(struct net_device *dev) + { + struct ipvl_dev *ipvlan = netdev_priv(dev); +- struct net_device *phy_dev = ipvlan->phy_dev; + struct ipvl_addr *addr; + + if (ipvlan->port->mode == IPVLAN_MODE_L3 || +@@ -178,7 +177,7 @@ static int ipvlan_open(struct net_device *dev) + ipvlan_ht_addr_add(ipvlan, addr); + rcu_read_unlock(); + +- return dev_uc_add(phy_dev, phy_dev->dev_addr); ++ return 0; + } + + static int ipvlan_stop(struct net_device *dev) +@@ -190,8 +189,6 @@ static int ipvlan_stop(struct net_device *dev) + dev_uc_unsync(phy_dev, dev); + dev_mc_unsync(phy_dev, dev); + +- dev_uc_del(phy_dev, phy_dev->dev_addr); +- + rcu_read_lock(); + list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) + ipvlan_ht_addr_del(addr); +diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c +index afd8b2a08245..6497a5c45220 100644 +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -2882,6 +2882,11 @@ static void macsec_dev_set_rx_mode(struct net_device *dev) + dev_uc_sync(real_dev, dev); + } + ++static sci_t dev_to_sci(struct net_device *dev, __be16 port) ++{ ++ return make_sci(dev->dev_addr, port); ++} ++ + static int macsec_set_mac_address(struct net_device *dev, void *p) + { + struct macsec_dev *macsec = macsec_priv(dev); +@@ -2903,6 +2908,7 @@ static int macsec_set_mac_address(struct net_device *dev, void *p) + + out: + ether_addr_copy(dev->dev_addr, addr->sa_data); ++ macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES); + return 0; + } + +@@ -2977,6 +2983,7 @@ static const struct device_type macsec_type = { + + static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = { + [IFLA_MACSEC_SCI] = { .type = NLA_U64 }, ++ [IFLA_MACSEC_PORT] = { .type = NLA_U16 }, + [IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 }, + [IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 }, + [IFLA_MACSEC_WINDOW] = { .type = NLA_U32 }, +@@ -3176,11 +3183,6 @@ static bool sci_exists(struct net_device *dev, sci_t sci) + return false; + } + +-static sci_t dev_to_sci(struct net_device *dev, __be16 port) +-{ +- return make_sci(dev->dev_addr, port); +-} +- + static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len) + { + struct macsec_dev *macsec = macsec_priv(dev); +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index c5bf61565726..26f6be4796c7 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -334,6 +334,8 @@ static void macvlan_process_broadcast(struct work_struct *w) + if (src) + dev_put(src->dev); + consume_skb(skb); ++ ++ cond_resched(); + } + } + +diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c +index 23f1958ba6ad..459fb2069c7e 100644 +--- a/drivers/net/phy/bcm63xx.c ++++ b/drivers/net/phy/bcm63xx.c +@@ -73,6 +73,7 @@ static struct phy_driver bcm63xx_driver[] = { + /* same phy as above, with just a different OUI */ + .phy_id = 0x002bdc00, + .phy_id_mask = 0xfffffc00, ++ .name = "Broadcom BCM63XX (2)", + /* PHY_BASIC_FEATURES */ + .flags = PHY_IS_INTERNAL, + .config_init = bcm63xx_config_init, +diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c +index 105d389b58e7..ea890d802ffe 100644 +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -761,7 +761,8 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat) + phy_trigger_machine(phydev); + } + +- if (phy_clear_interrupt(phydev)) ++ /* did_interrupt() may have cleared the interrupt already */ ++ if (!phydev->drv->did_interrupt && phy_clear_interrupt(phydev)) + goto phy_err; + return IRQ_HANDLED; + +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index 2bf0fda209a8..0907c3d8d94a 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -246,7 +246,7 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) + * MDIO bus driver and clock gated at this point. + */ + if (!netdev) +- return !phydev->suspended; ++ goto out; + + if (netdev->wol_enabled) + return false; +@@ -266,7 +266,8 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) + if (device_may_wakeup(&netdev->dev)) + return false; + +- return true; ++out: ++ return !phydev->suspended; + } + + static int mdio_bus_phy_suspend(struct device *dev) +@@ -284,6 +285,8 @@ static int mdio_bus_phy_suspend(struct device *dev) + if (!mdio_bus_phy_may_suspend(phydev)) + return 0; + ++ phydev->suspended_by_mdio_bus = 1; ++ + return phy_suspend(phydev); + } + +@@ -292,9 +295,11 @@ static int mdio_bus_phy_resume(struct device *dev) + struct phy_device *phydev = to_phy_device(dev); + int ret; + +- if (!mdio_bus_phy_may_suspend(phydev)) ++ if (!phydev->suspended_by_mdio_bus) + goto no_resume; + ++ phydev->suspended_by_mdio_bus = 0; ++ + ret = phy_resume(phydev); + if (ret < 0) + return ret; +diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c +index 58a69f830d29..f78ceba42e57 100644 +--- a/drivers/net/slip/slhc.c ++++ b/drivers/net/slip/slhc.c +@@ -232,7 +232,7 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + struct cstate *cs = lcs->next; + unsigned long deltaS, deltaA; + short changes = 0; +- int hlen; ++ int nlen, hlen; + unsigned char new_seq[16]; + unsigned char *cp = new_seq; + struct iphdr *ip; +@@ -248,6 +248,8 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + return isize; + + ip = (struct iphdr *) icp; ++ if (ip->version != 4 || ip->ihl < 5) ++ return isize; + + /* Bail if this packet isn't TCP, or is an IP fragment */ + if (ip->protocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) { +@@ -258,10 +260,14 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + comp->sls_o_tcp++; + return isize; + } +- /* Extract TCP header */ ++ nlen = ip->ihl * 4; ++ if (isize < nlen + sizeof(*th)) ++ return isize; + +- th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); +- hlen = ip->ihl*4 + th->doff*4; ++ th = (struct tcphdr *)(icp + nlen); ++ if (th->doff < sizeof(struct tcphdr) / 4) ++ return isize; ++ hlen = nlen + th->doff * 4; + + /* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or + * some other control bit is set). Also uncompressible if +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index ca70a1d840eb..4004f98e50d9 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -2240,6 +2240,8 @@ team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = { + [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG }, + [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 }, + [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY }, ++ [TEAM_ATTR_OPTION_PORT_IFINDEX] = { .type = NLA_U32 }, ++ [TEAM_ATTR_OPTION_ARRAY_INDEX] = { .type = NLA_U32 }, + }; + + static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index 6912624eed4a..44ea5dcc43fd 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -3006,6 +3006,8 @@ static u16 r8153_phy_status(struct r8152 *tp, u16 desired) + } + + msleep(20); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ break; + } + + return data; +@@ -4419,7 +4421,10 @@ static void r8153_init(struct r8152 *tp) + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & + AUTOLOAD_DONE) + break; ++ + msleep(20); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ break; + } + + data = r8153_phy_status(tp, 0); +@@ -4545,7 +4550,10 @@ static void r8153b_init(struct r8152 *tp) + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & + AUTOLOAD_DONE) + break; ++ + msleep(20); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ break; + } + + data = r8153_phy_status(tp, 0); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +index 945c1ea5cda8..ed367b0a185c 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +@@ -309,7 +309,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) + } + + /* PHY_SKU section is mandatory in B0 */ +- if (!mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { ++ if (mvm->trans->cfg->nvm_type == IWL_NVM_EXT && ++ !mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { + IWL_ERR(mvm, + "Can't parse phy_sku in B0, empty sections\n"); + return NULL; +diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c +index 8f69d00bd940..6249a46c1976 100644 +--- a/drivers/net/wireless/mediatek/mt76/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/dma.c +@@ -448,10 +448,13 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data, + struct page *page = virt_to_head_page(data); + int offset = data - page_address(page); + struct sk_buff *skb = q->rx_head; ++ struct skb_shared_info *shinfo = skb_shinfo(skb); + +- offset += q->buf_offset; +- skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, offset, len, +- q->buf_size); ++ if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) { ++ offset += q->buf_offset; ++ skb_add_rx_frag(skb, shinfo->nr_frags, page, offset, len, ++ q->buf_size); ++ } + + if (more) + return; +diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c +index 2bbd8ee93507..6381745e3bb1 100644 +--- a/drivers/pinctrl/core.c ++++ b/drivers/pinctrl/core.c +@@ -2025,7 +2025,6 @@ static int pinctrl_claim_hogs(struct pinctrl_dev *pctldev) + return PTR_ERR(pctldev->p); + } + +- kref_get(&pctldev->p->users); + pctldev->hog_default = + pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT); + if (IS_ERR(pctldev->hog_default)) { +diff --git a/drivers/pinctrl/freescale/pinctrl-scu.c b/drivers/pinctrl/freescale/pinctrl-scu.c +index 73bf1d9f9cc6..23cf04bdfc55 100644 +--- a/drivers/pinctrl/freescale/pinctrl-scu.c ++++ b/drivers/pinctrl/freescale/pinctrl-scu.c +@@ -23,12 +23,12 @@ struct imx_sc_msg_req_pad_set { + struct imx_sc_rpc_msg hdr; + u32 val; + u16 pad; +-} __packed; ++} __packed __aligned(4); + + struct imx_sc_msg_req_pad_get { + struct imx_sc_rpc_msg hdr; + u16 pad; +-} __packed; ++} __packed __aligned(4); + + struct imx_sc_msg_resp_pad_get { + struct imx_sc_rpc_msg hdr; +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +index 72c5373c8dc1..e8d1f3050487 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +@@ -147,8 +147,8 @@ static const unsigned int sdio_d0_pins[] = { GPIOX_0 }; + static const unsigned int sdio_d1_pins[] = { GPIOX_1 }; + static const unsigned int sdio_d2_pins[] = { GPIOX_2 }; + static const unsigned int sdio_d3_pins[] = { GPIOX_3 }; +-static const unsigned int sdio_cmd_pins[] = { GPIOX_4 }; +-static const unsigned int sdio_clk_pins[] = { GPIOX_5 }; ++static const unsigned int sdio_clk_pins[] = { GPIOX_4 }; ++static const unsigned int sdio_cmd_pins[] = { GPIOX_5 }; + static const unsigned int sdio_irq_pins[] = { GPIOX_7 }; + + static const unsigned int nand_ce0_pins[] = { BOOT_8 }; +diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c +index a454f57c264e..62c02b969327 100644 +--- a/drivers/pinctrl/pinctrl-falcon.c ++++ b/drivers/pinctrl/pinctrl-falcon.c +@@ -451,7 +451,7 @@ static int pinctrl_falcon_probe(struct platform_device *pdev) + falcon_info.clk[*bank] = clk_get(&ppdev->dev, NULL); + if (IS_ERR(falcon_info.clk[*bank])) { + dev_err(&ppdev->dev, "failed to get clock\n"); +- of_node_put(np) ++ of_node_put(np); + return PTR_ERR(falcon_info.clk[*bank]); + } + falcon_info.membase[*bank] = devm_ioremap_resource(&pdev->dev, +diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c +index 6cca72782af6..cf87eb27879f 100644 +--- a/drivers/s390/block/dasd.c ++++ b/drivers/s390/block/dasd.c +@@ -178,6 +178,8 @@ struct dasd_block *dasd_alloc_block(void) + (unsigned long) block); + INIT_LIST_HEAD(&block->ccw_queue); + spin_lock_init(&block->queue_lock); ++ INIT_LIST_HEAD(&block->format_list); ++ spin_lock_init(&block->format_lock); + timer_setup(&block->timer, dasd_block_timeout, 0); + spin_lock_init(&block->profile.lock); + +@@ -1779,20 +1781,26 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, + + if (dasd_ese_needs_format(cqr->block, irb)) { + if (rq_data_dir((struct request *)cqr->callback_data) == READ) { +- device->discipline->ese_read(cqr); ++ device->discipline->ese_read(cqr, irb); + cqr->status = DASD_CQR_SUCCESS; + cqr->stopclk = now; + dasd_device_clear_timer(device); + dasd_schedule_device_bh(device); + return; + } +- fcqr = device->discipline->ese_format(device, cqr); ++ fcqr = device->discipline->ese_format(device, cqr, irb); + if (IS_ERR(fcqr)) { ++ if (PTR_ERR(fcqr) == -EINVAL) { ++ cqr->status = DASD_CQR_ERROR; ++ return; ++ } + /* + * If we can't format now, let the request go + * one extra round. Maybe we can format later. + */ + cqr->status = DASD_CQR_QUEUED; ++ dasd_schedule_device_bh(device); ++ return; + } else { + fcqr->status = DASD_CQR_QUEUED; + cqr->status = DASD_CQR_QUEUED; +@@ -2748,11 +2756,13 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) + { + struct request *req; + blk_status_t error = BLK_STS_OK; ++ unsigned int proc_bytes; + int status; + + req = (struct request *) cqr->callback_data; + dasd_profile_end(cqr->block, cqr, req); + ++ proc_bytes = cqr->proc_bytes; + status = cqr->block->base->discipline->free_cp(cqr, req); + if (status < 0) + error = errno_to_blk_status(status); +@@ -2783,7 +2793,18 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) + blk_mq_end_request(req, error); + blk_mq_run_hw_queues(req->q, true); + } else { +- blk_mq_complete_request(req); ++ /* ++ * Partial completed requests can happen with ESE devices. ++ * During read we might have gotten a NRF error and have to ++ * complete a request partially. ++ */ ++ if (proc_bytes) { ++ blk_update_request(req, BLK_STS_OK, ++ blk_rq_bytes(req) - proc_bytes); ++ blk_mq_requeue_request(req, true); ++ } else { ++ blk_mq_complete_request(req); ++ } + } + } + +diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c +index a28b9ff82378..ad44d22e8859 100644 +--- a/drivers/s390/block/dasd_eckd.c ++++ b/drivers/s390/block/dasd_eckd.c +@@ -207,6 +207,45 @@ static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head) + geo->head |= head; + } + ++/* ++ * calculate failing track from sense data depending if ++ * it is an EAV device or not ++ */ ++static int dasd_eckd_track_from_irb(struct irb *irb, struct dasd_device *device, ++ sector_t *track) ++{ ++ struct dasd_eckd_private *private = device->private; ++ u8 *sense = NULL; ++ u32 cyl; ++ u8 head; ++ ++ sense = dasd_get_sense(irb); ++ if (!sense) { ++ DBF_DEV_EVENT(DBF_WARNING, device, "%s", ++ "ESE error no sense data\n"); ++ return -EINVAL; ++ } ++ if (!(sense[27] & DASD_SENSE_BIT_2)) { ++ DBF_DEV_EVENT(DBF_WARNING, device, "%s", ++ "ESE error no valid track data\n"); ++ return -EINVAL; ++ } ++ ++ if (sense[27] & DASD_SENSE_BIT_3) { ++ /* enhanced addressing */ ++ cyl = sense[30] << 20; ++ cyl |= (sense[31] & 0xF0) << 12; ++ cyl |= sense[28] << 8; ++ cyl |= sense[29]; ++ } else { ++ cyl = sense[29] << 8; ++ cyl |= sense[30]; ++ } ++ head = sense[31] & 0x0F; ++ *track = cyl * private->rdc_data.trk_per_cyl + head; ++ return 0; ++} ++ + static int set_timestamp(struct ccw1 *ccw, struct DE_eckd_data *data, + struct dasd_device *device) + { +@@ -2986,6 +3025,37 @@ static int dasd_eckd_format_device(struct dasd_device *base, + 0, NULL); + } + ++static bool test_and_set_format_track(struct dasd_format_entry *to_format, ++ struct dasd_block *block) ++{ ++ struct dasd_format_entry *format; ++ unsigned long flags; ++ bool rc = false; ++ ++ spin_lock_irqsave(&block->format_lock, flags); ++ list_for_each_entry(format, &block->format_list, list) { ++ if (format->track == to_format->track) { ++ rc = true; ++ goto out; ++ } ++ } ++ list_add_tail(&to_format->list, &block->format_list); ++ ++out: ++ spin_unlock_irqrestore(&block->format_lock, flags); ++ return rc; ++} ++ ++static void clear_format_track(struct dasd_format_entry *format, ++ struct dasd_block *block) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&block->format_lock, flags); ++ list_del_init(&format->list); ++ spin_unlock_irqrestore(&block->format_lock, flags); ++} ++ + /* + * Callback function to free ESE format requests. + */ +@@ -2993,15 +3063,19 @@ static void dasd_eckd_ese_format_cb(struct dasd_ccw_req *cqr, void *data) + { + struct dasd_device *device = cqr->startdev; + struct dasd_eckd_private *private = device->private; ++ struct dasd_format_entry *format = data; + ++ clear_format_track(format, cqr->basedev->block); + private->count--; + dasd_ffree_request(cqr, device); + } + + static struct dasd_ccw_req * +-dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) ++dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr, ++ struct irb *irb) + { + struct dasd_eckd_private *private; ++ struct dasd_format_entry *format; + struct format_data_t fdata; + unsigned int recs_per_trk; + struct dasd_ccw_req *fcqr; +@@ -3011,23 +3085,39 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) + struct request *req; + sector_t first_trk; + sector_t last_trk; ++ sector_t curr_trk; + int rc; + + req = cqr->callback_data; +- base = cqr->block->base; ++ block = cqr->block; ++ base = block->base; + private = base->private; +- block = base->block; + blksize = block->bp_block; + recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); ++ format = &startdev->format_entry; + + first_trk = blk_rq_pos(req) >> block->s2b_shift; + sector_div(first_trk, recs_per_trk); + last_trk = + (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; + sector_div(last_trk, recs_per_trk); ++ rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); ++ if (rc) ++ return ERR_PTR(rc); + +- fdata.start_unit = first_trk; +- fdata.stop_unit = last_trk; ++ if (curr_trk < first_trk || curr_trk > last_trk) { ++ DBF_DEV_EVENT(DBF_WARNING, startdev, ++ "ESE error track %llu not within range %llu - %llu\n", ++ curr_trk, first_trk, last_trk); ++ return ERR_PTR(-EINVAL); ++ } ++ format->track = curr_trk; ++ /* test if track is already in formatting by another thread */ ++ if (test_and_set_format_track(format, block)) ++ return ERR_PTR(-EEXIST); ++ ++ fdata.start_unit = curr_trk; ++ fdata.stop_unit = curr_trk; + fdata.blksize = blksize; + fdata.intensity = private->uses_cdl ? DASD_FMT_INT_COMPAT : 0; + +@@ -3044,6 +3134,7 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) + return fcqr; + + fcqr->callback = dasd_eckd_ese_format_cb; ++ fcqr->callback_data = (void *) format; + + return fcqr; + } +@@ -3051,29 +3142,87 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) + /* + * When data is read from an unformatted area of an ESE volume, this function + * returns zeroed data and thereby mimics a read of zero data. ++ * ++ * The first unformatted track is the one that got the NRF error, the address is ++ * encoded in the sense data. ++ * ++ * All tracks before have returned valid data and should not be touched. ++ * All tracks after the unformatted track might be formatted or not. This is ++ * currently not known, remember the processed data and return the remainder of ++ * the request to the blocklayer in __dasd_cleanup_cqr(). + */ +-static void dasd_eckd_ese_read(struct dasd_ccw_req *cqr) ++static int dasd_eckd_ese_read(struct dasd_ccw_req *cqr, struct irb *irb) + { ++ struct dasd_eckd_private *private; ++ sector_t first_trk, last_trk; ++ sector_t first_blk, last_blk; + unsigned int blksize, off; ++ unsigned int recs_per_trk; + struct dasd_device *base; + struct req_iterator iter; ++ struct dasd_block *block; ++ unsigned int skip_block; ++ unsigned int blk_count; + struct request *req; + struct bio_vec bv; ++ sector_t curr_trk; ++ sector_t end_blk; + char *dst; ++ int rc; + + req = (struct request *) cqr->callback_data; + base = cqr->block->base; + blksize = base->block->bp_block; ++ block = cqr->block; ++ private = base->private; ++ skip_block = 0; ++ blk_count = 0; ++ ++ recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); ++ first_trk = first_blk = blk_rq_pos(req) >> block->s2b_shift; ++ sector_div(first_trk, recs_per_trk); ++ last_trk = last_blk = ++ (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; ++ sector_div(last_trk, recs_per_trk); ++ rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); ++ if (rc) ++ return rc; ++ ++ /* sanity check if the current track from sense data is valid */ ++ if (curr_trk < first_trk || curr_trk > last_trk) { ++ DBF_DEV_EVENT(DBF_WARNING, base, ++ "ESE error track %llu not within range %llu - %llu\n", ++ curr_trk, first_trk, last_trk); ++ return -EINVAL; ++ } ++ ++ /* ++ * if not the first track got the NRF error we have to skip over valid ++ * blocks ++ */ ++ if (curr_trk != first_trk) ++ skip_block = curr_trk * recs_per_trk - first_blk; ++ ++ /* we have no information beyond the current track */ ++ end_blk = (curr_trk + 1) * recs_per_trk; + + rq_for_each_segment(bv, req, iter) { + dst = page_address(bv.bv_page) + bv.bv_offset; + for (off = 0; off < bv.bv_len; off += blksize) { +- if (dst && rq_data_dir(req) == READ) { ++ if (first_blk + blk_count >= end_blk) { ++ cqr->proc_bytes = blk_count * blksize; ++ return 0; ++ } ++ if (dst && !skip_block) { + dst += off; + memset(dst, 0, blksize); ++ } else { ++ skip_block--; + } ++ blk_count++; + } + } ++ return 0; + } + + /* +diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h +index 91c9f9586e0f..fa552f9f1666 100644 +--- a/drivers/s390/block/dasd_int.h ++++ b/drivers/s390/block/dasd_int.h +@@ -187,6 +187,7 @@ struct dasd_ccw_req { + + void (*callback)(struct dasd_ccw_req *, void *data); + void *callback_data; ++ unsigned int proc_bytes; /* bytes for partial completion */ + }; + + /* +@@ -387,8 +388,9 @@ struct dasd_discipline { + int (*ext_pool_warn_thrshld)(struct dasd_device *); + int (*ext_pool_oos)(struct dasd_device *); + int (*ext_pool_exhaust)(struct dasd_device *, struct dasd_ccw_req *); +- struct dasd_ccw_req *(*ese_format)(struct dasd_device *, struct dasd_ccw_req *); +- void (*ese_read)(struct dasd_ccw_req *); ++ struct dasd_ccw_req *(*ese_format)(struct dasd_device *, ++ struct dasd_ccw_req *, struct irb *); ++ int (*ese_read)(struct dasd_ccw_req *, struct irb *); + }; + + extern struct dasd_discipline *dasd_diag_discipline_pointer; +@@ -474,6 +476,11 @@ struct dasd_profile { + spinlock_t lock; + }; + ++struct dasd_format_entry { ++ struct list_head list; ++ sector_t track; ++}; ++ + struct dasd_device { + /* Block device stuff. */ + struct dasd_block *block; +@@ -539,6 +546,7 @@ struct dasd_device { + struct dentry *debugfs_dentry; + struct dentry *hosts_dentry; + struct dasd_profile profile; ++ struct dasd_format_entry format_entry; + }; + + struct dasd_block { +@@ -564,6 +572,9 @@ struct dasd_block { + + struct dentry *debugfs_dentry; + struct dasd_profile profile; ++ ++ struct list_head format_list; ++ spinlock_t format_lock; + }; + + struct dasd_attention_data { +diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c +index d2c4eb9efd70..7aaf150f89ba 100644 +--- a/drivers/virtio/virtio_balloon.c ++++ b/drivers/virtio/virtio_balloon.c +@@ -958,8 +958,8 @@ out_iput: + iput(vb->vb_dev_info.inode); + out_kern_unmount: + kern_unmount(balloon_mnt); +-#endif + out_del_vqs: ++#endif + vdev->config->del_vqs(vdev); + out_free_vb: + kfree(vb); +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index 867c7ebd3f10..58b96baa8d48 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -2203,10 +2203,10 @@ void vring_del_virtqueue(struct virtqueue *_vq) + vq->split.queue_size_in_bytes, + vq->split.vring.desc, + vq->split.queue_dma_addr); +- +- kfree(vq->split.desc_state); + } + } ++ if (!vq->packed_ring) ++ kfree(vq->split.desc_state); + list_del(&_vq->list); + kfree(vq); + } +diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c +index 7ce689d31aa2..5a35850ccb1a 100644 +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -560,7 +560,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, + if (server->ops->close) + server->ops->close(xid, tcon, &fid); + cifs_del_pending_open(&open); +- fput(file); + rc = -ENOMEM; + } + +diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c +index d71c2d6dd162..75898340eb46 100644 +--- a/fs/crypto/keysetup.c ++++ b/fs/crypto/keysetup.c +@@ -578,6 +578,15 @@ int fscrypt_drop_inode(struct inode *inode) + return 0; + mk = ci->ci_master_key->payload.data[0]; + ++ /* ++ * With proper, non-racy use of FS_IOC_REMOVE_ENCRYPTION_KEY, all inodes ++ * protected by the key were cleaned by sync_filesystem(). But if ++ * userspace is still using the files, inodes can be dirtied between ++ * then and now. We mustn't lose any writes, so skip dirty inodes here. ++ */ ++ if (inode->i_state & I_DIRTY_ALL) ++ return 0; ++ + /* + * Note: since we aren't holding ->mk_secret_sem, the result here can + * immediately become outdated. But there's no correctness problem with +diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c +index ed1abc9e33cf..4f2e4f38feb8 100644 +--- a/fs/fuse/dev.c ++++ b/fs/fuse/dev.c +@@ -276,12 +276,10 @@ static void flush_bg_queue(struct fuse_conn *fc) + void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) + { + struct fuse_iqueue *fiq = &fc->iq; +- bool async; + + if (test_and_set_bit(FR_FINISHED, &req->flags)) + goto put_request; + +- async = req->args->end; + /* + * test_and_set_bit() implies smp_mb() between bit + * changing and below intr_entry check. Pairs with +@@ -324,7 +322,7 @@ void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) + wake_up(&req->waitq); + } + +- if (async) ++ if (test_bit(FR_ASYNC, &req->flags)) + req->args->end(fc, req->args, req->out.h.error); + put_request: + fuse_put_request(fc, req); +@@ -471,6 +469,8 @@ static void fuse_args_to_req(struct fuse_req *req, struct fuse_args *args) + req->in.h.opcode = args->opcode; + req->in.h.nodeid = args->nodeid; + req->args = args; ++ if (args->end) ++ __set_bit(FR_ASYNC, &req->flags); + } + + ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) +diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h +index aa75e2305b75..ca344bf71404 100644 +--- a/fs/fuse/fuse_i.h ++++ b/fs/fuse/fuse_i.h +@@ -301,6 +301,7 @@ struct fuse_io_priv { + * FR_SENT: request is in userspace, waiting for an answer + * FR_FINISHED: request is finished + * FR_PRIVATE: request is on private list ++ * FR_ASYNC: request is asynchronous + */ + enum fuse_req_flag { + FR_ISREPLY, +@@ -314,6 +315,7 @@ enum fuse_req_flag { + FR_SENT, + FR_FINISHED, + FR_PRIVATE, ++ FR_ASYNC, + }; + + /** +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index e1e18fb587eb..8466166f22e3 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -1248,7 +1248,7 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, + if (!(file->f_mode & FMODE_OPENED)) + return finish_no_open(file, d); + dput(d); +- return 0; ++ return excl && (flags & O_CREAT) ? -EEXIST : 0; + } + + BUG_ON(d != NULL); +diff --git a/fs/open.c b/fs/open.c +index b62f5c0923a8..dcbd01611237 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -860,9 +860,6 @@ cleanup_file: + * the return value of d_splice_alias(), then the caller needs to perform dput() + * on it after finish_open(). + * +- * On successful return @file is a fully instantiated open file. After this, if +- * an error occurs in ->atomic_open(), it needs to clean up with fput(). +- * + * Returns zero on success or -errno if the open failed. + */ + int finish_open(struct file *file, struct dentry *dentry, +diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h +index d7b201652f4c..0c7c750fc2c4 100644 +--- a/include/dt-bindings/clock/imx8mn-clock.h ++++ b/include/dt-bindings/clock/imx8mn-clock.h +@@ -122,8 +122,8 @@ + #define IMX8MN_CLK_I2C1 105 + #define IMX8MN_CLK_I2C2 106 + #define IMX8MN_CLK_I2C3 107 +-#define IMX8MN_CLK_I2C4 118 +-#define IMX8MN_CLK_UART1 119 ++#define IMX8MN_CLK_I2C4 108 ++#define IMX8MN_CLK_UART1 109 + #define IMX8MN_CLK_UART2 110 + #define IMX8MN_CLK_UART3 111 + #define IMX8MN_CLK_UART4 112 +diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h +index 3ba3e6da13a6..57577075d204 100644 +--- a/include/linux/cgroup.h ++++ b/include/linux/cgroup.h +@@ -62,6 +62,7 @@ struct css_task_iter { + struct list_head *mg_tasks_head; + struct list_head *dying_tasks_head; + ++ struct list_head *cur_tasks_head; + struct css_set *cur_cset; + struct css_set *cur_dcset; + struct task_struct *cur_task; +diff --git a/include/linux/dmar.h b/include/linux/dmar.h +index a7cf3599d9a1..d3ea390336f3 100644 +--- a/include/linux/dmar.h ++++ b/include/linux/dmar.h +@@ -69,8 +69,9 @@ struct dmar_pci_notify_info { + extern struct rw_semaphore dmar_global_lock; + extern struct list_head dmar_drhd_units; + +-#define for_each_drhd_unit(drhd) \ +- list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) ++#define for_each_drhd_unit(drhd) \ ++ list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ ++ dmar_rcu_check()) + + #define for_each_active_drhd_unit(drhd) \ + list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \ +@@ -81,7 +82,8 @@ extern struct list_head dmar_drhd_units; + if (i=drhd->iommu, drhd->ignored) {} else + + #define for_each_iommu(i, drhd) \ +- list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \ ++ list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ ++ dmar_rcu_check()) \ + if (i=drhd->iommu, 0) {} else + + static inline bool dmar_rcu_check(void) +diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h +index 39faaaf843e1..c91cf2dee12a 100644 +--- a/include/linux/inet_diag.h ++++ b/include/linux/inet_diag.h +@@ -2,15 +2,10 @@ + #ifndef _INET_DIAG_H_ + #define _INET_DIAG_H_ 1 + ++#include + #include + +-struct net; +-struct sock; + struct inet_hashinfo; +-struct nlattr; +-struct nlmsghdr; +-struct sk_buff; +-struct netlink_callback; + + struct inet_diag_handler { + void (*dump)(struct sk_buff *skb, +@@ -62,6 +57,17 @@ int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk); + + void inet_diag_msg_common_fill(struct inet_diag_msg *r, struct sock *sk); + ++static inline size_t inet_diag_msg_attrs_size(void) ++{ ++ return nla_total_size(1) /* INET_DIAG_SHUTDOWN */ ++ + nla_total_size(1) /* INET_DIAG_TOS */ ++#if IS_ENABLED(CONFIG_IPV6) ++ + nla_total_size(1) /* INET_DIAG_TCLASS */ ++ + nla_total_size(1) /* INET_DIAG_SKV6ONLY */ ++#endif ++ + nla_total_size(4) /* INET_DIAG_MARK */ ++ + nla_total_size(4); /* INET_DIAG_CLASS_ID */ ++} + int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb, + struct inet_diag_msg *r, int ext, + struct user_namespace *user_ns, bool net_admin); +diff --git a/include/linux/phy.h b/include/linux/phy.h +index 3d5d53313e6c..80750783b5b0 100644 +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -336,6 +336,7 @@ struct phy_c45_device_ids { + * is_gigabit_capable: Set to true if PHY supports 1000Mbps + * has_fixups: Set to true if this phy has fixups/quirks. + * suspended: Set to true if this phy has been suspended successfully. ++ * suspended_by_mdio_bus: Set to true if this phy was suspended by MDIO bus. + * sysfs_links: Internal boolean tracking sysfs symbolic links setup/removal. + * loopback_enabled: Set true if this phy has been loopbacked successfully. + * state: state of the PHY for management purposes +@@ -372,6 +373,7 @@ struct phy_device { + unsigned is_gigabit_capable:1; + unsigned has_fixups:1; + unsigned suspended:1; ++ unsigned suspended_by_mdio_bus:1; + unsigned sysfs_links:1; + unsigned loopback_enabled:1; + +@@ -524,6 +526,7 @@ struct phy_driver { + /* + * Checks if the PHY generated an interrupt. + * For multi-PHY devices with shared PHY interrupt pin ++ * Set interrupt bits have to be cleared. + */ + int (*did_interrupt)(struct phy_device *phydev); + +diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h +index f2688404d1cd..569f446502be 100644 +--- a/include/linux/platform_device.h ++++ b/include/linux/platform_device.h +@@ -24,7 +24,7 @@ struct platform_device { + int id; + bool id_auto; + struct device dev; +- u64 dma_mask; ++ u64 platform_dma_mask; + u32 num_resources; + struct resource *resource; + +diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h +index 20dcadd8eed9..7fed3193f81d 100644 +--- a/include/net/fib_rules.h ++++ b/include/net/fib_rules.h +@@ -108,6 +108,7 @@ struct fib_rule_notifier_info { + [FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ + [FRA_PRIORITY] = { .type = NLA_U32 }, \ + [FRA_FWMARK] = { .type = NLA_U32 }, \ ++ [FRA_TUN_ID] = { .type = NLA_U64 }, \ + [FRA_FWMASK] = { .type = NLA_U32 }, \ + [FRA_TABLE] = { .type = NLA_U32 }, \ + [FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \ +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index 595c52d59f31..7c9e97553a00 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -4461,12 +4461,16 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it) + } + } while (!css_set_populated(cset) && list_empty(&cset->dying_tasks)); + +- if (!list_empty(&cset->tasks)) ++ if (!list_empty(&cset->tasks)) { + it->task_pos = cset->tasks.next; +- else if (!list_empty(&cset->mg_tasks)) ++ it->cur_tasks_head = &cset->tasks; ++ } else if (!list_empty(&cset->mg_tasks)) { + it->task_pos = cset->mg_tasks.next; +- else ++ it->cur_tasks_head = &cset->mg_tasks; ++ } else { + it->task_pos = cset->dying_tasks.next; ++ it->cur_tasks_head = &cset->dying_tasks; ++ } + + it->tasks_head = &cset->tasks; + it->mg_tasks_head = &cset->mg_tasks; +@@ -4524,10 +4528,14 @@ repeat: + else + it->task_pos = it->task_pos->next; + +- if (it->task_pos == it->tasks_head) ++ if (it->task_pos == it->tasks_head) { + it->task_pos = it->mg_tasks_head->next; +- if (it->task_pos == it->mg_tasks_head) ++ it->cur_tasks_head = it->mg_tasks_head; ++ } ++ if (it->task_pos == it->mg_tasks_head) { + it->task_pos = it->dying_tasks_head->next; ++ it->cur_tasks_head = it->dying_tasks_head; ++ } + if (it->task_pos == it->dying_tasks_head) + css_task_iter_advance_css_set(it); + } else { +@@ -4546,11 +4554,12 @@ repeat: + goto repeat; + + /* and dying leaders w/o live member threads */ +- if (!atomic_read(&task->signal->live)) ++ if (it->cur_tasks_head == it->dying_tasks_head && ++ !atomic_read(&task->signal->live)) + goto repeat; + } else { + /* skip all dying ones */ +- if (task->flags & PF_EXITING) ++ if (it->cur_tasks_head == it->dying_tasks_head) + goto repeat; + } + } +@@ -4659,6 +4668,9 @@ static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos) + struct kernfs_open_file *of = s->private; + struct css_task_iter *it = of->priv; + ++ if (pos) ++ (*pos)++; ++ + return css_task_iter_next(it); + } + +@@ -4674,7 +4686,7 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos, + * from position 0, so we can simply keep iterating on !0 *pos. + */ + if (!it) { +- if (WARN_ON_ONCE((*pos)++)) ++ if (WARN_ON_ONCE((*pos))) + return ERR_PTR(-EINVAL); + + it = kzalloc(sizeof(*it), GFP_KERNEL); +@@ -4682,10 +4694,11 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos, + return ERR_PTR(-ENOMEM); + of->priv = it; + css_task_iter_start(&cgrp->self, iter_flags, it); +- } else if (!(*pos)++) { ++ } else if (!(*pos)) { + css_task_iter_end(it); + css_task_iter_start(&cgrp->self, iter_flags, it); +- } ++ } else ++ return it->cur_task; + + return cgroup_procs_next(s, NULL, NULL); + } +@@ -6381,6 +6394,10 @@ void cgroup_sk_alloc(struct sock_cgroup_data *skcd) + return; + } + ++ /* Don't associate the sock with unrelated interrupted task's cgroup. */ ++ if (in_interrupt()) ++ return; ++ + rcu_read_lock(); + + while (true) { +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index e9c63b79e03f..1a0c224af6fb 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -1417,14 +1417,16 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, + return; + rcu_read_lock(); + retry: +- if (req_cpu == WORK_CPU_UNBOUND) +- cpu = wq_select_unbound_cpu(raw_smp_processor_id()); +- + /* pwq which will be used unless @work is executing elsewhere */ +- if (!(wq->flags & WQ_UNBOUND)) +- pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); +- else ++ if (wq->flags & WQ_UNBOUND) { ++ if (req_cpu == WORK_CPU_UNBOUND) ++ cpu = wq_select_unbound_cpu(raw_smp_processor_id()); + pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu)); ++ } else { ++ if (req_cpu == WORK_CPU_UNBOUND) ++ cpu = raw_smp_processor_id(); ++ pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); ++ } + + /* + * If @work was previously on a different pool, it might still be +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index ae9044bc9f80..23c99c6778d3 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -6792,19 +6792,9 @@ void mem_cgroup_sk_alloc(struct sock *sk) + if (!mem_cgroup_sockets_enabled) + return; + +- /* +- * Socket cloning can throw us here with sk_memcg already +- * filled. It won't however, necessarily happen from +- * process context. So the test for root memcg given +- * the current task's memcg won't help us in this case. +- * +- * Respecting the original socket's memcg is a better +- * decision in this case. +- */ +- if (sk->sk_memcg) { +- css_get(&sk->sk_memcg->css); ++ /* Do not associate the sock with unrelated interrupted task's memcg. */ ++ if (in_interrupt()) + return; +- } + + rcu_read_lock(); + memcg = mem_cgroup_from_task(current); +diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c +index 5b0b20e6da95..d88a4de02237 100644 +--- a/net/batman-adv/bat_iv_ogm.c ++++ b/net/batman-adv/bat_iv_ogm.c +@@ -789,6 +789,10 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface) + + lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex); + ++ /* interface already disabled by batadv_iv_ogm_iface_disable */ ++ if (!*ogm_buff) ++ return; ++ + /* the interface gets activated here to avoid race conditions between + * the moment of activating the interface in + * hardif_activate_interface() where the originator mac is set and +diff --git a/net/core/devlink.c b/net/core/devlink.c +index 61bc67047f56..4c25f1aa2d37 100644 +--- a/net/core/devlink.c ++++ b/net/core/devlink.c +@@ -3222,34 +3222,41 @@ devlink_param_value_get_from_info(const struct devlink_param *param, + struct genl_info *info, + union devlink_param_value *value) + { ++ struct nlattr *param_data; + int len; + +- if (param->type != DEVLINK_PARAM_TYPE_BOOL && +- !info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) ++ param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]; ++ ++ if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data) + return -EINVAL; + + switch (param->type) { + case DEVLINK_PARAM_TYPE_U8: +- value->vu8 = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); ++ if (nla_len(param_data) != sizeof(u8)) ++ return -EINVAL; ++ value->vu8 = nla_get_u8(param_data); + break; + case DEVLINK_PARAM_TYPE_U16: +- value->vu16 = nla_get_u16(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); ++ if (nla_len(param_data) != sizeof(u16)) ++ return -EINVAL; ++ value->vu16 = nla_get_u16(param_data); + break; + case DEVLINK_PARAM_TYPE_U32: +- value->vu32 = nla_get_u32(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); ++ if (nla_len(param_data) != sizeof(u32)) ++ return -EINVAL; ++ value->vu32 = nla_get_u32(param_data); + break; + case DEVLINK_PARAM_TYPE_STRING: +- len = strnlen(nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]), +- nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])); +- if (len == nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) || ++ len = strnlen(nla_data(param_data), nla_len(param_data)); ++ if (len == nla_len(param_data) || + len >= __DEVLINK_PARAM_MAX_STRING_VALUE) + return -EINVAL; +- strcpy(value->vstr, +- nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])); ++ strcpy(value->vstr, nla_data(param_data)); + break; + case DEVLINK_PARAM_TYPE_BOOL: +- value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ? +- true : false; ++ if (param_data && nla_len(param_data)) ++ return -EINVAL; ++ value->vbool = nla_get_flag(param_data); + break; + } + return 0; +@@ -5797,6 +5804,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 }, + [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING }, + [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 }, ++ [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .type = NLA_U64 }, ++ [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .type = NLA_U64 }, + [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING }, + [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 }, + [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 }, +diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c +index 0642f91c4038..b4c87fe31be2 100644 +--- a/net/core/netclassid_cgroup.c ++++ b/net/core/netclassid_cgroup.c +@@ -53,30 +53,60 @@ static void cgrp_css_free(struct cgroup_subsys_state *css) + kfree(css_cls_state(css)); + } + ++/* ++ * To avoid freezing of sockets creation for tasks with big number of threads ++ * and opened sockets lets release file_lock every 1000 iterated descriptors. ++ * New sockets will already have been created with new classid. ++ */ ++ ++struct update_classid_context { ++ u32 classid; ++ unsigned int batch; ++}; ++ ++#define UPDATE_CLASSID_BATCH 1000 ++ + static int update_classid_sock(const void *v, struct file *file, unsigned n) + { + int err; ++ struct update_classid_context *ctx = (void *)v; + struct socket *sock = sock_from_file(file, &err); + + if (sock) { + spin_lock(&cgroup_sk_update_lock); +- sock_cgroup_set_classid(&sock->sk->sk_cgrp_data, +- (unsigned long)v); ++ sock_cgroup_set_classid(&sock->sk->sk_cgrp_data, ctx->classid); + spin_unlock(&cgroup_sk_update_lock); + } ++ if (--ctx->batch == 0) { ++ ctx->batch = UPDATE_CLASSID_BATCH; ++ return n + 1; ++ } + return 0; + } + ++static void update_classid_task(struct task_struct *p, u32 classid) ++{ ++ struct update_classid_context ctx = { ++ .classid = classid, ++ .batch = UPDATE_CLASSID_BATCH ++ }; ++ unsigned int fd = 0; ++ ++ do { ++ task_lock(p); ++ fd = iterate_fd(p->files, fd, update_classid_sock, &ctx); ++ task_unlock(p); ++ cond_resched(); ++ } while (fd); ++} ++ + static void cgrp_attach(struct cgroup_taskset *tset) + { + struct cgroup_subsys_state *css; + struct task_struct *p; + + cgroup_taskset_for_each(p, css, tset) { +- task_lock(p); +- iterate_fd(p->files, 0, update_classid_sock, +- (void *)(unsigned long)css_cls_state(css)->classid); +- task_unlock(p); ++ update_classid_task(p, css_cls_state(css)->classid); + } + } + +@@ -98,10 +128,7 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft, + + css_task_iter_start(css, 0, &it); + while ((p = css_task_iter_next(&it))) { +- task_lock(p); +- iterate_fd(p->files, 0, update_classid_sock, +- (void *)(unsigned long)cs->classid); +- task_unlock(p); ++ update_classid_task(p, cs->classid); + cond_resched(); + } + css_task_iter_end(&it); +diff --git a/net/core/sock.c b/net/core/sock.c +index b4d1112174c1..0adf7a9e5a90 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1832,7 +1832,10 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) + atomic_set(&newsk->sk_zckey, 0); + + sock_reset_flag(newsk, SOCK_DONE); +- mem_cgroup_sk_alloc(newsk); ++ ++ /* sk->sk_memcg will be populated at accept() time */ ++ newsk->sk_memcg = NULL; ++ + cgroup_sk_alloc(&newsk->sk_cgrp_data); + + rcu_read_lock(); +diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h +index 12f8c7ee4dd8..bf9947c577b6 100644 +--- a/net/dsa/dsa_priv.h ++++ b/net/dsa/dsa_priv.h +@@ -128,7 +128,9 @@ static inline struct net_device *dsa_master_find_slave(struct net_device *dev, + /* port.c */ + int dsa_port_set_state(struct dsa_port *dp, u8 state, + struct switchdev_trans *trans); ++int dsa_port_enable_rt(struct dsa_port *dp, struct phy_device *phy); + int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy); ++void dsa_port_disable_rt(struct dsa_port *dp); + void dsa_port_disable(struct dsa_port *dp); + int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br); + void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br); +diff --git a/net/dsa/port.c b/net/dsa/port.c +index 9b54e5a76297..fa023af69bc4 100644 +--- a/net/dsa/port.c ++++ b/net/dsa/port.c +@@ -63,7 +63,7 @@ static void dsa_port_set_state_now(struct dsa_port *dp, u8 state) + pr_err("DSA: failed to set STP state %u (%d)\n", state, err); + } + +-int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy) ++int dsa_port_enable_rt(struct dsa_port *dp, struct phy_device *phy) + { + struct dsa_switch *ds = dp->ds; + int port = dp->index; +@@ -78,14 +78,31 @@ int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy) + if (!dp->bridge_dev) + dsa_port_set_state_now(dp, BR_STATE_FORWARDING); + ++ if (dp->pl) ++ phylink_start(dp->pl); ++ + return 0; + } + +-void dsa_port_disable(struct dsa_port *dp) ++int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy) ++{ ++ int err; ++ ++ rtnl_lock(); ++ err = dsa_port_enable_rt(dp, phy); ++ rtnl_unlock(); ++ ++ return err; ++} ++ ++void dsa_port_disable_rt(struct dsa_port *dp) + { + struct dsa_switch *ds = dp->ds; + int port = dp->index; + ++ if (dp->pl) ++ phylink_stop(dp->pl); ++ + if (!dp->bridge_dev) + dsa_port_set_state_now(dp, BR_STATE_DISABLED); + +@@ -93,6 +110,13 @@ void dsa_port_disable(struct dsa_port *dp) + ds->ops->port_disable(ds, port); + } + ++void dsa_port_disable(struct dsa_port *dp) ++{ ++ rtnl_lock(); ++ dsa_port_disable_rt(dp); ++ rtnl_unlock(); ++} ++ + int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br) + { + struct dsa_notifier_bridge_info info = { +@@ -615,10 +639,6 @@ static int dsa_port_phylink_register(struct dsa_port *dp) + goto err_phy_connect; + } + +- rtnl_lock(); +- phylink_start(dp->pl); +- rtnl_unlock(); +- + return 0; + + err_phy_connect: +@@ -629,9 +649,14 @@ err_phy_connect: + int dsa_port_link_register_of(struct dsa_port *dp) + { + struct dsa_switch *ds = dp->ds; ++ struct device_node *phy_np; + +- if (!ds->ops->adjust_link) +- return dsa_port_phylink_register(dp); ++ if (!ds->ops->adjust_link) { ++ phy_np = of_parse_phandle(dp->dn, "phy-handle", 0); ++ if (of_phy_is_fixed_link(dp->dn) || phy_np) ++ return dsa_port_phylink_register(dp); ++ return 0; ++ } + + dev_warn(ds->dev, + "Using legacy PHYLIB callbacks. Please migrate to PHYLINK!\n"); +@@ -646,11 +671,12 @@ void dsa_port_link_unregister_of(struct dsa_port *dp) + { + struct dsa_switch *ds = dp->ds; + +- if (!ds->ops->adjust_link) { ++ if (!ds->ops->adjust_link && dp->pl) { + rtnl_lock(); + phylink_disconnect_phy(dp->pl); + rtnl_unlock(); + phylink_destroy(dp->pl); ++ dp->pl = NULL; + return; + } + +diff --git a/net/dsa/slave.c b/net/dsa/slave.c +index 028e65f4b5ba..23c2210fa7ec 100644 +--- a/net/dsa/slave.c ++++ b/net/dsa/slave.c +@@ -90,12 +90,10 @@ static int dsa_slave_open(struct net_device *dev) + goto clear_allmulti; + } + +- err = dsa_port_enable(dp, dev->phydev); ++ err = dsa_port_enable_rt(dp, dev->phydev); + if (err) + goto clear_promisc; + +- phylink_start(dp->pl); +- + return 0; + + clear_promisc: +@@ -119,9 +117,7 @@ static int dsa_slave_close(struct net_device *dev) + cancel_work_sync(&dp->xmit_work); + skb_queue_purge(&dp->xmit_queue); + +- phylink_stop(dp->pl); +- +- dsa_port_disable(dp); ++ dsa_port_disable_rt(dp); + + dev_mc_unsync(master, dev); + dev_uc_unsync(master, dev); +diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c +index 2c7a38d76a3a..0672b2f01586 100644 +--- a/net/ieee802154/nl_policy.c ++++ b/net/ieee802154/nl_policy.c +@@ -21,7 +21,13 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = { + [IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, }, + [IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, }, + [IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_BCN_ORD] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_SF_ORD] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_PAN_COORD] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_BAT_EXT] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_COORD_REALIGN] = { .type = NLA_U8, }, + [IEEE802154_ATTR_PAGE] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_DEV_TYPE] = { .type = NLA_U8, }, + [IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, }, + [IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, }, + [IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, }, +diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c +index 5fd6e8ed02b5..66fdbfe5447c 100644 +--- a/net/ipv4/gre_demux.c ++++ b/net/ipv4/gre_demux.c +@@ -56,7 +56,9 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version) + } + EXPORT_SYMBOL_GPL(gre_del_protocol); + +-/* Fills in tpi and returns header length to be pulled. */ ++/* Fills in tpi and returns header length to be pulled. ++ * Note that caller must use pskb_may_pull() before pulling GRE header. ++ */ + int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, + bool *csum_err, __be16 proto, int nhs) + { +@@ -110,8 +112,14 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, + * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header + */ + if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) { ++ u8 _val, *val; ++ ++ val = skb_header_pointer(skb, nhs + hdr_len, ++ sizeof(_val), &_val); ++ if (!val) ++ return -EINVAL; + tpi->proto = proto; +- if ((*(u8 *)options & 0xF0) != 0x40) ++ if ((*val & 0xF0) != 0x40) + hdr_len += 4; + } + tpi->hdr_len = hdr_len; +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index ac05e273bc66..b0010c710802 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -482,8 +482,28 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern) + } + spin_unlock_bh(&queue->fastopenq.lock); + } ++ + out: + release_sock(sk); ++ if (newsk && mem_cgroup_sockets_enabled) { ++ int amt; ++ ++ /* atomically get the memory usage, set and charge the ++ * newsk->sk_memcg. ++ */ ++ lock_sock(newsk); ++ ++ /* The socket has not been accepted yet, no need to look at ++ * newsk->sk_wmem_queued. ++ */ ++ amt = sk_mem_pages(newsk->sk_forward_alloc + ++ atomic_read(&newsk->sk_rmem_alloc)); ++ mem_cgroup_sk_alloc(newsk); ++ if (newsk->sk_memcg && amt) ++ mem_cgroup_charge_skmem(newsk->sk_memcg, amt); ++ ++ release_sock(newsk); ++ } + if (req) + reqsk_put(req); + return newsk; +diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c +index 6a4c82f96e78..5b68bdaa8bff 100644 +--- a/net/ipv4/inet_diag.c ++++ b/net/ipv4/inet_diag.c +@@ -100,13 +100,9 @@ static size_t inet_sk_attr_size(struct sock *sk, + aux = handler->idiag_get_aux_size(sk, net_admin); + + return nla_total_size(sizeof(struct tcp_info)) +- + nla_total_size(1) /* INET_DIAG_SHUTDOWN */ +- + nla_total_size(1) /* INET_DIAG_TOS */ +- + nla_total_size(1) /* INET_DIAG_TCLASS */ +- + nla_total_size(4) /* INET_DIAG_MARK */ +- + nla_total_size(4) /* INET_DIAG_CLASS_ID */ +- + nla_total_size(sizeof(struct inet_diag_meminfo)) + + nla_total_size(sizeof(struct inet_diag_msg)) ++ + inet_diag_msg_attrs_size() ++ + nla_total_size(sizeof(struct inet_diag_meminfo)) + + nla_total_size(SK_MEMINFO_VARS * sizeof(u32)) + + nla_total_size(TCP_CA_NAME_MAX) + + nla_total_size(sizeof(struct tcpvegas_info)) +@@ -147,6 +143,24 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb, + if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, sk->sk_mark)) + goto errout; + ++ if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) || ++ ext & (1 << (INET_DIAG_TCLASS - 1))) { ++ u32 classid = 0; ++ ++#ifdef CONFIG_SOCK_CGROUP_DATA ++ classid = sock_cgroup_classid(&sk->sk_cgrp_data); ++#endif ++ /* Fallback to socket priority if class id isn't set. ++ * Classful qdiscs use it as direct reference to class. ++ * For cgroup2 classid is always zero. ++ */ ++ if (!classid) ++ classid = sk->sk_priority; ++ ++ if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid)) ++ goto errout; ++ } ++ + r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk)); + r->idiag_inode = sock_i_ino(sk); + +@@ -284,24 +298,6 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, + goto errout; + } + +- if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) || +- ext & (1 << (INET_DIAG_TCLASS - 1))) { +- u32 classid = 0; +- +-#ifdef CONFIG_SOCK_CGROUP_DATA +- classid = sock_cgroup_classid(&sk->sk_cgrp_data); +-#endif +- /* Fallback to socket priority if class id isn't set. +- * Classful qdiscs use it as direct reference to class. +- * For cgroup2 classid is always zero. +- */ +- if (!classid) +- classid = sk->sk_priority; +- +- if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid)) +- goto errout; +- } +- + out: + nlmsg_end(skb, nlh); + return 0; +diff --git a/net/ipv4/raw_diag.c b/net/ipv4/raw_diag.c +index e35736b99300..a93e7d1e1251 100644 +--- a/net/ipv4/raw_diag.c ++++ b/net/ipv4/raw_diag.c +@@ -100,8 +100,9 @@ static int raw_diag_dump_one(struct sk_buff *in_skb, + if (IS_ERR(sk)) + return PTR_ERR(sk); + +- rep = nlmsg_new(sizeof(struct inet_diag_msg) + +- sizeof(struct inet_diag_meminfo) + 64, ++ rep = nlmsg_new(nla_total_size(sizeof(struct inet_diag_msg)) + ++ inet_diag_msg_attrs_size() + ++ nla_total_size(sizeof(struct inet_diag_meminfo)) + 64, + GFP_KERNEL); + if (!rep) { + sock_put(sk); +diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c +index 910555a4d9fe..dccd2286bc28 100644 +--- a/net/ipv4/udp_diag.c ++++ b/net/ipv4/udp_diag.c +@@ -64,8 +64,9 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, + goto out; + + err = -ENOMEM; +- rep = nlmsg_new(sizeof(struct inet_diag_msg) + +- sizeof(struct inet_diag_meminfo) + 64, ++ rep = nlmsg_new(nla_total_size(sizeof(struct inet_diag_msg)) + ++ inet_diag_msg_attrs_size() + ++ nla_total_size(sizeof(struct inet_diag_meminfo)) + 64, + GFP_KERNEL); + if (!rep) + goto out; +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index b11ccb53c7e0..d02ccd749a60 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1226,11 +1226,13 @@ check_cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long *expires) + } + + static void +-cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, bool del_rt) ++cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, ++ bool del_rt, bool del_peer) + { + struct fib6_info *f6i; + +- f6i = addrconf_get_prefix_route(&ifp->addr, ifp->prefix_len, ++ f6i = addrconf_get_prefix_route(del_peer ? &ifp->peer_addr : &ifp->addr, ++ ifp->prefix_len, + ifp->idev->dev, 0, RTF_DEFAULT, true); + if (f6i) { + if (del_rt) +@@ -1293,7 +1295,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) + + if (action != CLEANUP_PREFIX_RT_NOP) { + cleanup_prefix_route(ifp, expires, +- action == CLEANUP_PREFIX_RT_DEL); ++ action == CLEANUP_PREFIX_RT_DEL, false); + } + + /* clean up prefsrc entries */ +@@ -3345,6 +3347,10 @@ static void addrconf_dev_config(struct net_device *dev) + (dev->type != ARPHRD_NONE) && + (dev->type != ARPHRD_RAWIP)) { + /* Alas, we support only Ethernet autoconfiguration. */ ++ idev = __in6_dev_get(dev); ++ if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP && ++ dev->flags & IFF_MULTICAST) ++ ipv6_mc_up(idev); + return; + } + +@@ -4586,12 +4592,14 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, + } + + static int modify_prefix_route(struct inet6_ifaddr *ifp, +- unsigned long expires, u32 flags) ++ unsigned long expires, u32 flags, ++ bool modify_peer) + { + struct fib6_info *f6i; + u32 prio; + +- f6i = addrconf_get_prefix_route(&ifp->addr, ifp->prefix_len, ++ f6i = addrconf_get_prefix_route(modify_peer ? &ifp->peer_addr : &ifp->addr, ++ ifp->prefix_len, + ifp->idev->dev, 0, RTF_DEFAULT, true); + if (!f6i) + return -ENOENT; +@@ -4602,7 +4610,8 @@ static int modify_prefix_route(struct inet6_ifaddr *ifp, + ip6_del_rt(dev_net(ifp->idev->dev), f6i); + + /* add new one */ +- addrconf_prefix_route(&ifp->addr, ifp->prefix_len, ++ addrconf_prefix_route(modify_peer ? &ifp->peer_addr : &ifp->addr, ++ ifp->prefix_len, + ifp->rt_priority, ifp->idev->dev, + expires, flags, GFP_KERNEL); + } else { +@@ -4624,6 +4633,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg) + unsigned long timeout; + bool was_managetempaddr; + bool had_prefixroute; ++ bool new_peer = false; + + ASSERT_RTNL(); + +@@ -4655,6 +4665,13 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg) + cfg->preferred_lft = timeout; + } + ++ if (cfg->peer_pfx && ++ memcmp(&ifp->peer_addr, cfg->peer_pfx, sizeof(struct in6_addr))) { ++ if (!ipv6_addr_any(&ifp->peer_addr)) ++ cleanup_prefix_route(ifp, expires, true, true); ++ new_peer = true; ++ } ++ + spin_lock_bh(&ifp->lock); + was_managetempaddr = ifp->flags & IFA_F_MANAGETEMPADDR; + had_prefixroute = ifp->flags & IFA_F_PERMANENT && +@@ -4670,6 +4687,9 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg) + if (cfg->rt_priority && cfg->rt_priority != ifp->rt_priority) + ifp->rt_priority = cfg->rt_priority; + ++ if (new_peer) ++ ifp->peer_addr = *cfg->peer_pfx; ++ + spin_unlock_bh(&ifp->lock); + if (!(ifp->flags&IFA_F_TENTATIVE)) + ipv6_ifa_notify(0, ifp); +@@ -4678,7 +4698,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg) + int rc = -ENOENT; + + if (had_prefixroute) +- rc = modify_prefix_route(ifp, expires, flags); ++ rc = modify_prefix_route(ifp, expires, flags, false); + + /* prefix route could have been deleted; if so restore it */ + if (rc == -ENOENT) { +@@ -4686,6 +4706,15 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg) + ifp->rt_priority, ifp->idev->dev, + expires, flags, GFP_KERNEL); + } ++ ++ if (had_prefixroute && !ipv6_addr_any(&ifp->peer_addr)) ++ rc = modify_prefix_route(ifp, expires, flags, true); ++ ++ if (rc == -ENOENT && !ipv6_addr_any(&ifp->peer_addr)) { ++ addrconf_prefix_route(&ifp->peer_addr, ifp->prefix_len, ++ ifp->rt_priority, ifp->idev->dev, ++ expires, flags, GFP_KERNEL); ++ } + } else if (had_prefixroute) { + enum cleanup_prefix_rt_t action; + unsigned long rt_expires; +@@ -4696,7 +4725,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, struct ifa6_config *cfg) + + if (action != CLEANUP_PREFIX_RT_NOP) { + cleanup_prefix_route(ifp, rt_expires, +- action == CLEANUP_PREFIX_RT_DEL); ++ action == CLEANUP_PREFIX_RT_DEL, false); + } + } + +@@ -5984,9 +6013,9 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) + if (ifp->idev->cnf.forwarding) + addrconf_join_anycast(ifp); + if (!ipv6_addr_any(&ifp->peer_addr)) +- addrconf_prefix_route(&ifp->peer_addr, 128, 0, +- ifp->idev->dev, 0, 0, +- GFP_ATOMIC); ++ addrconf_prefix_route(&ifp->peer_addr, 128, ++ ifp->rt_priority, ifp->idev->dev, ++ 0, 0, GFP_ATOMIC); + break; + case RTM_DELADDR: + if (ifp->idev->cnf.forwarding) +diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c +index 79fc012dd2ca..debdaeba5d8c 100644 +--- a/net/ipv6/ipv6_sockglue.c ++++ b/net/ipv6/ipv6_sockglue.c +@@ -183,9 +183,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, + retv = -EBUSY; + break; + } +- } else if (sk->sk_protocol != IPPROTO_TCP) ++ } else if (sk->sk_protocol == IPPROTO_TCP) { ++ if (sk->sk_prot != &tcpv6_prot) { ++ retv = -EBUSY; ++ break; ++ } + break; +- ++ } else { ++ break; ++ } + if (sk->sk_state != TCP_ESTABLISHED) { + retv = -ENOTCONN; + break; +diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c +index 410809c669e1..4912069627b6 100644 +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -411,7 +411,7 @@ static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) + *pos = cpu + 1; + return per_cpu_ptr(net->ct.stat, cpu); + } +- ++ (*pos)++; + return NULL; + } + +diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c +index b0930d4aba22..b9cbe1e2453e 100644 +--- a/net/netfilter/nf_synproxy_core.c ++++ b/net/netfilter/nf_synproxy_core.c +@@ -267,7 +267,7 @@ static void *synproxy_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) + *pos = cpu + 1; + return per_cpu_ptr(snet->stats, cpu); + } +- ++ (*pos)++; + return NULL; + } + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 23544842b692..068daff41f6e 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -1309,6 +1309,11 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net, + lockdep_commit_lock_is_held(net)); + if (nft_dump_stats(skb, stats)) + goto nla_put_failure; ++ ++ if ((chain->flags & NFT_CHAIN_HW_OFFLOAD) && ++ nla_put_be32(skb, NFTA_CHAIN_FLAGS, ++ htonl(NFT_CHAIN_HW_OFFLOAD))) ++ goto nla_put_failure; + } + + if (nla_put_be32(skb, NFTA_CHAIN_USE, htonl(chain->use))) +@@ -6970,13 +6975,8 @@ static void nf_tables_module_autoload(struct net *net) + list_splice_init(&net->nft.module_list, &module_list); + mutex_unlock(&net->nft.commit_mutex); + list_for_each_entry_safe(req, next, &module_list, list) { +- if (req->done) { +- list_del(&req->list); +- kfree(req); +- } else { +- request_module("%s", req->module); +- req->done = true; +- } ++ request_module("%s", req->module); ++ req->done = true; + } + mutex_lock(&net->nft.commit_mutex); + list_splice(&module_list, &net->nft.module_list); +@@ -7759,6 +7759,7 @@ static void __net_exit nf_tables_exit_net(struct net *net) + __nft_release_tables(net); + mutex_unlock(&net->nft.commit_mutex); + WARN_ON_ONCE(!list_empty(&net->nft.tables)); ++ WARN_ON_ONCE(!list_empty(&net->nft.module_list)); + } + + static struct pernet_operations nf_tables_net_ops = { +diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c +index 7525063c25f5..60838d5fb8e0 100644 +--- a/net/netfilter/nfnetlink_cthelper.c ++++ b/net/netfilter/nfnetlink_cthelper.c +@@ -742,6 +742,8 @@ static const struct nla_policy nfnl_cthelper_policy[NFCTH_MAX+1] = { + [NFCTH_NAME] = { .type = NLA_NUL_STRING, + .len = NF_CT_HELPER_NAME_LEN-1 }, + [NFCTH_QUEUE_NUM] = { .type = NLA_U32, }, ++ [NFCTH_PRIV_DATA_LEN] = { .type = NLA_U32, }, ++ [NFCTH_STATUS] = { .type = NLA_U32, }, + }; + + static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = { +diff --git a/net/netfilter/nft_chain_nat.c b/net/netfilter/nft_chain_nat.c +index ff9ac8ae0031..eac4a901233f 100644 +--- a/net/netfilter/nft_chain_nat.c ++++ b/net/netfilter/nft_chain_nat.c +@@ -89,6 +89,7 @@ static const struct nft_chain_type nft_chain_nat_inet = { + .name = "nat", + .type = NFT_CHAIN_T_NAT, + .family = NFPROTO_INET, ++ .owner = THIS_MODULE, + .hook_mask = (1 << NF_INET_PRE_ROUTING) | + (1 << NF_INET_LOCAL_IN) | + (1 << NF_INET_LOCAL_OUT) | +diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c +index 5cb2d8908d2a..0e3bfbc26e79 100644 +--- a/net/netfilter/nft_payload.c ++++ b/net/netfilter/nft_payload.c +@@ -121,6 +121,7 @@ static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = { + [NFTA_PAYLOAD_LEN] = { .type = NLA_U32 }, + [NFTA_PAYLOAD_CSUM_TYPE] = { .type = NLA_U32 }, + [NFTA_PAYLOAD_CSUM_OFFSET] = { .type = NLA_U32 }, ++ [NFTA_PAYLOAD_CSUM_FLAGS] = { .type = NLA_U32 }, + }; + + static int nft_payload_init(const struct nft_ctx *ctx, +diff --git a/net/netfilter/nft_tunnel.c b/net/netfilter/nft_tunnel.c +index 037e8fce9b30..1effd4878619 100644 +--- a/net/netfilter/nft_tunnel.c ++++ b/net/netfilter/nft_tunnel.c +@@ -339,6 +339,8 @@ static const struct nla_policy nft_tunnel_key_policy[NFTA_TUNNEL_KEY_MAX + 1] = + [NFTA_TUNNEL_KEY_FLAGS] = { .type = NLA_U32, }, + [NFTA_TUNNEL_KEY_TOS] = { .type = NLA_U8, }, + [NFTA_TUNNEL_KEY_TTL] = { .type = NLA_U8, }, ++ [NFTA_TUNNEL_KEY_SPORT] = { .type = NLA_U16, }, ++ [NFTA_TUNNEL_KEY_DPORT] = { .type = NLA_U16, }, + [NFTA_TUNNEL_KEY_OPTS] = { .type = NLA_NESTED, }, + }; + +diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c +index ce70c2576bb2..44f971f31992 100644 +--- a/net/netfilter/x_tables.c ++++ b/net/netfilter/x_tables.c +@@ -1551,6 +1551,9 @@ static void *xt_mttg_seq_next(struct seq_file *seq, void *v, loff_t *ppos, + uint8_t nfproto = (unsigned long)PDE_DATA(file_inode(seq->file)); + struct nf_mttg_trav *trav = seq->private; + ++ if (ppos != NULL) ++ ++(*ppos); ++ + switch (trav->class) { + case MTTG_TRAV_INIT: + trav->class = MTTG_TRAV_NFP_UNSPEC; +@@ -1576,9 +1579,6 @@ static void *xt_mttg_seq_next(struct seq_file *seq, void *v, loff_t *ppos, + default: + return NULL; + } +- +- if (ppos != NULL) +- ++*ppos; + return trav; + } + +diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c +index 781e0b482189..6c2582a19766 100644 +--- a/net/netfilter/xt_recent.c ++++ b/net/netfilter/xt_recent.c +@@ -492,12 +492,12 @@ static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos) + const struct recent_entry *e = v; + const struct list_head *head = e->list.next; + ++ (*pos)++; + while (head == &t->iphash[st->bucket]) { + if (++st->bucket >= ip_list_hash_size) + return NULL; + head = t->iphash[st->bucket].next; + } +- (*pos)++; + return list_entry(head, struct recent_entry, list); + } + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index e64b8784d487..c2a5174387ff 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -2434,7 +2434,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, + in_skb->len)) + WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, + (u8 *)extack->bad_attr - +- in_skb->data)); ++ (u8 *)nlh)); + } else { + if (extack->cookie_len) + WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE, +diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c +index 6f1b096e601c..43811b5219b5 100644 +--- a/net/nfc/hci/core.c ++++ b/net/nfc/hci/core.c +@@ -181,13 +181,20 @@ exit: + void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, + struct sk_buff *skb) + { +- u8 gate = hdev->pipes[pipe].gate; + u8 status = NFC_HCI_ANY_OK; + struct hci_create_pipe_resp *create_info; + struct hci_delete_pipe_noti *delete_info; + struct hci_all_pipe_cleared_noti *cleared_info; ++ u8 gate; + +- pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd); ++ pr_debug("from pipe %x cmd %x\n", pipe, cmd); ++ ++ if (pipe >= NFC_HCI_MAX_PIPES) { ++ status = NFC_HCI_ANY_E_NOK; ++ goto exit; ++ } ++ ++ gate = hdev->pipes[pipe].gate; + + switch (cmd) { + case NFC_HCI_ADM_NOTIFY_PIPE_CREATED: +@@ -375,8 +382,14 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, + struct sk_buff *skb) + { + int r = 0; +- u8 gate = hdev->pipes[pipe].gate; ++ u8 gate; ++ ++ if (pipe >= NFC_HCI_MAX_PIPES) { ++ pr_err("Discarded event %x to invalid pipe %x\n", event, pipe); ++ goto exit; ++ } + ++ gate = hdev->pipes[pipe].gate; + if (gate == NFC_HCI_INVALID_GATE) { + pr_err("Discarded event %x to unopened pipe %x\n", event, pipe); + goto exit; +diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c +index afde0d763039..1b261375722e 100644 +--- a/net/nfc/netlink.c ++++ b/net/nfc/netlink.c +@@ -32,6 +32,7 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { + [NFC_ATTR_DEVICE_NAME] = { .type = NLA_STRING, + .len = NFC_DEVICE_NAME_MAXSIZE }, + [NFC_ATTR_PROTOCOLS] = { .type = NLA_U32 }, ++ [NFC_ATTR_TARGET_INDEX] = { .type = NLA_U32 }, + [NFC_ATTR_COMM_MODE] = { .type = NLA_U8 }, + [NFC_ATTR_RF_MODE] = { .type = NLA_U8 }, + [NFC_ATTR_DEVICE_POWERED] = { .type = NLA_U8 }, +@@ -43,7 +44,10 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { + [NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED }, + [NFC_ATTR_FIRMWARE_NAME] = { .type = NLA_STRING, + .len = NFC_FIRMWARE_NAME_MAXSIZE }, ++ [NFC_ATTR_SE_INDEX] = { .type = NLA_U32 }, + [NFC_ATTR_SE_APDU] = { .type = NLA_BINARY }, ++ [NFC_ATTR_VENDOR_ID] = { .type = NLA_U32 }, ++ [NFC_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 }, + [NFC_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, + + }; +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 118cd66b7516..20edb7c25e22 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2273,6 +2273,13 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, + TP_STATUS_KERNEL, (macoff+snaplen)); + if (!h.raw) + goto drop_n_account; ++ ++ if (do_vnet && ++ virtio_net_hdr_from_skb(skb, h.raw + macoff - ++ sizeof(struct virtio_net_hdr), ++ vio_le(), true, 0)) ++ goto drop_n_account; ++ + if (po->tp_version <= TPACKET_V2) { + packet_increment_rx_head(po, &po->rx_ring); + /* +@@ -2285,12 +2292,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, + status |= TP_STATUS_LOSING; + } + +- if (do_vnet && +- virtio_net_hdr_from_skb(skb, h.raw + macoff - +- sizeof(struct virtio_net_hdr), +- vio_le(), true, 0)) +- goto drop_n_account; +- + po->stats.stats1.tp_packets++; + if (copy_skb) { + status |= TP_STATUS_COPY; +diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c +index 712ad248d6a7..f757ea90aba6 100644 +--- a/net/sched/sch_fq.c ++++ b/net/sched/sch_fq.c +@@ -745,6 +745,7 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = { + [TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 }, + [TCA_FQ_BUCKETS_LOG] = { .type = NLA_U32 }, + [TCA_FQ_FLOW_REFILL_DELAY] = { .type = NLA_U32 }, ++ [TCA_FQ_ORPHAN_MASK] = { .type = NLA_U32 }, + [TCA_FQ_LOW_RATE_THRESHOLD] = { .type = NLA_U32 }, + [TCA_FQ_CE_THRESHOLD] = { .type = NLA_U32 }, + }; +diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c +index 660fc45ee40f..b1eb12d33b9a 100644 +--- a/net/sched/sch_taprio.c ++++ b/net/sched/sch_taprio.c +@@ -564,8 +564,10 @@ static struct sk_buff *taprio_dequeue_soft(struct Qdisc *sch) + prio = skb->priority; + tc = netdev_get_prio_tc_map(dev, prio); + +- if (!(gate_mask & BIT(tc))) ++ if (!(gate_mask & BIT(tc))) { ++ skb = NULL; + continue; ++ } + + len = qdisc_pkt_len(skb); + guard = ktime_add_ns(taprio_get_time(q), +@@ -575,13 +577,17 @@ static struct sk_buff *taprio_dequeue_soft(struct Qdisc *sch) + * guard band ... + */ + if (gate_mask != TAPRIO_ALL_GATES_OPEN && +- ktime_after(guard, entry->close_time)) ++ ktime_after(guard, entry->close_time)) { ++ skb = NULL; + continue; ++ } + + /* ... and no budget. */ + if (gate_mask != TAPRIO_ALL_GATES_OPEN && +- atomic_sub_return(len, &entry->budget) < 0) ++ atomic_sub_return(len, &entry->budget) < 0) { ++ skb = NULL; + continue; ++ } + + skb = child->ops->dequeue(child); + if (unlikely(!skb)) +@@ -768,6 +774,7 @@ static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = { + [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME] = { .type = NLA_S64 }, + [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION] = { .type = NLA_S64 }, + [TCA_TAPRIO_ATTR_FLAGS] = { .type = NLA_U32 }, ++ [TCA_TAPRIO_ATTR_TXTIME_DELAY] = { .type = NLA_U32 }, + }; + + static int fill_sched_entry(struct nlattr **tb, struct sched_entry *entry, +diff --git a/net/sctp/diag.c b/net/sctp/diag.c +index 0851166b9175..ba9f64fdfd23 100644 +--- a/net/sctp/diag.c ++++ b/net/sctp/diag.c +@@ -237,15 +237,11 @@ static size_t inet_assoc_attr_size(struct sctp_association *asoc) + addrcnt++; + + return nla_total_size(sizeof(struct sctp_info)) +- + nla_total_size(1) /* INET_DIAG_SHUTDOWN */ +- + nla_total_size(1) /* INET_DIAG_TOS */ +- + nla_total_size(1) /* INET_DIAG_TCLASS */ +- + nla_total_size(4) /* INET_DIAG_MARK */ +- + nla_total_size(4) /* INET_DIAG_CLASS_ID */ + + nla_total_size(addrlen * asoc->peer.transport_count) + + nla_total_size(addrlen * addrcnt) +- + nla_total_size(sizeof(struct inet_diag_meminfo)) + + nla_total_size(sizeof(struct inet_diag_msg)) ++ + inet_diag_msg_attrs_size() ++ + nla_total_size(sizeof(struct inet_diag_meminfo)) + + 64; + } + +diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c +index d14ca4af6f94..d74a71dff5b8 100644 +--- a/net/smc/smc_ib.c ++++ b/net/smc/smc_ib.c +@@ -560,12 +560,15 @@ static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data) + struct smc_ib_device *smcibdev; + + smcibdev = ib_get_client_data(ibdev, &smc_ib_client); ++ if (!smcibdev || smcibdev->ibdev != ibdev) ++ return; + ib_set_client_data(ibdev, &smc_ib_client, NULL); + spin_lock(&smc_ib_devices.lock); + list_del_init(&smcibdev->list); /* remove from smc_ib_devices */ + spin_unlock(&smc_ib_devices.lock); + smc_ib_cleanup_per_ibdev(smcibdev); + ib_unregister_event_handler(&smcibdev->event_handler); ++ cancel_work_sync(&smcibdev->port_event_work); + kfree(smcibdev); + } + +diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c +index d6165ad384c0..e9bbf4a00881 100644 +--- a/net/tipc/netlink.c ++++ b/net/tipc/netlink.c +@@ -111,6 +111,7 @@ const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { + [TIPC_NLA_PROP_PRIO] = { .type = NLA_U32 }, + [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 }, + [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 }, ++ [TIPC_NLA_PROP_MTU] = { .type = NLA_U32 }, + [TIPC_NLA_PROP_BROADCAST] = { .type = NLA_U32 }, + [TIPC_NLA_PROP_BROADCAST_RATIO] = { .type = NLA_U32 } + }; +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 17514744af9e..321c132747ce 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -469,6 +469,8 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, + [NL80211_ATTR_STA_PLINK_STATE] = + NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1), ++ [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 }, ++ [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG }, + [NL80211_ATTR_MESH_PEER_AID] = + NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID), + [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, +@@ -530,6 +532,8 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [NL80211_ATTR_MDID] = { .type = NLA_U16 }, + [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY, + .len = IEEE80211_MAX_DATA_LEN }, ++ [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 }, ++ [NL80211_ATTR_MAX_CRIT_PROT_DURATION] = { .type = NLA_U16 }, + [NL80211_ATTR_PEER_AID] = + NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID), + [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, +@@ -560,6 +564,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1), + [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, + [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, ++ [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 }, + [NL80211_ATTR_MAC_MASK] = { + .type = NLA_EXACT_LEN_WARN, + .len = ETH_ALEN +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index b6b837a5bdaf..12858d95c2c8 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -949,7 +949,7 @@ struct alc_codec_rename_pci_table { + const char *name; + }; + +-static struct alc_codec_rename_table rename_tbl[] = { ++static const struct alc_codec_rename_table rename_tbl[] = { + { 0x10ec0221, 0xf00f, 0x1003, "ALC231" }, + { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, + { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, +@@ -970,7 +970,7 @@ static struct alc_codec_rename_table rename_tbl[] = { + { } /* terminator */ + }; + +-static struct alc_codec_rename_pci_table rename_pci_tbl[] = { ++static const struct alc_codec_rename_pci_table rename_pci_tbl[] = { + { 0x10ec0280, 0x1028, 0, "ALC3220" }, + { 0x10ec0282, 0x1028, 0, "ALC3221" }, + { 0x10ec0283, 0x1028, 0, "ALC3223" }, +@@ -3000,7 +3000,7 @@ static void alc269_shutup(struct hda_codec *codec) + alc_shutup_pins(codec); + } + +-static struct coef_fw alc282_coefs[] = { ++static const struct coef_fw alc282_coefs[] = { + WRITE_COEF(0x03, 0x0002), /* Power Down Control */ + UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */ + WRITE_COEF(0x07, 0x0200), /* DMIC control */ +@@ -3112,7 +3112,7 @@ static void alc282_shutup(struct hda_codec *codec) + alc_write_coef_idx(codec, 0x78, coef78); + } + +-static struct coef_fw alc283_coefs[] = { ++static const struct coef_fw alc283_coefs[] = { + WRITE_COEF(0x03, 0x0002), /* Power Down Control */ + UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */ + WRITE_COEF(0x07, 0x0200), /* DMIC control */ +@@ -4188,7 +4188,7 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, + } + } + +-static struct coef_fw alc225_pre_hsmode[] = { ++static const struct coef_fw alc225_pre_hsmode[] = { + UPDATE_COEF(0x4a, 1<<8, 0), + UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), + UPDATE_COEF(0x63, 3<<14, 3<<14), +@@ -4201,7 +4201,7 @@ static struct coef_fw alc225_pre_hsmode[] = { + + static void alc_headset_mode_unplugged(struct hda_codec *codec) + { +- static struct coef_fw coef0255[] = { ++ static const struct coef_fw coef0255[] = { + WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */ + WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */ + UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/ +@@ -4209,7 +4209,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) + WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */ + {} + }; +- static struct coef_fw coef0256[] = { ++ static const struct coef_fw coef0256[] = { + WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */ + WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */ + WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */ +@@ -4217,7 +4217,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) + UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/ + {} + }; +- static struct coef_fw coef0233[] = { ++ static const struct coef_fw coef0233[] = { + WRITE_COEF(0x1b, 0x0c0b), + WRITE_COEF(0x45, 0xc429), + UPDATE_COEF(0x35, 0x4000, 0), +@@ -4227,7 +4227,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) + WRITE_COEF(0x32, 0x42a3), + {} + }; +- static struct coef_fw coef0288[] = { ++ static const struct coef_fw coef0288[] = { + UPDATE_COEF(0x4f, 0xfcc0, 0xc400), + UPDATE_COEF(0x50, 0x2000, 0x2000), + UPDATE_COEF(0x56, 0x0006, 0x0006), +@@ -4235,18 +4235,18 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) + UPDATE_COEF(0x67, 0x2000, 0), + {} + }; +- static struct coef_fw coef0298[] = { ++ static const struct coef_fw coef0298[] = { + UPDATE_COEF(0x19, 0x1300, 0x0300), + {} + }; +- static struct coef_fw coef0292[] = { ++ static const struct coef_fw coef0292[] = { + WRITE_COEF(0x76, 0x000e), + WRITE_COEF(0x6c, 0x2400), + WRITE_COEF(0x18, 0x7308), + WRITE_COEF(0x6b, 0xc429), + {} + }; +- static struct coef_fw coef0293[] = { ++ static const struct coef_fw coef0293[] = { + UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */ + UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */ + UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */ +@@ -4255,16 +4255,16 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) + UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */ + {} + }; +- static struct coef_fw coef0668[] = { ++ static const struct coef_fw coef0668[] = { + WRITE_COEF(0x15, 0x0d40), + WRITE_COEF(0xb7, 0x802b), + {} + }; +- static struct coef_fw coef0225[] = { ++ static const struct coef_fw coef0225[] = { + UPDATE_COEF(0x63, 3<<14, 0), + {} + }; +- static struct coef_fw coef0274[] = { ++ static const struct coef_fw coef0274[] = { + UPDATE_COEF(0x4a, 0x0100, 0), + UPDATE_COEFEX(0x57, 0x05, 0x4000, 0), + UPDATE_COEF(0x6b, 0xf000, 0x5000), +@@ -4329,25 +4329,25 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) + static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, + hda_nid_t mic_pin) + { +- static struct coef_fw coef0255[] = { ++ static const struct coef_fw coef0255[] = { + WRITE_COEFEX(0x57, 0x03, 0x8aa6), + WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */ + {} + }; +- static struct coef_fw coef0256[] = { ++ static const struct coef_fw coef0256[] = { + UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), /* Direct Drive HP Amp control(Set to verb control)*/ + WRITE_COEFEX(0x57, 0x03, 0x09a3), + WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */ + {} + }; +- static struct coef_fw coef0233[] = { ++ static const struct coef_fw coef0233[] = { + UPDATE_COEF(0x35, 0, 1<<14), + WRITE_COEF(0x06, 0x2100), + WRITE_COEF(0x1a, 0x0021), + WRITE_COEF(0x26, 0x008c), + {} + }; +- static struct coef_fw coef0288[] = { ++ static const struct coef_fw coef0288[] = { + UPDATE_COEF(0x4f, 0x00c0, 0), + UPDATE_COEF(0x50, 0x2000, 0), + UPDATE_COEF(0x56, 0x0006, 0), +@@ -4356,30 +4356,30 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, + UPDATE_COEF(0x67, 0x2000, 0x2000), + {} + }; +- static struct coef_fw coef0292[] = { ++ static const struct coef_fw coef0292[] = { + WRITE_COEF(0x19, 0xa208), + WRITE_COEF(0x2e, 0xacf0), + {} + }; +- static struct coef_fw coef0293[] = { ++ static const struct coef_fw coef0293[] = { + UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */ + UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */ + UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */ + {} + }; +- static struct coef_fw coef0688[] = { ++ static const struct coef_fw coef0688[] = { + WRITE_COEF(0xb7, 0x802b), + WRITE_COEF(0xb5, 0x1040), + UPDATE_COEF(0xc3, 0, 1<<12), + {} + }; +- static struct coef_fw coef0225[] = { ++ static const struct coef_fw coef0225[] = { + UPDATE_COEFEX(0x57, 0x05, 1<<14, 1<<14), + UPDATE_COEF(0x4a, 3<<4, 2<<4), + UPDATE_COEF(0x63, 3<<14, 0), + {} + }; +- static struct coef_fw coef0274[] = { ++ static const struct coef_fw coef0274[] = { + UPDATE_COEFEX(0x57, 0x05, 0x4000, 0x4000), + UPDATE_COEF(0x4a, 0x0010, 0), + UPDATE_COEF(0x6b, 0xf000, 0), +@@ -4465,7 +4465,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, + + static void alc_headset_mode_default(struct hda_codec *codec) + { +- static struct coef_fw coef0225[] = { ++ static const struct coef_fw coef0225[] = { + UPDATE_COEF(0x45, 0x3f<<10, 0x30<<10), + UPDATE_COEF(0x45, 0x3f<<10, 0x31<<10), + UPDATE_COEF(0x49, 3<<8, 0<<8), +@@ -4474,14 +4474,14 @@ static void alc_headset_mode_default(struct hda_codec *codec) + UPDATE_COEF(0x67, 0xf000, 0x3000), + {} + }; +- static struct coef_fw coef0255[] = { ++ static const struct coef_fw coef0255[] = { + WRITE_COEF(0x45, 0xc089), + WRITE_COEF(0x45, 0xc489), + WRITE_COEFEX(0x57, 0x03, 0x8ea6), + WRITE_COEF(0x49, 0x0049), + {} + }; +- static struct coef_fw coef0256[] = { ++ static const struct coef_fw coef0256[] = { + WRITE_COEF(0x45, 0xc489), + WRITE_COEFEX(0x57, 0x03, 0x0da3), + WRITE_COEF(0x49, 0x0049), +@@ -4489,12 +4489,12 @@ static void alc_headset_mode_default(struct hda_codec *codec) + WRITE_COEF(0x06, 0x6100), + {} + }; +- static struct coef_fw coef0233[] = { ++ static const struct coef_fw coef0233[] = { + WRITE_COEF(0x06, 0x2100), + WRITE_COEF(0x32, 0x4ea3), + {} + }; +- static struct coef_fw coef0288[] = { ++ static const struct coef_fw coef0288[] = { + UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */ + UPDATE_COEF(0x50, 0x2000, 0x2000), + UPDATE_COEF(0x56, 0x0006, 0x0006), +@@ -4502,26 +4502,26 @@ static void alc_headset_mode_default(struct hda_codec *codec) + UPDATE_COEF(0x67, 0x2000, 0), + {} + }; +- static struct coef_fw coef0292[] = { ++ static const struct coef_fw coef0292[] = { + WRITE_COEF(0x76, 0x000e), + WRITE_COEF(0x6c, 0x2400), + WRITE_COEF(0x6b, 0xc429), + WRITE_COEF(0x18, 0x7308), + {} + }; +- static struct coef_fw coef0293[] = { ++ static const struct coef_fw coef0293[] = { + UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */ + WRITE_COEF(0x45, 0xC429), /* Set to TRS type */ + UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */ + {} + }; +- static struct coef_fw coef0688[] = { ++ static const struct coef_fw coef0688[] = { + WRITE_COEF(0x11, 0x0041), + WRITE_COEF(0x15, 0x0d40), + WRITE_COEF(0xb7, 0x802b), + {} + }; +- static struct coef_fw coef0274[] = { ++ static const struct coef_fw coef0274[] = { + WRITE_COEF(0x45, 0x4289), + UPDATE_COEF(0x4a, 0x0010, 0x0010), + UPDATE_COEF(0x6b, 0x0f00, 0), +@@ -4584,53 +4584,53 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) + { + int val; + +- static struct coef_fw coef0255[] = { ++ static const struct coef_fw coef0255[] = { + WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */ + WRITE_COEF(0x1b, 0x0c2b), + WRITE_COEFEX(0x57, 0x03, 0x8ea6), + {} + }; +- static struct coef_fw coef0256[] = { ++ static const struct coef_fw coef0256[] = { + WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */ + WRITE_COEF(0x1b, 0x0e6b), + {} + }; +- static struct coef_fw coef0233[] = { ++ static const struct coef_fw coef0233[] = { + WRITE_COEF(0x45, 0xd429), + WRITE_COEF(0x1b, 0x0c2b), + WRITE_COEF(0x32, 0x4ea3), + {} + }; +- static struct coef_fw coef0288[] = { ++ static const struct coef_fw coef0288[] = { + UPDATE_COEF(0x50, 0x2000, 0x2000), + UPDATE_COEF(0x56, 0x0006, 0x0006), + UPDATE_COEF(0x66, 0x0008, 0), + UPDATE_COEF(0x67, 0x2000, 0), + {} + }; +- static struct coef_fw coef0292[] = { ++ static const struct coef_fw coef0292[] = { + WRITE_COEF(0x6b, 0xd429), + WRITE_COEF(0x76, 0x0008), + WRITE_COEF(0x18, 0x7388), + {} + }; +- static struct coef_fw coef0293[] = { ++ static const struct coef_fw coef0293[] = { + WRITE_COEF(0x45, 0xd429), /* Set to ctia type */ + UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */ + {} + }; +- static struct coef_fw coef0688[] = { ++ static const struct coef_fw coef0688[] = { + WRITE_COEF(0x11, 0x0001), + WRITE_COEF(0x15, 0x0d60), + WRITE_COEF(0xc3, 0x0000), + {} + }; +- static struct coef_fw coef0225_1[] = { ++ static const struct coef_fw coef0225_1[] = { + UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10), + UPDATE_COEF(0x63, 3<<14, 2<<14), + {} + }; +- static struct coef_fw coef0225_2[] = { ++ static const struct coef_fw coef0225_2[] = { + UPDATE_COEF(0x45, 0x3f<<10, 0x35<<10), + UPDATE_COEF(0x63, 3<<14, 1<<14), + {} +@@ -4702,48 +4702,48 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) + /* Nokia type */ + static void alc_headset_mode_omtp(struct hda_codec *codec) + { +- static struct coef_fw coef0255[] = { ++ static const struct coef_fw coef0255[] = { + WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */ + WRITE_COEF(0x1b, 0x0c2b), + WRITE_COEFEX(0x57, 0x03, 0x8ea6), + {} + }; +- static struct coef_fw coef0256[] = { ++ static const struct coef_fw coef0256[] = { + WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */ + WRITE_COEF(0x1b, 0x0e6b), + {} + }; +- static struct coef_fw coef0233[] = { ++ static const struct coef_fw coef0233[] = { + WRITE_COEF(0x45, 0xe429), + WRITE_COEF(0x1b, 0x0c2b), + WRITE_COEF(0x32, 0x4ea3), + {} + }; +- static struct coef_fw coef0288[] = { ++ static const struct coef_fw coef0288[] = { + UPDATE_COEF(0x50, 0x2000, 0x2000), + UPDATE_COEF(0x56, 0x0006, 0x0006), + UPDATE_COEF(0x66, 0x0008, 0), + UPDATE_COEF(0x67, 0x2000, 0), + {} + }; +- static struct coef_fw coef0292[] = { ++ static const struct coef_fw coef0292[] = { + WRITE_COEF(0x6b, 0xe429), + WRITE_COEF(0x76, 0x0008), + WRITE_COEF(0x18, 0x7388), + {} + }; +- static struct coef_fw coef0293[] = { ++ static const struct coef_fw coef0293[] = { + WRITE_COEF(0x45, 0xe429), /* Set to omtp type */ + UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */ + {} + }; +- static struct coef_fw coef0688[] = { ++ static const struct coef_fw coef0688[] = { + WRITE_COEF(0x11, 0x0001), + WRITE_COEF(0x15, 0x0d50), + WRITE_COEF(0xc3, 0x0000), + {} + }; +- static struct coef_fw coef0225[] = { ++ static const struct coef_fw coef0225[] = { + UPDATE_COEF(0x45, 0x3f<<10, 0x39<<10), + UPDATE_COEF(0x63, 3<<14, 2<<14), + {} +@@ -4803,17 +4803,17 @@ static void alc_determine_headset_type(struct hda_codec *codec) + int val; + bool is_ctia = false; + struct alc_spec *spec = codec->spec; +- static struct coef_fw coef0255[] = { ++ static const struct coef_fw coef0255[] = { + WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/ + WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref + conteol) */ + {} + }; +- static struct coef_fw coef0288[] = { ++ static const struct coef_fw coef0288[] = { + UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */ + {} + }; +- static struct coef_fw coef0298[] = { ++ static const struct coef_fw coef0298[] = { + UPDATE_COEF(0x50, 0x2000, 0x2000), + UPDATE_COEF(0x56, 0x0006, 0x0006), + UPDATE_COEF(0x66, 0x0008, 0), +@@ -4821,19 +4821,19 @@ static void alc_determine_headset_type(struct hda_codec *codec) + UPDATE_COEF(0x19, 0x1300, 0x1300), + {} + }; +- static struct coef_fw coef0293[] = { ++ static const struct coef_fw coef0293[] = { + UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */ + WRITE_COEF(0x45, 0xD429), /* Set to ctia type */ + {} + }; +- static struct coef_fw coef0688[] = { ++ static const struct coef_fw coef0688[] = { + WRITE_COEF(0x11, 0x0001), + WRITE_COEF(0xb7, 0x802b), + WRITE_COEF(0x15, 0x0d60), + WRITE_COEF(0xc3, 0x0c00), + {} + }; +- static struct coef_fw coef0274[] = { ++ static const struct coef_fw coef0274[] = { + UPDATE_COEF(0x4a, 0x0010, 0), + UPDATE_COEF(0x4a, 0x8000, 0), + WRITE_COEF(0x45, 0xd289), +@@ -5120,7 +5120,7 @@ static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, + static void alc255_set_default_jack_type(struct hda_codec *codec) + { + /* Set to iphone type */ +- static struct coef_fw alc255fw[] = { ++ static const struct coef_fw alc255fw[] = { + WRITE_COEF(0x1b, 0x880b), + WRITE_COEF(0x45, 0xd089), + WRITE_COEF(0x1b, 0x080b), +@@ -5128,7 +5128,7 @@ static void alc255_set_default_jack_type(struct hda_codec *codec) + WRITE_COEF(0x1b, 0x0c0b), + {} + }; +- static struct coef_fw alc256fw[] = { ++ static const struct coef_fw alc256fw[] = { + WRITE_COEF(0x1b, 0x884b), + WRITE_COEF(0x45, 0xd089), + WRITE_COEF(0x1b, 0x084b), +@@ -8542,7 +8542,30 @@ static void alc662_fixup_aspire_ethos_hp(struct hda_codec *codec, + } + } + +-static struct coef_fw alc668_coefs[] = { ++static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ struct alc_spec *spec = codec->spec; ++ ++ static const struct hda_pintbl pincfgs[] = { ++ { 0x19, 0x02a11040 }, /* use as headset mic, with its own jack detect */ ++ { 0x1b, 0x0181304f }, ++ { } ++ }; ++ ++ switch (action) { ++ case HDA_FIXUP_ACT_PRE_PROBE: ++ spec->gen.mixer_nid = 0; ++ spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; ++ snd_hda_apply_pincfgs(codec, pincfgs); ++ break; ++ case HDA_FIXUP_ACT_INIT: ++ alc_write_coef_idx(codec, 0x19, 0xa054); ++ break; ++ } ++} ++ ++static const struct coef_fw alc668_coefs[] = { + WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0), + WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80), + WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b, 0x0), +@@ -8615,6 +8638,7 @@ enum { + ALC662_FIXUP_LENOVO_MULTI_CODECS, + ALC669_FIXUP_ACER_ASPIRE_ETHOS, + ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET, ++ ALC671_FIXUP_HP_HEADSET_MIC2, + }; + + static const struct hda_fixup alc662_fixups[] = { +@@ -8956,6 +8980,10 @@ static const struct hda_fixup alc662_fixups[] = { + .chained = true, + .chain_id = ALC669_FIXUP_ACER_ASPIRE_ETHOS_HEADSET + }, ++ [ALC671_FIXUP_HP_HEADSET_MIC2] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc671_fixup_hp_headset_mic2, ++ }, + }; + + static const struct snd_pci_quirk alc662_fixup_tbl[] = { +@@ -9138,6 +9166,23 @@ static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = { + {0x12, 0x90a60130}, + {0x14, 0x90170110}, + {0x15, 0x0321101f}), ++ SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2, ++ {0x14, 0x01014010}, ++ {0x17, 0x90170150}, ++ {0x19, 0x02a11060}, ++ {0x1b, 0x01813030}, ++ {0x21, 0x02211020}), ++ SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2, ++ {0x14, 0x01014010}, ++ {0x18, 0x01a19040}, ++ {0x1b, 0x01813030}, ++ {0x21, 0x02211020}), ++ SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2, ++ {0x14, 0x01014020}, ++ {0x17, 0x90170110}, ++ {0x18, 0x01a19050}, ++ {0x1b, 0x01813040}, ++ {0x21, 0x02211030}), + {} + }; + +diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c +index df810096abfe..58906e9499bb 100644 +--- a/tools/perf/bench/futex-wake.c ++++ b/tools/perf/bench/futex-wake.c +@@ -43,7 +43,7 @@ static bool done = false, silent = false, fshared = false; + static pthread_mutex_t thread_lock; + static pthread_cond_t thread_parent, thread_worker; + static struct stats waketime_stats, wakeup_stats; +-static unsigned int ncpus, threads_starting, nthreads = 0; ++static unsigned int threads_starting, nthreads = 0; + static int futex_flag = 0; + + static const struct option options[] = { +@@ -141,7 +141,7 @@ int bench_futex_wake(int argc, const char **argv) + sigaction(SIGINT, &act, NULL); + + if (!nthreads) +- nthreads = ncpus; ++ nthreads = cpu->nr; + + worker = calloc(nthreads, sizeof(*worker)); + if (!worker) +diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl +index 220d04f958a6..42b6cd41d2ea 100755 +--- a/tools/testing/ktest/ktest.pl ++++ b/tools/testing/ktest/ktest.pl +@@ -1383,7 +1383,7 @@ sub reboot { + + } else { + # Make sure everything has been written to disk +- run_ssh("sync"); ++ run_ssh("sync", 10); + + if (defined($time)) { + start_monitor; +diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh +index 474638ef2697..09854f8a0b57 100755 +--- a/tools/testing/selftests/net/fib_tests.sh ++++ b/tools/testing/selftests/net/fib_tests.sh +@@ -1041,6 +1041,27 @@ ipv6_addr_metric_test() + fi + log_test $rc 0 "Prefix route with metric on link up" + ++ # verify peer metric added correctly ++ set -e ++ run_cmd "$IP -6 addr flush dev dummy2" ++ run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260" ++ set +e ++ ++ check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260" ++ log_test $? 0 "Set metric with peer route on local side" ++ log_test $? 0 "User specified metric on local address" ++ check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260" ++ log_test $? 0 "Set metric with peer route on peer side" ++ ++ set -e ++ run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261" ++ set +e ++ ++ check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261" ++ log_test $? 0 "Modify metric and peer address on local side" ++ check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261" ++ log_test $? 0 "Modify metric and peer address on peer side" ++ + $IP li del dummy1 + $IP li del dummy2 + cleanup +@@ -1457,13 +1478,20 @@ ipv4_addr_metric_test() + + run_cmd "$IP addr flush dev dummy2" + run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260" +- run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 261" + rc=$? + if [ $rc -eq 0 ]; then +- check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261" ++ check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260" ++ rc=$? ++ fi ++ log_test $rc 0 "Set metric of address with peer route" ++ ++ run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261" ++ rc=$? ++ if [ $rc -eq 0 ]; then ++ check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261" + rc=$? + fi +- log_test $rc 0 "Modify metric of address with peer route" ++ log_test $rc 0 "Modify metric and peer address for peer route" + + $IP li del dummy1 + $IP li del dummy2 diff --git a/patch/kernel/odroidxu4-current/03-patch-5.4.26-27.patch b/patch/kernel/odroidxu4-current/03-patch-5.4.26-27.patch new file mode 100644 index 0000000000..bf0ff09c14 --- /dev/null +++ b/patch/kernel/odroidxu4-current/03-patch-5.4.26-27.patch @@ -0,0 +1,1989 @@ +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 5594c8bf1dcd..b5c933fa971f 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -136,6 +136,10 @@ + dynamic table installation which will install SSDT + tables to /sys/firmware/acpi/tables/dynamic. + ++ acpi_no_watchdog [HW,ACPI,WDT] ++ Ignore the ACPI-based watchdog interface (WDAT) and let ++ a native driver control the watchdog device instead. ++ + acpi_rsdp= [ACPI,EFI,KEXEC] + Pass the RSDP address to the kernel, mostly used + on machines running EFI runtime service to boot the +diff --git a/Makefile b/Makefile +index 2250b1bb8aa9..36a0847534dd 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 26 ++SUBLEVEL = 27 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +@@ -1237,7 +1237,7 @@ ifneq ($(dtstree),) + %.dtb: include/config/kernel.release scripts_dtc + $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ + +-PHONY += dtbs dtbs_install dt_binding_check ++PHONY += dtbs dtbs_install dtbs_check + dtbs dtbs_check: include/config/kernel.release scripts_dtc + $(Q)$(MAKE) $(build)=$(dtstree) + +@@ -1257,6 +1257,7 @@ PHONY += scripts_dtc + scripts_dtc: scripts_basic + $(Q)$(MAKE) $(build)=scripts/dtc + ++PHONY += dt_binding_check + dt_binding_check: scripts_dtc + $(Q)$(MAKE) $(build)=Documentation/devicetree/bindings + +diff --git a/arch/arm/Makefile b/arch/arm/Makefile +index db857d07114f..1fc32b611f8a 100644 +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -307,13 +307,15 @@ endif + ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) + prepare: stack_protector_prepare + stack_protector_prepare: prepare0 +- $(eval KBUILD_CFLAGS += \ ++ $(eval SSP_PLUGIN_CFLAGS := \ + -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \ + awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\ + include/generated/asm-offsets.h) \ + -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ + awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\ + include/generated/asm-offsets.h)) ++ $(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS)) ++ $(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS)) + endif + + all: $(notdir $(KBUILD_IMAGE)) +diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile +index 9219389bbe61..1483966dcf23 100644 +--- a/arch/arm/boot/compressed/Makefile ++++ b/arch/arm/boot/compressed/Makefile +@@ -101,7 +101,6 @@ clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \ + $(libfdt) $(libfdt_hdrs) hyp-stub.S + + KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +-KBUILD_CFLAGS += $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) + + ifeq ($(CONFIG_FUNCTION_TRACER),y) + ORIG_CFLAGS := $(KBUILD_CFLAGS) +@@ -117,7 +116,8 @@ CFLAGS_fdt_ro.o := $(nossp_flags) + CFLAGS_fdt_rw.o := $(nossp_flags) + CFLAGS_fdt_wip.o := $(nossp_flags) + +-ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin -I$(obj) ++ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \ ++ -I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) + asflags-y := -DZIMAGE + + # Supply kernel BSS size to the decompressor via a linker symbol. +diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c +index 9bf16c93ee6a..f00e45fa62c4 100644 +--- a/arch/arm/kernel/vdso.c ++++ b/arch/arm/kernel/vdso.c +@@ -92,6 +92,8 @@ static bool __init cntvct_functional(void) + * this. + */ + np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); ++ if (!np) ++ np = of_find_compatible_node(NULL, NULL, "arm,armv8-timer"); + if (!np) + goto out_put; + +diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S +index 95b2e1ce559c..f8016e3db65d 100644 +--- a/arch/arm/lib/copy_from_user.S ++++ b/arch/arm/lib/copy_from_user.S +@@ -118,7 +118,7 @@ ENTRY(arm_copy_from_user) + + ENDPROC(arm_copy_from_user) + +- .pushsection .fixup,"ax" ++ .pushsection .text.fixup,"ax" + .align 0 + copy_abort_preamble + ldmfd sp!, {r1, r2, r3} +diff --git a/block/blk-flush.c b/block/blk-flush.c +index b1f0a1ac505c..5aa6fada2259 100644 +--- a/block/blk-flush.c ++++ b/block/blk-flush.c +@@ -399,7 +399,7 @@ void blk_insert_flush(struct request *rq) + */ + if ((policy & REQ_FSEQ_DATA) && + !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) { +- blk_mq_request_bypass_insert(rq, false); ++ blk_mq_request_bypass_insert(rq, false, false); + return; + } + +diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c +index ca22afd47b3d..74cedea56034 100644 +--- a/block/blk-mq-sched.c ++++ b/block/blk-mq-sched.c +@@ -361,13 +361,19 @@ static bool blk_mq_sched_bypass_insert(struct blk_mq_hw_ctx *hctx, + bool has_sched, + struct request *rq) + { +- /* dispatch flush rq directly */ +- if (rq->rq_flags & RQF_FLUSH_SEQ) { +- spin_lock(&hctx->lock); +- list_add(&rq->queuelist, &hctx->dispatch); +- spin_unlock(&hctx->lock); ++ /* ++ * dispatch flush and passthrough rq directly ++ * ++ * passthrough request has to be added to hctx->dispatch directly. ++ * For some reason, device may be in one situation which can't ++ * handle FS request, so STS_RESOURCE is always returned and the ++ * FS request will be added to hctx->dispatch. However passthrough ++ * request may be required at that time for fixing the problem. If ++ * passthrough request is added to scheduler queue, there isn't any ++ * chance to dispatch it given we prioritize requests in hctx->dispatch. ++ */ ++ if ((rq->rq_flags & RQF_FLUSH_SEQ) || blk_rq_is_passthrough(rq)) + return true; +- } + + if (has_sched) + rq->rq_flags |= RQF_SORTED; +@@ -391,8 +397,32 @@ void blk_mq_sched_insert_request(struct request *rq, bool at_head, + + WARN_ON(e && (rq->tag != -1)); + +- if (blk_mq_sched_bypass_insert(hctx, !!e, rq)) ++ if (blk_mq_sched_bypass_insert(hctx, !!e, rq)) { ++ /* ++ * Firstly normal IO request is inserted to scheduler queue or ++ * sw queue, meantime we add flush request to dispatch queue( ++ * hctx->dispatch) directly and there is at most one in-flight ++ * flush request for each hw queue, so it doesn't matter to add ++ * flush request to tail or front of the dispatch queue. ++ * ++ * Secondly in case of NCQ, flush request belongs to non-NCQ ++ * command, and queueing it will fail when there is any ++ * in-flight normal IO request(NCQ command). When adding flush ++ * rq to the front of hctx->dispatch, it is easier to introduce ++ * extra time to flush rq's latency because of S_SCHED_RESTART ++ * compared with adding to the tail of dispatch queue, then ++ * chance of flush merge is increased, and less flush requests ++ * will be issued to controller. It is observed that ~10% time ++ * is saved in blktests block/004 on disk attached to AHCI/NCQ ++ * drive when adding flush rq to the front of hctx->dispatch. ++ * ++ * Simply queue flush rq to the front of hctx->dispatch so that ++ * intensive flush workloads can benefit in case of NCQ HW. ++ */ ++ at_head = (rq->rq_flags & RQF_FLUSH_SEQ) ? true : at_head; ++ blk_mq_request_bypass_insert(rq, at_head, false); + goto run; ++ } + + if (e && e->type->ops.insert_requests) { + LIST_HEAD(list); +diff --git a/block/blk-mq.c b/block/blk-mq.c +index ec791156e9cc..3c1abab1fdf5 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -761,7 +761,7 @@ static void blk_mq_requeue_work(struct work_struct *work) + * merge. + */ + if (rq->rq_flags & RQF_DONTPREP) +- blk_mq_request_bypass_insert(rq, false); ++ blk_mq_request_bypass_insert(rq, false, false); + else + blk_mq_sched_insert_request(rq, true, false, false); + } +@@ -1313,7 +1313,7 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list, + q->mq_ops->commit_rqs(hctx); + + spin_lock(&hctx->lock); +- list_splice_init(list, &hctx->dispatch); ++ list_splice_tail_init(list, &hctx->dispatch); + spin_unlock(&hctx->lock); + + /* +@@ -1668,12 +1668,16 @@ void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + * Should only be used carefully, when the caller knows we want to + * bypass a potential IO scheduler on the target device. + */ +-void blk_mq_request_bypass_insert(struct request *rq, bool run_queue) ++void blk_mq_request_bypass_insert(struct request *rq, bool at_head, ++ bool run_queue) + { + struct blk_mq_hw_ctx *hctx = rq->mq_hctx; + + spin_lock(&hctx->lock); +- list_add_tail(&rq->queuelist, &hctx->dispatch); ++ if (at_head) ++ list_add(&rq->queuelist, &hctx->dispatch); ++ else ++ list_add_tail(&rq->queuelist, &hctx->dispatch); + spin_unlock(&hctx->lock); + + if (run_queue) +@@ -1863,7 +1867,7 @@ insert: + if (bypass_insert) + return BLK_STS_RESOURCE; + +- blk_mq_request_bypass_insert(rq, run_queue); ++ blk_mq_request_bypass_insert(rq, false, run_queue); + return BLK_STS_OK; + } + +@@ -1879,7 +1883,7 @@ static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx, + + ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false, true); + if (ret == BLK_STS_RESOURCE || ret == BLK_STS_DEV_RESOURCE) +- blk_mq_request_bypass_insert(rq, true); ++ blk_mq_request_bypass_insert(rq, false, true); + else if (ret != BLK_STS_OK) + blk_mq_end_request(rq, ret); + +@@ -1913,7 +1917,7 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx, + if (ret != BLK_STS_OK) { + if (ret == BLK_STS_RESOURCE || + ret == BLK_STS_DEV_RESOURCE) { +- blk_mq_request_bypass_insert(rq, ++ blk_mq_request_bypass_insert(rq, false, + list_empty(list)); + break; + } +diff --git a/block/blk-mq.h b/block/blk-mq.h +index 32c62c64e6c2..f2075978db50 100644 +--- a/block/blk-mq.h ++++ b/block/blk-mq.h +@@ -66,7 +66,8 @@ int blk_mq_alloc_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags, + */ + void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + bool at_head); +-void blk_mq_request_bypass_insert(struct request *rq, bool run_queue); ++void blk_mq_request_bypass_insert(struct request *rq, bool at_head, ++ bool run_queue); + void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx, + struct list_head *list); + +diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c +index d827a4a3e946..6e9ec6e3fe47 100644 +--- a/drivers/acpi/acpi_watchdog.c ++++ b/drivers/acpi/acpi_watchdog.c +@@ -55,12 +55,14 @@ static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) + } + #endif + ++static bool acpi_no_watchdog; ++ + static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) + { + const struct acpi_table_wdat *wdat = NULL; + acpi_status status; + +- if (acpi_disabled) ++ if (acpi_disabled || acpi_no_watchdog) + return NULL; + + status = acpi_get_table(ACPI_SIG_WDAT, 0, +@@ -88,6 +90,14 @@ bool acpi_has_watchdog(void) + } + EXPORT_SYMBOL_GPL(acpi_has_watchdog); + ++/* ACPI watchdog can be disabled on boot command line */ ++static int __init disable_acpi_watchdog(char *str) ++{ ++ acpi_no_watchdog = true; ++ return 1; ++} ++__setup("acpi_no_watchdog", disable_acpi_watchdog); ++ + void __init acpi_watchdog_init(void) + { + const struct acpi_wdat_entry *entries; +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +index a7ba4c6cf7a1..f642e066e67a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +@@ -230,7 +230,8 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, + unsigned int vmhub, uint32_t flush_type) + { + struct amdgpu_vmhub *hub = &adev->vmhub[vmhub]; +- u32 tmp = gmc_v10_0_get_invalidate_req(vmid, flush_type); ++ u32 inv_req = gmc_v10_0_get_invalidate_req(vmid, flush_type); ++ u32 tmp; + /* Use register 17 for GART */ + const unsigned eng = 17; + unsigned int i; +@@ -258,7 +259,7 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, + DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); + } + +- WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); ++ WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, inv_req); + + /* + * Issue a dummy read to wait for the ACK register to be cleared +diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +index da53a55bf955..688111ef814d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +@@ -487,13 +487,13 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, + { + bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub); + const unsigned eng = 17; +- u32 j, tmp; ++ u32 j, inv_req, tmp; + struct amdgpu_vmhub *hub; + + BUG_ON(vmhub >= adev->num_vmhubs); + + hub = &adev->vmhub[vmhub]; +- tmp = gmc_v9_0_get_invalidate_req(vmid, flush_type); ++ inv_req = gmc_v9_0_get_invalidate_req(vmid, flush_type); + + /* This is necessary for a HW workaround under SRIOV as well + * as GFXOFF under bare metal +@@ -504,7 +504,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, + uint32_t req = hub->vm_inv_eng0_req + eng; + uint32_t ack = hub->vm_inv_eng0_ack + eng; + +- amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, tmp, ++ amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req, + 1 << vmid); + return; + } +@@ -532,7 +532,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, + DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); + } + +- WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); ++ WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, inv_req); + + /* + * Issue a dummy read to wait for the ACK register to be cleared +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +index c5257ae3188a..0922d9cd858a 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +@@ -988,8 +988,12 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu) + struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks; + int ret = 0; + +- max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks), ++ if (!smu->smu_table.max_sustainable_clocks) ++ max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks), + GFP_KERNEL); ++ else ++ max_sustainable_clocks = smu->smu_table.max_sustainable_clocks; ++ + smu->smu_table.max_sustainable_clocks = (void *)max_sustainable_clocks; + + max_sustainable_clocks->uclock = smu->smu_table.boot_values.uclk / 100; +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index 6ac8becc2372..d732d1d10caf 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -340,7 +340,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, + unsigned long **bit, int *max) + { + if (usage->hid == (HID_UP_CUSTOM | 0x0003) || +- usage->hid == (HID_UP_MSVENDOR | 0x0003)) { ++ usage->hid == (HID_UP_MSVENDOR | 0x0003) || ++ usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) { + /* The fn key on Apple USB keyboards */ + set_bit(EV_REP, hi->input->evbit); + hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); +diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c +index 3f6abd190df4..db6da21ade06 100644 +--- a/drivers/hid/hid-bigbenff.c ++++ b/drivers/hid/hid-bigbenff.c +@@ -174,6 +174,7 @@ static __u8 pid0902_rdesc_fixed[] = { + struct bigben_device { + struct hid_device *hid; + struct hid_report *report; ++ bool removed; + u8 led_state; /* LED1 = 1 .. LED4 = 8 */ + u8 right_motor_on; /* right motor off/on 0/1 */ + u8 left_motor_force; /* left motor force 0-255 */ +@@ -190,6 +191,9 @@ static void bigben_worker(struct work_struct *work) + struct bigben_device, worker); + struct hid_field *report_field = bigben->report->field[0]; + ++ if (bigben->removed) ++ return; ++ + if (bigben->work_led) { + bigben->work_led = false; + report_field->value[0] = 0x01; /* 1 = led message */ +@@ -220,10 +224,16 @@ static void bigben_worker(struct work_struct *work) + static int hid_bigben_play_effect(struct input_dev *dev, void *data, + struct ff_effect *effect) + { +- struct bigben_device *bigben = data; ++ struct hid_device *hid = input_get_drvdata(dev); ++ struct bigben_device *bigben = hid_get_drvdata(hid); + u8 right_motor_on; + u8 left_motor_force; + ++ if (!bigben) { ++ hid_err(hid, "no device data\n"); ++ return 0; ++ } ++ + if (effect->type != FF_RUMBLE) + return 0; + +@@ -298,8 +308,8 @@ static void bigben_remove(struct hid_device *hid) + { + struct bigben_device *bigben = hid_get_drvdata(hid); + ++ bigben->removed = true; + cancel_work_sync(&bigben->worker); +- hid_hw_close(hid); + hid_hw_stop(hid); + } + +@@ -319,6 +329,7 @@ static int bigben_probe(struct hid_device *hid, + return -ENOMEM; + hid_set_drvdata(hid, bigben); + bigben->hid = hid; ++ bigben->removed = false; + + error = hid_parse(hid); + if (error) { +@@ -341,10 +352,10 @@ static int bigben_probe(struct hid_device *hid, + + INIT_WORK(&bigben->worker, bigben_worker); + +- error = input_ff_create_memless(hidinput->input, bigben, ++ error = input_ff_create_memless(hidinput->input, NULL, + hid_bigben_play_effect); + if (error) +- return error; ++ goto error_hw_stop; + + name_sz = strlen(dev_name(&hid->dev)) + strlen(":red:bigben#") + 1; + +@@ -354,8 +365,10 @@ static int bigben_probe(struct hid_device *hid, + sizeof(struct led_classdev) + name_sz, + GFP_KERNEL + ); +- if (!led) +- return -ENOMEM; ++ if (!led) { ++ error = -ENOMEM; ++ goto error_hw_stop; ++ } + name = (void *)(&led[1]); + snprintf(name, name_sz, + "%s:red:bigben%d", +@@ -369,7 +382,7 @@ static int bigben_probe(struct hid_device *hid, + bigben->leds[n] = led; + error = devm_led_classdev_register(&hid->dev, led); + if (error) +- return error; ++ goto error_hw_stop; + } + + /* initial state: LED1 is on, no rumble effect */ +@@ -383,6 +396,10 @@ static int bigben_probe(struct hid_device *hid, + hid_info(hid, "LED and force feedback support for BigBen gamepad\n"); + + return 0; ++ ++error_hw_stop: ++ hid_hw_stop(hid); ++ return error; + } + + static __u8 *bigben_report_fixup(struct hid_device *hid, __u8 *rdesc, +diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c +index d86a9189e88f..aeb351658ad3 100644 +--- a/drivers/hid/hid-google-hammer.c ++++ b/drivers/hid/hid-google-hammer.c +@@ -473,6 +473,8 @@ static const struct hid_device_id hammer_devices[] = { + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, ++ { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, ++ USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 5fc82029a03b..646b98809ed3 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -478,6 +478,7 @@ + #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 + #define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c + #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d ++#define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044 + + #define USB_VENDOR_ID_GOTOP 0x08f2 + #define USB_DEVICE_ID_SUPER_Q2 0x007f +@@ -726,6 +727,7 @@ + #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 + #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 + #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 ++#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d + + #define USB_VENDOR_ID_LG 0x1fd2 + #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 +diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c +index fa58a7cbb3ff..ae64a286a68f 100644 +--- a/drivers/hid/hid-quirks.c ++++ b/drivers/hid/hid-quirks.c +@@ -103,6 +103,7 @@ static const struct hid_device_id hid_quirks[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET }, +diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +index d31ea82b84c1..a66f08041a1a 100644 +--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c ++++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +@@ -341,6 +341,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { + }, + .driver_data = (void *)&sipodev_desc + }, ++ { ++ .ident = "Trekstor SURFBOOK E11B", ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"), ++ }, ++ .driver_data = (void *)&sipodev_desc ++ }, + { + .ident = "Direkt-Tek DTLAPY116-2", + .matches = { +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +index 6f2cf569a283..79b3d53f2fbf 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +@@ -297,6 +297,7 @@ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth, + } + + hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); ++ hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); + + hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT; + hw_ioctxt.cmdq_depth = 0; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +index b069045de416..66fd2340d447 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +@@ -151,8 +151,8 @@ struct hinic_cmd_hw_ioctxt { + + u8 lro_en; + u8 rsvd3; ++ u8 ppf_idx; + u8 rsvd4; +- u8 rsvd5; + + u16 rq_depth; + u16 rx_buf_sz_idx; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +index 517794509eb2..c7bb9ceca72c 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +@@ -137,6 +137,7 @@ + #define HINIC_HWIF_FUNC_IDX(hwif) ((hwif)->attr.func_idx) + #define HINIC_HWIF_PCI_INTF(hwif) ((hwif)->attr.pci_intf_idx) + #define HINIC_HWIF_PF_IDX(hwif) ((hwif)->attr.pf_idx) ++#define HINIC_HWIF_PPF_IDX(hwif) ((hwif)->attr.ppf_idx) + + #define HINIC_FUNC_TYPE(hwif) ((hwif)->attr.func_type) + #define HINIC_IS_PF(hwif) (HINIC_FUNC_TYPE(hwif) == HINIC_PF) +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +index f4a339b10b10..79091e131418 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +@@ -94,6 +94,7 @@ struct hinic_rq { + + struct hinic_wq *wq; + ++ struct cpumask affinity_mask; + u32 irq; + u16 msix_entry; + +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c +index 2411ad270c98..42d00b049c6e 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c +@@ -356,7 +356,8 @@ static void hinic_enable_rss(struct hinic_dev *nic_dev) + if (!num_cpus) + num_cpus = num_online_cpus(); + +- nic_dev->num_qps = min_t(u16, nic_dev->max_qps, num_cpus); ++ nic_dev->num_qps = hinic_hwdev_num_qps(hwdev); ++ nic_dev->num_qps = min_t(u16, nic_dev->num_qps, num_cpus); + + nic_dev->rss_limit = nic_dev->num_qps; + nic_dev->num_rss = nic_dev->num_qps; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c +index 56ea6d692f1c..2695ad69fca6 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c +@@ -475,7 +475,6 @@ static int rx_request_irq(struct hinic_rxq *rxq) + struct hinic_hwdev *hwdev = nic_dev->hwdev; + struct hinic_rq *rq = rxq->rq; + struct hinic_qp *qp; +- struct cpumask mask; + int err; + + rx_add_napi(rxq); +@@ -492,8 +491,8 @@ static int rx_request_irq(struct hinic_rxq *rxq) + } + + qp = container_of(rq, struct hinic_qp, rq); +- cpumask_set_cpu(qp->q_id % num_online_cpus(), &mask); +- return irq_set_affinity_hint(rq->irq, &mask); ++ cpumask_set_cpu(qp->q_id % num_online_cpus(), &rq->affinity_mask); ++ return irq_set_affinity_hint(rq->irq, &rq->affinity_mask); + } + + static void rx_free_irq(struct hinic_rxq *rxq) +diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c +index 1c9e70c8cc30..58579baf3f7a 100644 +--- a/drivers/net/ethernet/micrel/ks8851_mll.c ++++ b/drivers/net/ethernet/micrel/ks8851_mll.c +@@ -513,14 +513,17 @@ static irqreturn_t ks_irq(int irq, void *pw) + { + struct net_device *netdev = pw; + struct ks_net *ks = netdev_priv(netdev); ++ unsigned long flags; + u16 status; + ++ spin_lock_irqsave(&ks->statelock, flags); + /*this should be the first in IRQ handler */ + ks_save_cmd_reg(ks); + + status = ks_rdreg16(ks, KS_ISR); + if (unlikely(!status)) { + ks_restore_cmd_reg(ks); ++ spin_unlock_irqrestore(&ks->statelock, flags); + return IRQ_NONE; + } + +@@ -546,6 +549,7 @@ static irqreturn_t ks_irq(int irq, void *pw) + ks->netdev->stats.rx_over_errors++; + /* this should be the last in IRQ handler*/ + ks_restore_cmd_reg(ks); ++ spin_unlock_irqrestore(&ks->statelock, flags); + return IRQ_HANDLED; + } + +@@ -615,6 +619,7 @@ static int ks_net_stop(struct net_device *netdev) + + /* shutdown RX/TX QMU */ + ks_disable_qmu(ks); ++ ks_disable_int(ks); + + /* set powermode to soft power down to save power */ + ks_set_powermode(ks, PMECR_PM_SOFTDOWN); +@@ -671,10 +676,9 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) + { + netdev_tx_t retv = NETDEV_TX_OK; + struct ks_net *ks = netdev_priv(netdev); ++ unsigned long flags; + +- disable_irq(netdev->irq); +- ks_disable_int(ks); +- spin_lock(&ks->statelock); ++ spin_lock_irqsave(&ks->statelock, flags); + + /* Extra space are required: + * 4 byte for alignment, 4 for status/length, 4 for CRC +@@ -688,9 +692,7 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) + dev_kfree_skb(skb); + } else + retv = NETDEV_TX_BUSY; +- spin_unlock(&ks->statelock); +- ks_enable_int(ks); +- enable_irq(netdev->irq); ++ spin_unlock_irqrestore(&ks->statelock, flags); + return retv; + } + +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +index 06de59521fc4..fbf4cbcf1a65 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +@@ -13,25 +13,6 @@ + #include "rmnet_vnd.h" + #include "rmnet_private.h" + +-/* Locking scheme - +- * The shared resource which needs to be protected is realdev->rx_handler_data. +- * For the writer path, this is using rtnl_lock(). The writer paths are +- * rmnet_newlink(), rmnet_dellink() and rmnet_force_unassociate_device(). These +- * paths are already called with rtnl_lock() acquired in. There is also an +- * ASSERT_RTNL() to ensure that we are calling with rtnl acquired. For +- * dereference here, we will need to use rtnl_dereference(). Dev list writing +- * needs to happen with rtnl_lock() acquired for netdev_master_upper_dev_link(). +- * For the reader path, the real_dev->rx_handler_data is called in the TX / RX +- * path. We only need rcu_read_lock() for these scenarios. In these cases, +- * the rcu_read_lock() is held in __dev_queue_xmit() and +- * netif_receive_skb_internal(), so readers need to use rcu_dereference_rtnl() +- * to get the relevant information. For dev list reading, we again acquire +- * rcu_read_lock() in rmnet_dellink() for netdev_master_upper_dev_get_rcu(). +- * We also use unregister_netdevice_many() to free all rmnet devices in +- * rmnet_force_unassociate_device() so we dont lose the rtnl_lock() and free in +- * same context. +- */ +- + /* Local Definitions and Declarations */ + + static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX + 1] = { +@@ -51,9 +32,10 @@ rmnet_get_port_rtnl(const struct net_device *real_dev) + return rtnl_dereference(real_dev->rx_handler_data); + } + +-static int rmnet_unregister_real_device(struct net_device *real_dev, +- struct rmnet_port *port) ++static int rmnet_unregister_real_device(struct net_device *real_dev) + { ++ struct rmnet_port *port = rmnet_get_port_rtnl(real_dev); ++ + if (port->nr_rmnet_devs) + return -EINVAL; + +@@ -61,9 +43,6 @@ static int rmnet_unregister_real_device(struct net_device *real_dev, + + kfree(port); + +- /* release reference on real_dev */ +- dev_put(real_dev); +- + netdev_dbg(real_dev, "Removed from rmnet\n"); + return 0; + } +@@ -89,9 +68,6 @@ static int rmnet_register_real_device(struct net_device *real_dev) + return -EBUSY; + } + +- /* hold on to real dev for MAP data */ +- dev_hold(real_dev); +- + for (entry = 0; entry < RMNET_MAX_LOGICAL_EP; entry++) + INIT_HLIST_HEAD(&port->muxed_ep[entry]); + +@@ -99,28 +75,33 @@ static int rmnet_register_real_device(struct net_device *real_dev) + return 0; + } + +-static void rmnet_unregister_bridge(struct net_device *dev, +- struct rmnet_port *port) ++static void rmnet_unregister_bridge(struct rmnet_port *port) + { +- struct rmnet_port *bridge_port; +- struct net_device *bridge_dev; ++ struct net_device *bridge_dev, *real_dev, *rmnet_dev; ++ struct rmnet_port *real_port; + + if (port->rmnet_mode != RMNET_EPMODE_BRIDGE) + return; + +- /* bridge slave handling */ ++ rmnet_dev = port->rmnet_dev; + if (!port->nr_rmnet_devs) { +- bridge_dev = port->bridge_ep; ++ /* bridge device */ ++ real_dev = port->bridge_ep; ++ bridge_dev = port->dev; + +- bridge_port = rmnet_get_port_rtnl(bridge_dev); +- bridge_port->bridge_ep = NULL; +- bridge_port->rmnet_mode = RMNET_EPMODE_VND; ++ real_port = rmnet_get_port_rtnl(real_dev); ++ real_port->bridge_ep = NULL; ++ real_port->rmnet_mode = RMNET_EPMODE_VND; + } else { ++ /* real device */ + bridge_dev = port->bridge_ep; + +- bridge_port = rmnet_get_port_rtnl(bridge_dev); +- rmnet_unregister_real_device(bridge_dev, bridge_port); ++ port->bridge_ep = NULL; ++ port->rmnet_mode = RMNET_EPMODE_VND; + } ++ ++ netdev_upper_dev_unlink(bridge_dev, rmnet_dev); ++ rmnet_unregister_real_device(bridge_dev); + } + + static int rmnet_newlink(struct net *src_net, struct net_device *dev, +@@ -135,6 +116,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, + int err = 0; + u16 mux_id; + ++ if (!tb[IFLA_LINK]) { ++ NL_SET_ERR_MSG_MOD(extack, "link not specified"); ++ return -EINVAL; ++ } ++ + real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK])); + if (!real_dev || !dev) + return -ENODEV; +@@ -157,7 +143,12 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, + if (err) + goto err1; + ++ err = netdev_upper_dev_link(real_dev, dev, extack); ++ if (err < 0) ++ goto err2; ++ + port->rmnet_mode = mode; ++ port->rmnet_dev = dev; + + hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]); + +@@ -173,8 +164,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, + + return 0; + ++err2: ++ unregister_netdevice(dev); ++ rmnet_vnd_dellink(mux_id, port, ep); + err1: +- rmnet_unregister_real_device(real_dev, port); ++ rmnet_unregister_real_device(real_dev); + err0: + kfree(ep); + return err; +@@ -183,77 +177,74 @@ err0: + static void rmnet_dellink(struct net_device *dev, struct list_head *head) + { + struct rmnet_priv *priv = netdev_priv(dev); +- struct net_device *real_dev; ++ struct net_device *real_dev, *bridge_dev; ++ struct rmnet_port *real_port, *bridge_port; + struct rmnet_endpoint *ep; +- struct rmnet_port *port; +- u8 mux_id; ++ u8 mux_id = priv->mux_id; + + real_dev = priv->real_dev; + +- if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) ++ if (!rmnet_is_real_dev_registered(real_dev)) + return; + +- port = rmnet_get_port_rtnl(real_dev); +- +- mux_id = rmnet_vnd_get_mux(dev); ++ real_port = rmnet_get_port_rtnl(real_dev); ++ bridge_dev = real_port->bridge_ep; ++ if (bridge_dev) { ++ bridge_port = rmnet_get_port_rtnl(bridge_dev); ++ rmnet_unregister_bridge(bridge_port); ++ } + +- ep = rmnet_get_endpoint(port, mux_id); ++ ep = rmnet_get_endpoint(real_port, mux_id); + if (ep) { + hlist_del_init_rcu(&ep->hlnode); +- rmnet_unregister_bridge(dev, port); +- rmnet_vnd_dellink(mux_id, port, ep); ++ rmnet_vnd_dellink(mux_id, real_port, ep); + kfree(ep); + } +- rmnet_unregister_real_device(real_dev, port); + ++ netdev_upper_dev_unlink(real_dev, dev); ++ rmnet_unregister_real_device(real_dev); + unregister_netdevice_queue(dev, head); + } + +-static void rmnet_force_unassociate_device(struct net_device *dev) ++static void rmnet_force_unassociate_device(struct net_device *real_dev) + { +- struct net_device *real_dev = dev; + struct hlist_node *tmp_ep; + struct rmnet_endpoint *ep; + struct rmnet_port *port; + unsigned long bkt_ep; + LIST_HEAD(list); + +- if (!rmnet_is_real_dev_registered(real_dev)) +- return; +- +- ASSERT_RTNL(); +- +- port = rmnet_get_port_rtnl(dev); +- +- rcu_read_lock(); +- rmnet_unregister_bridge(dev, port); +- +- hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { +- unregister_netdevice_queue(ep->egress_dev, &list); +- rmnet_vnd_dellink(ep->mux_id, port, ep); ++ port = rmnet_get_port_rtnl(real_dev); + +- hlist_del_init_rcu(&ep->hlnode); +- kfree(ep); ++ if (port->nr_rmnet_devs) { ++ /* real device */ ++ rmnet_unregister_bridge(port); ++ hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { ++ unregister_netdevice_queue(ep->egress_dev, &list); ++ netdev_upper_dev_unlink(real_dev, ep->egress_dev); ++ rmnet_vnd_dellink(ep->mux_id, port, ep); ++ hlist_del_init_rcu(&ep->hlnode); ++ kfree(ep); ++ } ++ rmnet_unregister_real_device(real_dev); ++ unregister_netdevice_many(&list); ++ } else { ++ rmnet_unregister_bridge(port); + } +- +- rcu_read_unlock(); +- unregister_netdevice_many(&list); +- +- rmnet_unregister_real_device(real_dev, port); + } + + static int rmnet_config_notify_cb(struct notifier_block *nb, + unsigned long event, void *data) + { +- struct net_device *dev = netdev_notifier_info_to_dev(data); ++ struct net_device *real_dev = netdev_notifier_info_to_dev(data); + +- if (!dev) ++ if (!rmnet_is_real_dev_registered(real_dev)) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UNREGISTER: +- netdev_dbg(dev, "Kernel unregister\n"); +- rmnet_force_unassociate_device(dev); ++ netdev_dbg(real_dev, "Kernel unregister\n"); ++ rmnet_force_unassociate_device(real_dev); + break; + + default: +@@ -295,16 +286,18 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[], + if (!dev) + return -ENODEV; + +- real_dev = __dev_get_by_index(dev_net(dev), +- nla_get_u32(tb[IFLA_LINK])); +- +- if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) ++ real_dev = priv->real_dev; ++ if (!rmnet_is_real_dev_registered(real_dev)) + return -ENODEV; + + port = rmnet_get_port_rtnl(real_dev); + + if (data[IFLA_RMNET_MUX_ID]) { + mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]); ++ if (rmnet_get_endpoint(port, mux_id)) { ++ NL_SET_ERR_MSG_MOD(extack, "MUX ID already exists"); ++ return -EINVAL; ++ } + ep = rmnet_get_endpoint(port, priv->mux_id); + if (!ep) + return -ENODEV; +@@ -379,11 +372,10 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = { + .fill_info = rmnet_fill_info, + }; + +-/* Needs either rcu_read_lock() or rtnl lock */ +-struct rmnet_port *rmnet_get_port(struct net_device *real_dev) ++struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev) + { + if (rmnet_is_real_dev_registered(real_dev)) +- return rcu_dereference_rtnl(real_dev->rx_handler_data); ++ return rcu_dereference_bh(real_dev->rx_handler_data); + else + return NULL; + } +@@ -409,7 +401,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, + struct rmnet_port *port, *slave_port; + int err; + +- port = rmnet_get_port(real_dev); ++ port = rmnet_get_port_rtnl(real_dev); + + /* If there is more than one rmnet dev attached, its probably being + * used for muxing. Skip the briding in that case +@@ -417,6 +409,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, + if (port->nr_rmnet_devs > 1) + return -EINVAL; + ++ if (port->rmnet_mode != RMNET_EPMODE_VND) ++ return -EINVAL; ++ + if (rmnet_is_real_dev_registered(slave_dev)) + return -EBUSY; + +@@ -424,9 +419,17 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, + if (err) + return -EBUSY; + +- slave_port = rmnet_get_port(slave_dev); ++ err = netdev_master_upper_dev_link(slave_dev, rmnet_dev, NULL, NULL, ++ extack); ++ if (err) { ++ rmnet_unregister_real_device(slave_dev); ++ return err; ++ } ++ ++ slave_port = rmnet_get_port_rtnl(slave_dev); + slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE; + slave_port->bridge_ep = real_dev; ++ slave_port->rmnet_dev = rmnet_dev; + + port->rmnet_mode = RMNET_EPMODE_BRIDGE; + port->bridge_ep = slave_dev; +@@ -438,16 +441,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, + int rmnet_del_bridge(struct net_device *rmnet_dev, + struct net_device *slave_dev) + { +- struct rmnet_priv *priv = netdev_priv(rmnet_dev); +- struct net_device *real_dev = priv->real_dev; +- struct rmnet_port *port, *slave_port; ++ struct rmnet_port *port = rmnet_get_port_rtnl(slave_dev); + +- port = rmnet_get_port(real_dev); +- port->rmnet_mode = RMNET_EPMODE_VND; +- port->bridge_ep = NULL; +- +- slave_port = rmnet_get_port(slave_dev); +- rmnet_unregister_real_device(slave_dev, slave_port); ++ rmnet_unregister_bridge(port); + + netdev_dbg(slave_dev, "removed from rmnet as slave\n"); + return 0; +@@ -473,8 +469,8 @@ static int __init rmnet_init(void) + + static void __exit rmnet_exit(void) + { +- unregister_netdevice_notifier(&rmnet_dev_notifier); + rtnl_link_unregister(&rmnet_link_ops); ++ unregister_netdevice_notifier(&rmnet_dev_notifier); + } + + module_init(rmnet_init) +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +index cd0a6bcbe74a..be515982d628 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +@@ -28,6 +28,7 @@ struct rmnet_port { + u8 rmnet_mode; + struct hlist_head muxed_ep[RMNET_MAX_LOGICAL_EP]; + struct net_device *bridge_ep; ++ struct net_device *rmnet_dev; + }; + + extern struct rtnl_link_ops rmnet_link_ops; +@@ -65,7 +66,7 @@ struct rmnet_priv { + struct rmnet_priv_stats stats; + }; + +-struct rmnet_port *rmnet_get_port(struct net_device *real_dev); ++struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev); + struct rmnet_endpoint *rmnet_get_endpoint(struct rmnet_port *port, u8 mux_id); + int rmnet_add_bridge(struct net_device *rmnet_dev, + struct net_device *slave_dev, +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +index 1b74bc160402..29a7bfa2584d 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +@@ -159,6 +159,9 @@ static int rmnet_map_egress_handler(struct sk_buff *skb, + static void + rmnet_bridge_handler(struct sk_buff *skb, struct net_device *bridge_dev) + { ++ if (skb_mac_header_was_set(skb)) ++ skb_push(skb, skb->mac_len); ++ + if (bridge_dev) { + skb->dev = bridge_dev; + dev_queue_xmit(skb); +@@ -184,7 +187,7 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb) + return RX_HANDLER_PASS; + + dev = skb->dev; +- port = rmnet_get_port(dev); ++ port = rmnet_get_port_rcu(dev); + + switch (port->rmnet_mode) { + case RMNET_EPMODE_VND: +@@ -217,7 +220,7 @@ void rmnet_egress_handler(struct sk_buff *skb) + skb->dev = priv->real_dev; + mux_id = priv->mux_id; + +- port = rmnet_get_port(skb->dev); ++ port = rmnet_get_port_rcu(skb->dev); + if (!port) + goto drop; + +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +index 509dfc895a33..26ad40f19c64 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +@@ -266,14 +266,6 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port, + return 0; + } + +-u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev) +-{ +- struct rmnet_priv *priv; +- +- priv = netdev_priv(rmnet_dev); +- return priv->mux_id; +-} +- + int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable) + { + netdev_dbg(rmnet_dev, "Setting VND TX queue state to %d\n", enable); +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h +index 54cbaf3c3bc4..14d77c709d4a 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h +@@ -16,6 +16,5 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port, + struct rmnet_endpoint *ep); + void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev); + void rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev); +-u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev); + void rmnet_vnd_setup(struct net_device *dev); + #endif /* _RMNET_VND_H_ */ +diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c +index af15a737c675..59b4f16896a8 100644 +--- a/drivers/net/ethernet/sfc/ptp.c ++++ b/drivers/net/ethernet/sfc/ptp.c +@@ -560,13 +560,45 @@ efx_ptp_mac_nic_to_ktime_correction(struct efx_nic *efx, + u32 nic_major, u32 nic_minor, + s32 correction) + { ++ u32 sync_timestamp; + ktime_t kt = { 0 }; ++ s16 delta; + + if (!(nic_major & 0x80000000)) { + WARN_ON_ONCE(nic_major >> 16); +- /* Use the top bits from the latest sync event. */ +- nic_major &= 0xffff; +- nic_major |= (last_sync_timestamp_major(efx) & 0xffff0000); ++ ++ /* Medford provides 48 bits of timestamp, so we must get the top ++ * 16 bits from the timesync event state. ++ * ++ * We only have the lower 16 bits of the time now, but we do ++ * have a full resolution timestamp at some point in past. As ++ * long as the difference between the (real) now and the sync ++ * is less than 2^15, then we can reconstruct the difference ++ * between those two numbers using only the lower 16 bits of ++ * each. ++ * ++ * Put another way ++ * ++ * a - b = ((a mod k) - b) mod k ++ * ++ * when -k/2 < (a-b) < k/2. In our case k is 2^16. We know ++ * (a mod k) and b, so can calculate the delta, a - b. ++ * ++ */ ++ sync_timestamp = last_sync_timestamp_major(efx); ++ ++ /* Because delta is s16 this does an implicit mask down to ++ * 16 bits which is what we need, assuming ++ * MEDFORD_TX_SECS_EVENT_BITS is 16. delta is signed so that ++ * we can deal with the (unlikely) case of sync timestamps ++ * arriving from the future. ++ */ ++ delta = nic_major - sync_timestamp; ++ ++ /* Recover the fully specified time now, by applying the offset ++ * to the (fully specified) sync time. ++ */ ++ nic_major = sync_timestamp + delta; + + kt = ptp->nic_to_kernel_time(nic_major, nic_minor, + correction); +diff --git a/drivers/net/ethernet/xilinx/ll_temac.h b/drivers/net/ethernet/xilinx/ll_temac.h +index 276292bca334..53fb8141f1a6 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac.h ++++ b/drivers/net/ethernet/xilinx/ll_temac.h +@@ -375,10 +375,14 @@ struct temac_local { + int tx_bd_next; + int tx_bd_tail; + int rx_bd_ci; ++ int rx_bd_tail; + + /* DMA channel control setup */ + u32 tx_chnl_ctrl; + u32 rx_chnl_ctrl; ++ u8 coalesce_count_rx; ++ ++ struct delayed_work restart_work; + }; + + /* Wrappers for temac_ior()/temac_iow() function pointers above */ +diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c +index 21c1b4322ea7..eb480204cdbe 100644 +--- a/drivers/net/ethernet/xilinx/ll_temac_main.c ++++ b/drivers/net/ethernet/xilinx/ll_temac_main.c +@@ -51,6 +51,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -367,6 +368,8 @@ static int temac_dma_bd_init(struct net_device *ndev) + skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, + XTE_MAX_JUMBO_FRAME_SIZE, + DMA_FROM_DEVICE); ++ if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) ++ goto out; + lp->rx_bd_v[i].phys = cpu_to_be32(skb_dma_addr); + lp->rx_bd_v[i].len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); + lp->rx_bd_v[i].app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); +@@ -387,12 +390,13 @@ static int temac_dma_bd_init(struct net_device *ndev) + lp->tx_bd_next = 0; + lp->tx_bd_tail = 0; + lp->rx_bd_ci = 0; ++ lp->rx_bd_tail = RX_BD_NUM - 1; + + /* Enable RX DMA transfers */ + wmb(); + lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); + lp->dma_out(lp, RX_TAILDESC_PTR, +- lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); ++ lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * lp->rx_bd_tail)); + + /* Prepare for TX DMA transfer */ + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); +@@ -788,6 +792,9 @@ static void temac_start_xmit_done(struct net_device *ndev) + stat = be32_to_cpu(cur_p->app0); + } + ++ /* Matches barrier in temac_start_xmit */ ++ smp_mb(); ++ + netif_wake_queue(ndev); + } + +@@ -830,9 +837,19 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + + if (temac_check_tx_bd_space(lp, num_frag + 1)) { +- if (!netif_queue_stopped(ndev)) +- netif_stop_queue(ndev); +- return NETDEV_TX_BUSY; ++ if (netif_queue_stopped(ndev)) ++ return NETDEV_TX_BUSY; ++ ++ netif_stop_queue(ndev); ++ ++ /* Matches barrier in temac_start_xmit_done */ ++ smp_mb(); ++ ++ /* Space might have just been freed - check again */ ++ if (temac_check_tx_bd_space(lp, num_frag)) ++ return NETDEV_TX_BUSY; ++ ++ netif_wake_queue(ndev); + } + + cur_p->app0 = 0; +@@ -850,12 +867,16 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) + skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + cur_p->len = cpu_to_be32(skb_headlen(skb)); ++ if (WARN_ON_ONCE(dma_mapping_error(ndev->dev.parent, skb_dma_addr))) { ++ dev_kfree_skb_any(skb); ++ ndev->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++ } + cur_p->phys = cpu_to_be32(skb_dma_addr); + ptr_to_txbd((void *)skb, cur_p); + + for (ii = 0; ii < num_frag; ii++) { +- lp->tx_bd_tail++; +- if (lp->tx_bd_tail >= TX_BD_NUM) ++ if (++lp->tx_bd_tail >= TX_BD_NUM) + lp->tx_bd_tail = 0; + + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; +@@ -863,6 +884,27 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) + skb_frag_address(frag), + skb_frag_size(frag), + DMA_TO_DEVICE); ++ if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) { ++ if (--lp->tx_bd_tail < 0) ++ lp->tx_bd_tail = TX_BD_NUM - 1; ++ cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; ++ while (--ii >= 0) { ++ --frag; ++ dma_unmap_single(ndev->dev.parent, ++ be32_to_cpu(cur_p->phys), ++ skb_frag_size(frag), ++ DMA_TO_DEVICE); ++ if (--lp->tx_bd_tail < 0) ++ lp->tx_bd_tail = TX_BD_NUM - 1; ++ cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; ++ } ++ dma_unmap_single(ndev->dev.parent, ++ be32_to_cpu(cur_p->phys), ++ skb_headlen(skb), DMA_TO_DEVICE); ++ dev_kfree_skb_any(skb); ++ ndev->stats.tx_dropped++; ++ return NETDEV_TX_OK; ++ } + cur_p->phys = cpu_to_be32(skb_dma_addr); + cur_p->len = cpu_to_be32(skb_frag_size(frag)); + cur_p->app0 = 0; +@@ -884,31 +926,56 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) + return NETDEV_TX_OK; + } + ++static int ll_temac_recv_buffers_available(struct temac_local *lp) ++{ ++ int available; ++ ++ if (!lp->rx_skb[lp->rx_bd_ci]) ++ return 0; ++ available = 1 + lp->rx_bd_tail - lp->rx_bd_ci; ++ if (available <= 0) ++ available += RX_BD_NUM; ++ return available; ++} + + static void ll_temac_recv(struct net_device *ndev) + { + struct temac_local *lp = netdev_priv(ndev); +- struct sk_buff *skb, *new_skb; +- unsigned int bdstat; +- struct cdmac_bd *cur_p; +- dma_addr_t tail_p, skb_dma_addr; +- int length; + unsigned long flags; ++ int rx_bd; ++ bool update_tail = false; + + spin_lock_irqsave(&lp->rx_lock, flags); + +- tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; +- cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; +- +- bdstat = be32_to_cpu(cur_p->app0); +- while ((bdstat & STS_CTRL_APP0_CMPLT)) { ++ /* Process all received buffers, passing them on network ++ * stack. After this, the buffer descriptors will be in an ++ * un-allocated stage, where no skb is allocated for it, and ++ * they are therefore not available for TEMAC/DMA. ++ */ ++ do { ++ struct cdmac_bd *bd = &lp->rx_bd_v[lp->rx_bd_ci]; ++ struct sk_buff *skb = lp->rx_skb[lp->rx_bd_ci]; ++ unsigned int bdstat = be32_to_cpu(bd->app0); ++ int length; ++ ++ /* While this should not normally happen, we can end ++ * here when GFP_ATOMIC allocations fail, and we ++ * therefore have un-allocated buffers. ++ */ ++ if (!skb) ++ break; + +- skb = lp->rx_skb[lp->rx_bd_ci]; +- length = be32_to_cpu(cur_p->app4) & 0x3FFF; ++ /* Loop over all completed buffer descriptors */ ++ if (!(bdstat & STS_CTRL_APP0_CMPLT)) ++ break; + +- dma_unmap_single(ndev->dev.parent, be32_to_cpu(cur_p->phys), ++ dma_unmap_single(ndev->dev.parent, be32_to_cpu(bd->phys), + XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); ++ /* The buffer is not valid for DMA anymore */ ++ bd->phys = 0; ++ bd->len = 0; + ++ length = be32_to_cpu(bd->app4) & 0x3FFF; + skb_put(skb, length); + skb->protocol = eth_type_trans(skb, ndev); + skb_checksum_none_assert(skb); +@@ -923,43 +990,102 @@ static void ll_temac_recv(struct net_device *ndev) + * (back) for proper IP checksum byte order + * (be16). + */ +- skb->csum = htons(be32_to_cpu(cur_p->app3) & 0xFFFF); ++ skb->csum = htons(be32_to_cpu(bd->app3) & 0xFFFF); + skb->ip_summed = CHECKSUM_COMPLETE; + } + + if (!skb_defer_rx_timestamp(skb)) + netif_rx(skb); ++ /* The skb buffer is now owned by network stack above */ ++ lp->rx_skb[lp->rx_bd_ci] = NULL; + + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += length; + +- new_skb = netdev_alloc_skb_ip_align(ndev, +- XTE_MAX_JUMBO_FRAME_SIZE); +- if (!new_skb) { +- spin_unlock_irqrestore(&lp->rx_lock, flags); +- return; ++ rx_bd = lp->rx_bd_ci; ++ if (++lp->rx_bd_ci >= RX_BD_NUM) ++ lp->rx_bd_ci = 0; ++ } while (rx_bd != lp->rx_bd_tail); ++ ++ /* DMA operations will halt when the last buffer descriptor is ++ * processed (ie. the one pointed to by RX_TAILDESC_PTR). ++ * When that happens, no more interrupt events will be ++ * generated. No IRQ_COAL or IRQ_DLY, and not even an ++ * IRQ_ERR. To avoid stalling, we schedule a delayed work ++ * when there is a potential risk of that happening. The work ++ * will call this function, and thus re-schedule itself until ++ * enough buffers are available again. ++ */ ++ if (ll_temac_recv_buffers_available(lp) < lp->coalesce_count_rx) ++ schedule_delayed_work(&lp->restart_work, HZ / 1000); ++ ++ /* Allocate new buffers for those buffer descriptors that were ++ * passed to network stack. Note that GFP_ATOMIC allocations ++ * can fail (e.g. when a larger burst of GFP_ATOMIC ++ * allocations occurs), so while we try to allocate all ++ * buffers in the same interrupt where they were processed, we ++ * continue with what we could get in case of allocation ++ * failure. Allocation of remaining buffers will be retried ++ * in following calls. ++ */ ++ while (1) { ++ struct sk_buff *skb; ++ struct cdmac_bd *bd; ++ dma_addr_t skb_dma_addr; ++ ++ rx_bd = lp->rx_bd_tail + 1; ++ if (rx_bd >= RX_BD_NUM) ++ rx_bd = 0; ++ bd = &lp->rx_bd_v[rx_bd]; ++ ++ if (bd->phys) ++ break; /* All skb's allocated */ ++ ++ skb = netdev_alloc_skb_ip_align(ndev, XTE_MAX_JUMBO_FRAME_SIZE); ++ if (!skb) { ++ dev_warn(&ndev->dev, "skb alloc failed\n"); ++ break; + } + +- cur_p->app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); +- skb_dma_addr = dma_map_single(ndev->dev.parent, new_skb->data, ++ skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, + XTE_MAX_JUMBO_FRAME_SIZE, + DMA_FROM_DEVICE); +- cur_p->phys = cpu_to_be32(skb_dma_addr); +- cur_p->len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); +- lp->rx_skb[lp->rx_bd_ci] = new_skb; ++ if (WARN_ON_ONCE(dma_mapping_error(ndev->dev.parent, ++ skb_dma_addr))) { ++ dev_kfree_skb_any(skb); ++ break; ++ } + +- lp->rx_bd_ci++; +- if (lp->rx_bd_ci >= RX_BD_NUM) +- lp->rx_bd_ci = 0; ++ bd->phys = cpu_to_be32(skb_dma_addr); ++ bd->len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); ++ bd->app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); ++ lp->rx_skb[rx_bd] = skb; + +- cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; +- bdstat = be32_to_cpu(cur_p->app0); ++ lp->rx_bd_tail = rx_bd; ++ update_tail = true; ++ } ++ ++ /* Move tail pointer when buffers have been allocated */ ++ if (update_tail) { ++ lp->dma_out(lp, RX_TAILDESC_PTR, ++ lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_tail); + } +- lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); + + spin_unlock_irqrestore(&lp->rx_lock, flags); + } + ++/* Function scheduled to ensure a restart in case of DMA halt ++ * condition caused by running out of buffer descriptors. ++ */ ++static void ll_temac_restart_work_func(struct work_struct *work) ++{ ++ struct temac_local *lp = container_of(work, struct temac_local, ++ restart_work.work); ++ struct net_device *ndev = lp->ndev; ++ ++ ll_temac_recv(ndev); ++} ++ + static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) + { + struct net_device *ndev = _ndev; +@@ -1052,6 +1178,8 @@ static int temac_stop(struct net_device *ndev) + + dev_dbg(&ndev->dev, "temac_close()\n"); + ++ cancel_delayed_work_sync(&lp->restart_work); ++ + free_irq(lp->tx_irq, ndev); + free_irq(lp->rx_irq, ndev); + +@@ -1184,6 +1312,7 @@ static int temac_probe(struct platform_device *pdev) + lp->dev = &pdev->dev; + lp->options = XTE_OPTION_DEFAULTS; + spin_lock_init(&lp->rx_lock); ++ INIT_DELAYED_WORK(&lp->restart_work, ll_temac_restart_work_func); + + /* Setup mutex for synchronization of indirect register access */ + if (pdata) { +@@ -1290,6 +1419,7 @@ static int temac_probe(struct platform_device *pdev) + */ + lp->tx_chnl_ctrl = 0x10220000; + lp->rx_chnl_ctrl = 0xff070000; ++ lp->coalesce_count_rx = 0x07; + + /* Finished with the DMA node; drop the reference */ + of_node_put(dma_np); +@@ -1321,11 +1451,14 @@ static int temac_probe(struct platform_device *pdev) + (pdata->tx_irq_count << 16); + else + lp->tx_chnl_ctrl = 0x10220000; +- if (pdata->rx_irq_timeout || pdata->rx_irq_count) ++ if (pdata->rx_irq_timeout || pdata->rx_irq_count) { + lp->rx_chnl_ctrl = (pdata->rx_irq_timeout << 24) | + (pdata->rx_irq_count << 16); +- else ++ lp->coalesce_count_rx = pdata->rx_irq_count; ++ } else { + lp->rx_chnl_ctrl = 0xff070000; ++ lp->coalesce_count_rx = 0x07; ++ } + } + + /* Error handle returned DMA RX and TX interrupts */ +diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c +index 7ada1fd9ca71..2339b9381d21 100644 +--- a/drivers/net/phy/mscc.c ++++ b/drivers/net/phy/mscc.c +@@ -302,11 +302,11 @@ enum rgmii_rx_clock_delay { + BIT(VSC8531_FORCE_LED_OFF) | \ + BIT(VSC8531_FORCE_LED_ON)) + +-#define MSCC_VSC8584_REVB_INT8051_FW "mscc_vsc8584_revb_int8051_fb48.bin" ++#define MSCC_VSC8584_REVB_INT8051_FW "microchip/mscc_vsc8584_revb_int8051_fb48.bin" + #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800 + #define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48 + +-#define MSCC_VSC8574_REVB_INT8051_FW "mscc_vsc8574_revb_int8051_29e8.bin" ++#define MSCC_VSC8574_REVB_INT8051_FW "microchip/mscc_vsc8574_revb_int8051_29e8.bin" + #define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000 + #define MSCC_VSC8574_REVB_INT8051_FW_CRC 0x29e8 + +diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c +index 61d7e0d1d77d..8e56a41dd758 100644 +--- a/drivers/net/slip/slip.c ++++ b/drivers/net/slip/slip.c +@@ -863,7 +863,10 @@ err_free_chan: + tty->disc_data = NULL; + clear_bit(SLF_INUSE, &sl->flags); + sl_free_netdev(sl->dev); ++ /* do not call free_netdev before rtnl_unlock */ ++ rtnl_unlock(); + free_netdev(sl->dev); ++ return err; + + err_exit: + rtnl_unlock(); +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 3b7a3b8a5e06..5754bb6ca0ee 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -337,6 +337,9 @@ static void qmi_wwan_netdev_setup(struct net_device *net) + netdev_dbg(net, "mode: raw IP\n"); + } else if (!net->header_ops) { /* don't bother if already set */ + ether_setup(net); ++ /* Restoring min/max mtu values set originally by usbnet */ ++ net->min_mtu = 0; ++ net->max_mtu = ETH_MAX_MTU; + clear_bit(EVENT_NO_IP_ALIGN, &dev->flags); + netdev_dbg(net, "mode: Ethernet\n"); + } +diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c +index 9c5f7c9178c6..2b865c6423e2 100644 +--- a/drivers/scsi/libfc/fc_disc.c ++++ b/drivers/scsi/libfc/fc_disc.c +@@ -628,6 +628,8 @@ redisc: + } + out: + kref_put(&rdata->kref, fc_rport_destroy); ++ if (!IS_ERR(fp)) ++ fc_frame_free(fp); + } + + /** +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index 1ce39de917f0..88c5e6361aa0 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -54,6 +54,13 @@ module_param(nowayout, bool, 0); + MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + ++#define WDAT_DEFAULT_TIMEOUT 30 ++ ++static int timeout = WDAT_DEFAULT_TIMEOUT; ++module_param(timeout, int, 0); ++MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" ++ __MODULE_STRING(WDAT_DEFAULT_TIMEOUT) ")"); ++ + static int wdat_wdt_read(struct wdat_wdt *wdat, + const struct wdat_instruction *instr, u32 *value) + { +@@ -438,6 +445,22 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + platform_set_drvdata(pdev, wdat); + ++ /* ++ * Set initial timeout so that userspace has time to configure the ++ * watchdog properly after it has opened the device. In some cases ++ * the BIOS default is too short and causes immediate reboot. ++ */ ++ if (timeout * 1000 < wdat->wdd.min_hw_heartbeat_ms || ++ timeout * 1000 > wdat->wdd.max_hw_heartbeat_ms) { ++ dev_warn(dev, "Invalid timeout %d given, using %d\n", ++ timeout, WDAT_DEFAULT_TIMEOUT); ++ timeout = WDAT_DEFAULT_TIMEOUT; ++ } ++ ++ ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); ++ if (ret) ++ return ret; ++ + watchdog_set_nowayout(&wdat->wdd, nowayout); + return devm_watchdog_register_device(dev, &wdat->wdd); + } +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index b17f05ae6011..de992a70ddfe 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -1079,8 +1079,8 @@ static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh, + /* For undo access buffer must have data copied */ + if (undo && !jh->b_committed_data) + goto out; +- if (jh->b_transaction != handle->h_transaction && +- jh->b_next_transaction != handle->h_transaction) ++ if (READ_ONCE(jh->b_transaction) != handle->h_transaction && ++ READ_ONCE(jh->b_next_transaction) != handle->h_transaction) + goto out; + /* + * There are two reasons for the barrier here: +@@ -2535,8 +2535,8 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh) + * our jh reference and thus __jbd2_journal_file_buffer() must not + * take a new one. + */ +- jh->b_transaction = jh->b_next_transaction; +- jh->b_next_transaction = NULL; ++ WRITE_ONCE(jh->b_transaction, jh->b_next_transaction); ++ WRITE_ONCE(jh->b_next_transaction, NULL); + if (buffer_freed(bh)) + jlist = BJ_Forget; + else if (jh->b_modified) +diff --git a/kernel/signal.c b/kernel/signal.c +index bcd46f547db3..eea748174ade 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -413,27 +413,32 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi + { + struct sigqueue *q = NULL; + struct user_struct *user; ++ int sigpending; + + /* + * Protect access to @t credentials. This can go away when all + * callers hold rcu read lock. ++ * ++ * NOTE! A pending signal will hold on to the user refcount, ++ * and we get/put the refcount only when the sigpending count ++ * changes from/to zero. + */ + rcu_read_lock(); +- user = get_uid(__task_cred(t)->user); +- atomic_inc(&user->sigpending); ++ user = __task_cred(t)->user; ++ sigpending = atomic_inc_return(&user->sigpending); ++ if (sigpending == 1) ++ get_uid(user); + rcu_read_unlock(); + +- if (override_rlimit || +- atomic_read(&user->sigpending) <= +- task_rlimit(t, RLIMIT_SIGPENDING)) { ++ if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) { + q = kmem_cache_alloc(sigqueue_cachep, flags); + } else { + print_dropped_signal(sig); + } + + if (unlikely(q == NULL)) { +- atomic_dec(&user->sigpending); +- free_uid(user); ++ if (atomic_dec_and_test(&user->sigpending)) ++ free_uid(user); + } else { + INIT_LIST_HEAD(&q->list); + q->flags = 0; +@@ -447,8 +452,8 @@ static void __sigqueue_free(struct sigqueue *q) + { + if (q->flags & SIGQUEUE_PREALLOC) + return; +- atomic_dec(&q->user->sigpending); +- free_uid(q->user); ++ if (atomic_dec_and_test(&q->user->sigpending)) ++ free_uid(q->user); + kmem_cache_free(sigqueue_cachep, q); + } + +diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c +index a31be3fce3e8..6495800fb92a 100644 +--- a/kernel/trace/trace_events_hist.c ++++ b/kernel/trace/trace_events_hist.c +@@ -811,6 +811,29 @@ static const char *synth_field_fmt(char *type) + return fmt; + } + ++static void print_synth_event_num_val(struct trace_seq *s, ++ char *print_fmt, char *name, ++ int size, u64 val, char *space) ++{ ++ switch (size) { ++ case 1: ++ trace_seq_printf(s, print_fmt, name, (u8)val, space); ++ break; ++ ++ case 2: ++ trace_seq_printf(s, print_fmt, name, (u16)val, space); ++ break; ++ ++ case 4: ++ trace_seq_printf(s, print_fmt, name, (u32)val, space); ++ break; ++ ++ default: ++ trace_seq_printf(s, print_fmt, name, val, space); ++ break; ++ } ++} ++ + static enum print_line_t print_synth_event(struct trace_iterator *iter, + int flags, + struct trace_event *event) +@@ -849,10 +872,13 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter, + } else { + struct trace_print_flags __flags[] = { + __def_gfpflag_names, {-1, NULL} }; ++ char *space = (i == se->n_fields - 1 ? "" : " "); + +- trace_seq_printf(s, print_fmt, se->fields[i]->name, +- entry->fields[n_u64], +- i == se->n_fields - 1 ? "" : " "); ++ print_synth_event_num_val(s, print_fmt, ++ se->fields[i]->name, ++ se->fields[i]->size, ++ entry->fields[n_u64], ++ space); + + if (strcmp(se->fields[i]->type, "gfp_t") == 0) { + trace_seq_puts(s, " ("); +diff --git a/mm/slub.c b/mm/slub.c +index 20d72cb20515..3ca4a223f44c 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -3154,6 +3154,15 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, + void *object = c->freelist; + + if (unlikely(!object)) { ++ /* ++ * We may have removed an object from c->freelist using ++ * the fastpath in the previous iteration; in that case, ++ * c->tid has not been bumped yet. ++ * Since ___slab_alloc() may reenable interrupts while ++ * allocating memory, we should bump c->tid now. ++ */ ++ c->tid = next_tid(c->tid); ++ + /* + * Invoking slow path likely have side-effect + * of re-populating per CPU c->freelist +diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c +index 376882215919..0bd10a1f477f 100644 +--- a/net/ipv4/cipso_ipv4.c ++++ b/net/ipv4/cipso_ipv4.c +@@ -1724,6 +1724,7 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) + { + unsigned char optbuf[sizeof(struct ip_options) + 40]; + struct ip_options *opt = (struct ip_options *)optbuf; ++ int res; + + if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES) + return; +@@ -1735,7 +1736,11 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) + + memset(opt, 0, sizeof(struct ip_options)); + opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); +- if (__ip_options_compile(dev_net(skb->dev), opt, skb, NULL)) ++ rcu_read_lock(); ++ res = __ip_options_compile(dev_net(skb->dev), opt, skb, NULL); ++ rcu_read_unlock(); ++ ++ if (res) + return; + + if (gateway) +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 0e05ff037672..0ba98ad9bc85 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -4114,7 +4114,7 @@ void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata) + + lockdep_assert_held(&local->sta_mtx); + +- list_for_each_entry_rcu(sta, &local->sta_list, list) { ++ list_for_each_entry(sta, &local->sta_list, list) { + if (sdata != sta->sdata && + (!sta->sdata->bss || sta->sdata->bss != sdata->bss)) + continue; +diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c +index 1b68a131083c..8c835ad63729 100644 +--- a/net/netfilter/xt_hashlimit.c ++++ b/net/netfilter/xt_hashlimit.c +@@ -358,21 +358,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg, + return 0; + } + +-static bool select_all(const struct xt_hashlimit_htable *ht, +- const struct dsthash_ent *he) +-{ +- return true; +-} +- +-static bool select_gc(const struct xt_hashlimit_htable *ht, +- const struct dsthash_ent *he) +-{ +- return time_after_eq(jiffies, he->expires); +-} +- +-static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, +- bool (*select)(const struct xt_hashlimit_htable *ht, +- const struct dsthash_ent *he)) ++static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, bool select_all) + { + unsigned int i; + +@@ -382,7 +368,7 @@ static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, + + spin_lock_bh(&ht->lock); + hlist_for_each_entry_safe(dh, n, &ht->hash[i], node) { +- if ((*select)(ht, dh)) ++ if (time_after_eq(jiffies, dh->expires) || select_all) + dsthash_free(ht, dh); + } + spin_unlock_bh(&ht->lock); +@@ -396,7 +382,7 @@ static void htable_gc(struct work_struct *work) + + ht = container_of(work, struct xt_hashlimit_htable, gc_work.work); + +- htable_selective_cleanup(ht, select_gc); ++ htable_selective_cleanup(ht, false); + + queue_delayed_work(system_power_efficient_wq, + &ht->gc_work, msecs_to_jiffies(ht->cfg.gc_interval)); +@@ -416,15 +402,6 @@ static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo) + remove_proc_entry(hinfo->name, parent); + } + +-static void htable_destroy(struct xt_hashlimit_htable *hinfo) +-{ +- cancel_delayed_work_sync(&hinfo->gc_work); +- htable_remove_proc_entry(hinfo); +- htable_selective_cleanup(hinfo, select_all); +- kfree(hinfo->name); +- vfree(hinfo); +-} +- + static struct xt_hashlimit_htable *htable_find_get(struct net *net, + const char *name, + u_int8_t family) +@@ -446,8 +423,13 @@ static void htable_put(struct xt_hashlimit_htable *hinfo) + { + if (refcount_dec_and_mutex_lock(&hinfo->use, &hashlimit_mutex)) { + hlist_del(&hinfo->node); ++ htable_remove_proc_entry(hinfo); + mutex_unlock(&hashlimit_mutex); +- htable_destroy(hinfo); ++ ++ cancel_delayed_work_sync(&hinfo->gc_work); ++ htable_selective_cleanup(hinfo, true); ++ kfree(hinfo->name); ++ vfree(hinfo); + } + } + +diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c +index 88f98f27ad88..3d24d45be5f4 100644 +--- a/net/qrtr/qrtr.c ++++ b/net/qrtr/qrtr.c +@@ -196,7 +196,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, + hdr->size = cpu_to_le32(len); + hdr->confirm_rx = 0; + +- skb_put_padto(skb, ALIGN(len, 4)); ++ skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr)); + + mutex_lock(&node->ep_lock); + if (node->ep) +diff --git a/net/wireless/reg.c b/net/wireless/reg.c +index fff9a74891fc..1a8218f1bbe0 100644 +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -2276,7 +2276,7 @@ static void handle_channel_custom(struct wiphy *wiphy, + break; + } + +- if (IS_ERR(reg_rule)) { ++ if (IS_ERR_OR_NULL(reg_rule)) { + pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n", + chan->center_freq); + if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) { +diff --git a/tools/testing/selftests/rseq/Makefile b/tools/testing/selftests/rseq/Makefile +index f1053630bb6f..2af9d39a9716 100644 +--- a/tools/testing/selftests/rseq/Makefile ++++ b/tools/testing/selftests/rseq/Makefile +@@ -4,7 +4,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) + CLANG_FLAGS += -no-integrated-as + endif + +-CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L./ -Wl,-rpath=./ \ ++CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L$(OUTPUT) -Wl,-rpath=./ \ + $(CLANG_FLAGS) + LDLIBS += -lpthread + diff --git a/patch/kernel/odroidxu4-current/overlay.patch b/patch/kernel/odroidxu4-current/overlay.patch index ba65e83adf..2c6b021d6d 100644 --- a/patch/kernel/odroidxu4-current/overlay.patch +++ b/patch/kernel/odroidxu4-current/overlay.patch @@ -51,11 +51,11 @@ index 07998b60d56cf..5579165a84634 100644 %.dtb: include/config/kernel.release scripts_dtc $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ --PHONY += dtbs dtbs_install dt_binding_check +-PHONY += dtbs dtbs_install dtbs_check +%.dtbo: + $(Q)$(MAKE) -C $(dtstree)/overlays $@ + -+PHONY += dtbs dtbs_install dt_binding_check dtbos ++PHONY += dtbs dtbs_install dtbs_check dtbos +dtbos: + $(Q)$(MAKE) -C $(dtstree)/overlays dtbs dtbs_check: include/config/kernel.release scripts_dtc diff --git a/patch/kernel/rockchip64-current/board-rk3399-increase_CPU_frequency_during_early_boot.patch b/patch/kernel/rockchip64-current/board-rk3399-increase_CPU_frequency_during_early_boot.patch new file mode 100644 index 0000000000..70715915c3 --- /dev/null +++ b/patch/kernel/rockchip64-current/board-rk3399-increase_CPU_frequency_during_early_boot.patch @@ -0,0 +1,113 @@ +From 0a2aa023e6180b6d0416ed61310a57ce24d03dba Mon Sep 17 00:00:00 2001 +From: Heiher +Date: Fri, 20 Mar 2020 00:46:13 +0800 +Subject: [PATCH] arm64: rk3399: increase CPU frequency during early boot + +This is a workaround to fix the following issues. The right way should +be to increase frequency of CPU before boot linux kernel in bootloader. + +[ 92.165850] watchdog: BUG: soft lockup - CPU#4 stuck for 22s! [swapper/0:1] +[ 92.166643] Modules linked in: +[ 92.167463] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.5.10-ARCH #1 +[ 92.168025] Hardware name: FriendlyElec NanoPi M4 (DT) +[ 92.168672] pstate: 20000005 (nzCv daif -PAN -UAO) +[ 92.169504] pc : trace_event_eval_update+0xfc/0x348 +[ 92.170164] lr : trace_event_eval_update+0x144/0x348 +[ 92.170652] sp : ffff80001004bcf0 +[ 92.171112] x29: ffff80001004bcf0 x28: 0000000000000001 +[ 92.171834] x27: ffff8000118d2228 x26: ffff8000111710b0 +[ 92.172502] x25: ffff80001180db98 x24: 000000000000000e +[ 92.173134] x23: ffff800011746428 x22: 00000000000000ec +[ 92.173749] x21: 0000000000000264 x20: 0000000000000158 +[ 92.174352] x19: ffff8000118bc778 x18: 0000000000000001 +[ 92.174951] x17: 00000000ed34b782 x16: 00000000d54c3662 +[ 92.175549] x15: 2d20377b1910031c x14: ff00000000000000 +[ 92.176140] x13: 0000000000000000 x12: 0000000000000007 +[ 92.176731] x11: 0101010101010101 x10: 0000000000000005 +[ 92.177322] x9 : 0000000000000003 x8 : 0000000000000008 +[ 92.177922] x7 : 1c0310197b37202d x6 : 2d20377b1910031c +[ 92.178506] x5 : 0000000000000000 x4 : 000000000000000e +[ 92.179085] x3 : ffff8000118bbbee x2 : 0000000000000045 +[ 92.179671] x1 : 000000000000002c x0 : 0000000000000000 +[ 92.180263] Call trace: +[ 92.180921] trace_event_eval_update+0xfc/0x348 +[ 92.181652] tracer_init_tracefs+0x160/0x1e8 +[ 92.182304] do_one_initcall+0x4c/0x218 +[ 92.182949] kernel_init_freeable+0x1d0/0x240 +[ 92.183652] kernel_init+0x18/0x104 +[ 92.184245] ret_from_fork+0x10/0x18 + +[ 133.872912] cpufreq: cpufreq_online: CPU4: Running at unlisted freq: 12000 KHz +[ 133.891606] cpufreq: cpufreq_online: CPU4: Unlisted initial frequency changed to: 408000 KHz +--- + arch/arm64/kernel/setup.c | 43 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c +index 56f6645617548..81f4538f231fe 100644 +--- a/arch/arm64/kernel/setup.c ++++ b/arch/arm64/kernel/setup.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -373,6 +374,36 @@ static inline bool cpu_can_disable(unsigned int cpu) + return false; + } + ++static unsigned long __init cpu_max_freq(unsigned int cpu) ++{ ++ unsigned long max_freq = 0; ++ struct device_node *cpu_node; ++ struct device_node *op_node; ++ struct device_node *np; ++ ++ cpu_node = of_get_cpu_node(cpu, NULL); ++ if (!cpu_node) ++ return 0; ++ ++ op_node = of_parse_phandle(cpu_node, "operating-points-v2", 0); ++ of_node_put(cpu_node); ++ if (!op_node) ++ return 0; ++ ++ for_each_available_child_of_node(op_node, np) { ++ u64 freq; ++ ++ if (of_property_read_u64(np, "opp-hz", &freq) < 0) ++ continue; ++ ++ if (freq > max_freq) ++ max_freq = freq; ++ } ++ of_node_put(op_node); ++ ++ return max_freq; ++} ++ + static int __init topology_init(void) + { + int i; +@@ -386,6 +417,18 @@ static int __init topology_init(void) + register_cpu(cpu, i); + } + ++ for_each_possible_cpu(i) { ++ struct device *cpu_dev = get_cpu_device(i); ++ unsigned long cpu_freq = cpu_max_freq(i); ++ if (cpu_dev && cpu_freq) { ++ struct clk *cpu_clk = clk_get(cpu_dev, NULL); ++ if (!PTR_ERR_OR_ZERO(cpu_clk)) { ++ clk_set_rate(cpu_clk, cpu_freq); ++ clk_put(cpu_clk); ++ } ++ } ++ } ++ + return 0; + } + subsys_initcall(topology_init); diff --git a/patch/kernel/rockchip64-dev/board-rk3399-increase_CPU_frequency_during_early_boot.patch b/patch/kernel/rockchip64-dev/board-rk3399-increase_CPU_frequency_during_early_boot.patch new file mode 100644 index 0000000000..70715915c3 --- /dev/null +++ b/patch/kernel/rockchip64-dev/board-rk3399-increase_CPU_frequency_during_early_boot.patch @@ -0,0 +1,113 @@ +From 0a2aa023e6180b6d0416ed61310a57ce24d03dba Mon Sep 17 00:00:00 2001 +From: Heiher +Date: Fri, 20 Mar 2020 00:46:13 +0800 +Subject: [PATCH] arm64: rk3399: increase CPU frequency during early boot + +This is a workaround to fix the following issues. The right way should +be to increase frequency of CPU before boot linux kernel in bootloader. + +[ 92.165850] watchdog: BUG: soft lockup - CPU#4 stuck for 22s! [swapper/0:1] +[ 92.166643] Modules linked in: +[ 92.167463] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.5.10-ARCH #1 +[ 92.168025] Hardware name: FriendlyElec NanoPi M4 (DT) +[ 92.168672] pstate: 20000005 (nzCv daif -PAN -UAO) +[ 92.169504] pc : trace_event_eval_update+0xfc/0x348 +[ 92.170164] lr : trace_event_eval_update+0x144/0x348 +[ 92.170652] sp : ffff80001004bcf0 +[ 92.171112] x29: ffff80001004bcf0 x28: 0000000000000001 +[ 92.171834] x27: ffff8000118d2228 x26: ffff8000111710b0 +[ 92.172502] x25: ffff80001180db98 x24: 000000000000000e +[ 92.173134] x23: ffff800011746428 x22: 00000000000000ec +[ 92.173749] x21: 0000000000000264 x20: 0000000000000158 +[ 92.174352] x19: ffff8000118bc778 x18: 0000000000000001 +[ 92.174951] x17: 00000000ed34b782 x16: 00000000d54c3662 +[ 92.175549] x15: 2d20377b1910031c x14: ff00000000000000 +[ 92.176140] x13: 0000000000000000 x12: 0000000000000007 +[ 92.176731] x11: 0101010101010101 x10: 0000000000000005 +[ 92.177322] x9 : 0000000000000003 x8 : 0000000000000008 +[ 92.177922] x7 : 1c0310197b37202d x6 : 2d20377b1910031c +[ 92.178506] x5 : 0000000000000000 x4 : 000000000000000e +[ 92.179085] x3 : ffff8000118bbbee x2 : 0000000000000045 +[ 92.179671] x1 : 000000000000002c x0 : 0000000000000000 +[ 92.180263] Call trace: +[ 92.180921] trace_event_eval_update+0xfc/0x348 +[ 92.181652] tracer_init_tracefs+0x160/0x1e8 +[ 92.182304] do_one_initcall+0x4c/0x218 +[ 92.182949] kernel_init_freeable+0x1d0/0x240 +[ 92.183652] kernel_init+0x18/0x104 +[ 92.184245] ret_from_fork+0x10/0x18 + +[ 133.872912] cpufreq: cpufreq_online: CPU4: Running at unlisted freq: 12000 KHz +[ 133.891606] cpufreq: cpufreq_online: CPU4: Unlisted initial frequency changed to: 408000 KHz +--- + arch/arm64/kernel/setup.c | 43 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c +index 56f6645617548..81f4538f231fe 100644 +--- a/arch/arm64/kernel/setup.c ++++ b/arch/arm64/kernel/setup.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -373,6 +374,36 @@ static inline bool cpu_can_disable(unsigned int cpu) + return false; + } + ++static unsigned long __init cpu_max_freq(unsigned int cpu) ++{ ++ unsigned long max_freq = 0; ++ struct device_node *cpu_node; ++ struct device_node *op_node; ++ struct device_node *np; ++ ++ cpu_node = of_get_cpu_node(cpu, NULL); ++ if (!cpu_node) ++ return 0; ++ ++ op_node = of_parse_phandle(cpu_node, "operating-points-v2", 0); ++ of_node_put(cpu_node); ++ if (!op_node) ++ return 0; ++ ++ for_each_available_child_of_node(op_node, np) { ++ u64 freq; ++ ++ if (of_property_read_u64(np, "opp-hz", &freq) < 0) ++ continue; ++ ++ if (freq > max_freq) ++ max_freq = freq; ++ } ++ of_node_put(op_node); ++ ++ return max_freq; ++} ++ + static int __init topology_init(void) + { + int i; +@@ -386,6 +417,18 @@ static int __init topology_init(void) + register_cpu(cpu, i); + } + ++ for_each_possible_cpu(i) { ++ struct device *cpu_dev = get_cpu_device(i); ++ unsigned long cpu_freq = cpu_max_freq(i); ++ if (cpu_dev && cpu_freq) { ++ struct clk *cpu_clk = clk_get(cpu_dev, NULL); ++ if (!PTR_ERR_OR_ZERO(cpu_clk)) { ++ clk_set_rate(cpu_clk, cpu_freq); ++ clk_put(cpu_clk); ++ } ++ } ++ } ++ + return 0; + } + subsys_initcall(topology_init);