summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-10-21 05:32:05 -0700
committerLinux Build Service Account <lnxbuild@localhost>2019-10-21 05:32:05 -0700
commit5f91b62563a63b32639ec0608024c10f91b687d6 (patch)
tree2c0d1336180f31b76edffbc871dabb7922664a8e
parent7a117f98b5fbd7726aed973448051fe71855be70 (diff)
parent6dec23e2d32dd103cb6ece90a831f3bb224a8f4f (diff)
Merge 6dec23e2d32dd103cb6ece90a831f3bb224a8f4f on remote branch
Change-Id: Ie9ffa6f969667108741ac99373d809eca056fc67
-rw-r--r--Makefile2
-rw-r--r--arch/arc/configs/axs101_defconfig1
-rw-r--r--arch/arc/configs/axs103_defconfig1
-rw-r--r--arch/arc/configs/axs103_smp_defconfig1
-rw-r--r--arch/arc/configs/nsim_700_defconfig1
-rw-r--r--arch/arc/configs/nsim_hs_defconfig1
-rw-r--r--arch/arc/configs/nsim_hs_smp_defconfig1
-rw-r--r--arch/arc/configs/nsimosci_defconfig1
-rw-r--r--arch/arc/configs/nsimosci_hs_defconfig1
-rw-r--r--arch/arc/configs/nsimosci_hs_smp_defconfig1
-rw-r--r--arch/arc/kernel/traps.c1
-rw-r--r--arch/arm/boot/dts/qcom/msm-arm-smmu-8996.dtsi15
-rw-r--r--arch/arm/boot/dts/qcom/msm8996.dtsi4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996pro-auto.dtsi122
-rw-r--r--arch/arm/mach-omap2/omap4-common.c3
-rw-r--r--arch/arm/mm/init.c3
-rw-r--r--arch/arm64/configs/msm-perf_defconfig2
-rw-r--r--arch/arm64/configs/msm_defconfig2
-rw-r--r--arch/mips/Kconfig3
-rw-r--r--arch/mips/include/asm/netlogic/xlr/fmn.h2
-rw-r--r--arch/mips/include/asm/smp.h12
-rw-r--r--arch/mips/sibyte/common/Makefile1
-rw-r--r--arch/mips/sibyte/common/dma.c14
-rw-r--r--arch/mips/vdso/Makefile4
-rw-r--r--arch/s390/kvm/interrupt.c10
-rw-r--r--arch/s390/kvm/kvm-s390.c2
-rw-r--r--arch/s390/net/bpf_jit_comp.c12
-rw-r--r--arch/x86/Makefile1
-rw-r--r--arch/x86/boot/compressed/misc.c1
-rw-r--r--arch/x86/boot/compressed/misc.h1
-rw-r--r--arch/x86/include/asm/bootparam_utils.h1
-rw-r--r--arch/x86/kernel/apic/io_apic.c8
-rw-r--r--arch/x86/kvm/vmx.c7
-rw-r--r--arch/x86/kvm/x86.c7
-rw-r--r--drivers/atm/Kconfig2
-rw-r--r--drivers/base/core.c53
-rw-r--r--drivers/block/floppy.c4
-rw-r--r--drivers/char/diag/diag_masks.c3
-rw-r--r--drivers/clk/clk-s2mps11.c2
-rw-r--r--drivers/clk/rockchip/clk-mmc-phase.c4
-rw-r--r--drivers/crypto/talitos.c29
-rw-r--r--drivers/devfreq/governor_gpubw_mon.c11
-rw-r--r--drivers/dma/omap-dma.c4
-rw-r--r--drivers/gpu/msm/kgsl.c26
-rw-r--r--drivers/gpu/msm/kgsl_device.h3
-rw-r--r--drivers/isdn/capi/capi.c10
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c50
-rw-r--r--drivers/media/usb/dvb-usb/technisat-usb2.c21
-rw-r--r--drivers/media/usb/tm6000/tm6000-dvb.c3
-rw-r--r--drivers/misc/qseecom.c30
-rw-r--r--drivers/net/ethernet/marvell/sky2.c7
-rw-r--r--drivers/net/ethernet/seeq/sgiseeq.c7
-rw-r--r--drivers/net/tun.c16
-rw-r--r--drivers/net/usb/cdc_ether.c13
-rw-r--r--drivers/net/usb/r8152.c5
-rw-r--r--drivers/net/wireless/cnss2/Makefile1
-rw-r--r--drivers/net/wireless/cnss2/bus.c39
-rw-r--r--drivers/net/wireless/cnss2/bus.h3
-rw-r--r--drivers/net/wireless/cnss2/main.c72
-rw-r--r--drivers/net/wireless/cnss2/main.h4
-rw-r--r--drivers/net/wireless/cnss2/power.c52
-rw-r--r--drivers/net/wireless/cnss2/qmi.c3
-rw-r--r--drivers/net/wireless/cnss2/sdio.c410
-rw-r--r--drivers/net/wireless/cnss2/sdio.h86
-rw-r--r--drivers/net/wireless/mwifiex/ie.c3
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c9
-rw-r--r--drivers/net/xen-netfront.c2
-rw-r--r--drivers/pci/host/pci-msm.c12
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_flt.c8
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h1
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_rt.c11
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_utils.c18
-rw-r--r--drivers/soc/qcom/hab/ghs_comm.c13
-rw-r--r--drivers/soc/qcom/hab/hab_ghs.c3
-rw-r--r--drivers/tty/serial/atmel_serial.c1
-rw-r--r--drivers/tty/serial/sprd_serial.c2
-rw-r--r--drivers/usb/core/config.c12
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c39
-rw-r--r--drivers/usb/phy/phy-msm-qusb.c3
-rw-r--r--drivers/vhost/test.c13
-rw-r--r--drivers/vhost/vhost.c4
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c9
-rw-r--r--fs/btrfs/tree-log.c6
-rw-r--r--fs/cifs/connect.c22
-rw-r--r--fs/nfs/nfs4file.c12
-rw-r--r--fs/nfs/pagelist.c2
-rw-r--r--fs/nfs/proc.c7
-rw-r--r--fs/overlayfs/dir.c8
-rw-r--r--include/linux/diagchar.h4
-rw-r--r--include/net/cnss2.h56
-rw-r--r--include/net/xfrm.h17
-rw-r--r--include/uapi/linux/isdn/capicmd.h1
-rw-r--r--kernel/irq/resend.c2
-rw-r--r--net/bridge/br_mdb.c2
-rw-r--r--net/core/dev.c2
-rw-r--r--net/ipv4/tcp_input.c2
-rw-r--r--net/ipv6/ping.c2
-rw-r--r--net/key/af_key.c4
-rw-r--r--net/netfilter/nf_conntrack_ftp.c2
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/sched/sch_generic.c6
-rw-r--r--net/sched/sch_hhf.c2
-rw-r--r--net/sctp/protocol.c2
-rw-r--r--net/sctp/sm_sideeffect.c2
-rw-r--r--net/tipc/name_distr.c3
-rw-r--r--net/xfrm/xfrm_state.c2
-rw-r--r--net/xfrm/xfrm_user.c14
-rwxr-xr-xscripts/decode_stacktrace.sh2
-rw-r--r--security/keys/request_key_auth.c6
-rw-r--r--sound/pci/hda/hda_auto_parser.c4
-rw-r--r--sound/pci/hda/hda_generic.c3
-rw-r--r--sound/pci/hda/hda_generic.h1
-rw-r--r--sound/pci/hda/patch_realtek.c2
-rw-r--r--tools/power/x86/turbostat/turbostat.c2
-rw-r--r--virt/kvm/coalesced_mmio.c17
115 files changed, 1344 insertions, 262 deletions
diff --git a/Makefile b/Makefile
index 4f84720c2dd1..22542ea5e37f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 4
-SUBLEVEL = 192
+SUBLEVEL = 194
EXTRAVERSION =
NAME = Blurry Fish Butt
diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig
index 3023f91c77c2..9843e52bbb13 100644
--- a/arch/arc/configs/axs101_defconfig
+++ b/arch/arc/configs/axs101_defconfig
@@ -11,7 +11,6 @@ CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_VM_EVENT_COUNTERS is not set
diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig
index f18107185f53..27c6cb573686 100644
--- a/arch/arc/configs/axs103_defconfig
+++ b/arch/arc/configs/axs103_defconfig
@@ -11,7 +11,6 @@ CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_VM_EVENT_COUNTERS is not set
diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig
index 6e1dd8521d2a..72f34534983f 100644
--- a/arch/arc/configs/axs103_smp_defconfig
+++ b/arch/arc/configs/axs103_smp_defconfig
@@ -11,7 +11,6 @@ CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/"
CONFIG_EMBEDDED=y
CONFIG_PERF_EVENTS=y
# CONFIG_VM_EVENT_COUNTERS is not set
diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig
index 86e5a62556a8..c93370cc840a 100644
--- a/arch/arc/configs/nsim_700_defconfig
+++ b/arch/arc/configs/nsim_700_defconfig
@@ -11,7 +11,6 @@ CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
diff --git a/arch/arc/configs/nsim_hs_defconfig b/arch/arc/configs/nsim_hs_defconfig
index f68838e8068a..27c73028b798 100644
--- a/arch/arc/configs/nsim_hs_defconfig
+++ b/arch/arc/configs/nsim_hs_defconfig
@@ -12,7 +12,6 @@ CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
diff --git a/arch/arc/configs/nsim_hs_smp_defconfig b/arch/arc/configs/nsim_hs_smp_defconfig
index 96bd1c20fb0b..c3605874487b 100644
--- a/arch/arc/configs/nsim_hs_smp_defconfig
+++ b/arch/arc/configs/nsim_hs_smp_defconfig
@@ -9,7 +9,6 @@ CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig
index a4d7b919224a..b7dbb20cd28b 100644
--- a/arch/arc/configs/nsimosci_defconfig
+++ b/arch/arc/configs/nsimosci_defconfig
@@ -12,7 +12,6 @@ CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig
index b3fb49c8bd14..ce22594bb0c7 100644
--- a/arch/arc/configs/nsimosci_hs_defconfig
+++ b/arch/arc/configs/nsimosci_hs_defconfig
@@ -12,7 +12,6 @@ CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
# CONFIG_SLUB_DEBUG is not set
diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig
index 710c167bbdd8..f9e5aef7e04e 100644
--- a/arch/arc/configs/nsimosci_hs_smp_defconfig
+++ b/arch/arc/configs/nsimosci_hs_smp_defconfig
@@ -9,7 +9,6 @@ CONFIG_IKCONFIG_PROC=y
# CONFIG_UTS_NS is not set
# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../arc_initramfs_hs/"
# CONFIG_COMPAT_BRK is not set
CONFIG_KPROBES=y
CONFIG_MODULES=y
diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c
index 2fb0cd39a31c..cd6e3615e3d1 100644
--- a/arch/arc/kernel/traps.c
+++ b/arch/arc/kernel/traps.c
@@ -163,3 +163,4 @@ void abort(void)
{
__asm__ __volatile__("trap_s 5\n");
}
+EXPORT_SYMBOL(abort);
diff --git a/arch/arm/boot/dts/qcom/msm-arm-smmu-8996.dtsi b/arch/arm/boot/dts/qcom/msm-arm-smmu-8996.dtsi
index cbe65e266968..527765d34821 100644
--- a/arch/arm/boot/dts/qcom/msm-arm-smmu-8996.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-arm-smmu-8996.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 2019 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -251,16 +251,3 @@
"gcc_mmss_bimc_gfx_clk", "gcc_bimc_gfx_clk";
#clock-cells = <1>;
};
-
-&soc {
- iommu_test_device {
- compatible = "iommu-debug-test";
- /*
- * 42 shouldn't be used by anyone on the cpp_fd_smmu. We just
- * need _something_ here to get this node recognized by the
- * SMMU driver. Our test uses ATOS, which doesn't use SIDs
- * anyways, so using a dummy value is ok.
- */
- iommus = <&cpp_fd_smmu 42>;
- };
-};
diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi
index 5836185838d9..faba8108afaa 100644
--- a/arch/arm/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996.dtsi
@@ -2029,6 +2029,8 @@
interrupts = <0 131 0>;
usb-phy = <&qusb_phy0>, <&ssphy>;
tx-fifo-resize;
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
snps,usb3-u1u2-disable;
snps,nominal-elastic-buffer;
snps,is-utmi-l1-suspend;
@@ -2138,6 +2140,8 @@
interrupts = <0 138 0>;
usb-phy = <&qusb_phy1>, <&usb_nop_phy>;
maximum-speed = "high-speed";
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
snps,nominal-elastic-buffer;
snps,is-utmi-l1-suspend;
snps,hird-threshold = /bits/ 8 <0x0>;
diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto.dtsi b/arch/arm/boot/dts/qcom/msm8996pro-auto.dtsi
index b9ae88fa8865..9ed1b09bc26d 100644
--- a/arch/arm/boot/dts/qcom/msm8996pro-auto.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996pro-auto.dtsi
@@ -476,15 +476,135 @@
/* GPU overrides for auto */
&msm_gpu {
+ /delete-node/ qcom,gpu-pwrlevel-bins;
+
qcom,gpu-pwrlevel-bins {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible="qcom,gpu-pwrlevel-bins";
+
qcom,gpu-pwrlevels-0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <0>;
+
qcom,initial-pwrlevel = <1>;
+
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <624000000>;
+ qcom,bus-freq = <12>;
+ qcom,bus-min = <11>;
+ qcom,bus-max = <12>;
+ };
+
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <560000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <12>;
+ };
+
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <510000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <11>;
+ };
+
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <401800000>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <7>;
+ qcom,bus-max = <9>;
+ };
+
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <315000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <7>;
+ };
+
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <0>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
};
- qcom,gpu-pwrlevels-2 {
+ qcom,gpu-pwrlevels-1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <1>;
+
qcom,initial-pwrlevel = <2>;
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <510000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <11>;
+ };
+
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <401800000>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <7>;
+ qcom,bus-max = <9>;
+ };
+
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <315000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <7>;
+ };
+
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <0>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
};
+ qcom,gpu-pwrlevels-2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,speed-bin = <2>;
+
+ qcom,initial-pwrlevel = <0>;
+
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <315000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <5>;
+ qcom,bus-max = <7>;
+ };
+
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <0>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
};
};
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 949696b6f17b..511fd08c784b 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -131,6 +131,9 @@ static int __init omap4_sram_init(void)
struct device_node *np;
struct gen_pool *sram_pool;
+ if (!soc_is_omap44xx() && !soc_is_omap54xx())
+ return 0;
+
np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
if (!np)
pr_warn("%s:Unable to allocate sram needed to handle errata I688\n",
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index d05984a85c64..a3759740ce18 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -790,7 +790,8 @@ static void update_sections_early(struct section_perm perms[], int n)
if (t->flags & PF_KTHREAD)
continue;
for_each_thread(t, s)
- set_section_perms(perms, n, true, s->mm);
+ if (s->mm)
+ set_section_perms(perms, n, true, s->mm);
}
read_unlock(&tasklist_lock);
set_section_perms(perms, n, true, current->active_mm);
diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig
index fbaff4d0b6c6..95fb47583db4 100644
--- a/arch/arm64/configs/msm-perf_defconfig
+++ b/arch/arm64/configs/msm-perf_defconfig
@@ -49,6 +49,8 @@ CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8996=y
CONFIG_PCI=y
CONFIG_PCI_MSM=y
+CONFIG_ENABLE_FP_SIMD_SETTINGS=y
+CONFIG_MSM_APP_SETTINGS=y
CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8
CONFIG_PREEMPT=y
diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig
index ccff9670af63..3661419528c2 100644
--- a/arch/arm64/configs/msm_defconfig
+++ b/arch/arm64/configs/msm_defconfig
@@ -46,6 +46,8 @@ CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8996=y
CONFIG_PCI=y
CONFIG_PCI_MSM=y
+CONFIG_ENABLE_FP_SIMD_SETTINGS=y
+CONFIG_MSM_APP_SETTINGS=y
CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8
CONFIG_PREEMPT=y
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index f561e36917d1..c6ae78b81e54 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -814,7 +814,6 @@ config SIBYTE_SWARM
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_LITTLE_ENDIAN
select ZONE_DMA32 if 64BIT
- select SWIOTLB if ARCH_DMA_ADDR_T_64BIT && PCI
config SIBYTE_LITTLESUR
bool "Sibyte BCM91250C2-LittleSur"
@@ -837,7 +836,6 @@ config SIBYTE_SENTOSA
select SYS_HAS_CPU_SB1
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
- select SWIOTLB if ARCH_DMA_ADDR_T_64BIT && PCI
config SIBYTE_BIGSUR
bool "Sibyte BCM91480B-BigSur"
@@ -851,7 +849,6 @@ config SIBYTE_BIGSUR
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_LITTLE_ENDIAN
select ZONE_DMA32 if 64BIT
- select SWIOTLB if ARCH_DMA_ADDR_T_64BIT && PCI
config SNI_RM
bool "SNI RM200/300/400"
diff --git a/arch/mips/include/asm/netlogic/xlr/fmn.h b/arch/mips/include/asm/netlogic/xlr/fmn.h
index 5604db3d1836..d79c68fa78d9 100644
--- a/arch/mips/include/asm/netlogic/xlr/fmn.h
+++ b/arch/mips/include/asm/netlogic/xlr/fmn.h
@@ -301,8 +301,6 @@ static inline int nlm_fmn_send(unsigned int size, unsigned int code,
for (i = 0; i < 8; i++) {
nlm_msgsnd(dest);
status = nlm_read_c2_status0();
- if ((status & 0x2) == 1)
- pr_info("Send pending fail!\n");
if ((status & 0x4) == 0)
return 0;
}
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
index 03722d4326a1..82852dfd8dab 100644
--- a/arch/mips/include/asm/smp.h
+++ b/arch/mips/include/asm/smp.h
@@ -25,7 +25,17 @@ extern cpumask_t cpu_sibling_map[];
extern cpumask_t cpu_core_map[];
extern cpumask_t cpu_foreign_map;
-#define raw_smp_processor_id() (current_thread_info()->cpu)
+static inline int raw_smp_processor_id(void)
+{
+#if defined(__VDSO__)
+ extern int vdso_smp_processor_id(void)
+ __compiletime_error("VDSO should not call smp_processor_id()");
+ return vdso_smp_processor_id();
+#else
+ return current_thread_info()->cpu;
+#endif
+}
+#define raw_smp_processor_id raw_smp_processor_id
/* Map from cpu id to sequential logical cpu number. This will only
not be idempotent when cpus failed to come on-line. */
diff --git a/arch/mips/sibyte/common/Makefile b/arch/mips/sibyte/common/Makefile
index 3ef3fb658136..b3d6bf23a662 100644
--- a/arch/mips/sibyte/common/Makefile
+++ b/arch/mips/sibyte/common/Makefile
@@ -1,5 +1,4 @@
obj-y := cfe.o
-obj-$(CONFIG_SWIOTLB) += dma.o
obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o
obj-$(CONFIG_SIBYTE_CFE_CONSOLE) += cfe_console.o
obj-$(CONFIG_SIBYTE_TBPROF) += sb_tbprof.o
diff --git a/arch/mips/sibyte/common/dma.c b/arch/mips/sibyte/common/dma.c
deleted file mode 100644
index eb47a94f3583..000000000000
--- a/arch/mips/sibyte/common/dma.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * DMA support for Broadcom SiByte platforms.
- *
- * Copyright (c) 2018 Maciej W. Rozycki
- */
-
-#include <linux/swiotlb.h>
-#include <asm/bootinfo.h>
-
-void __init plat_swiotlb_setup(void)
-{
- swiotlb_init(1);
-}
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index 886005b1e87d..dfd082eb86f8 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -6,7 +6,9 @@ ccflags-vdso := \
$(filter -I%,$(KBUILD_CFLAGS)) \
$(filter -E%,$(KBUILD_CFLAGS)) \
$(filter -mmicromips,$(KBUILD_CFLAGS)) \
- $(filter -march=%,$(KBUILD_CFLAGS))
+ $(filter -march=%,$(KBUILD_CFLAGS)) \
+ $(filter -m%-float,$(KBUILD_CFLAGS)) \
+ -D__VDSO__
cflags-vdso := $(ccflags-vdso) \
$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
-O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 6a75352f453c..950b0c00a092 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -1487,6 +1487,16 @@ int s390int_to_s390irq(struct kvm_s390_interrupt *s390int,
case KVM_S390_MCHK:
irq->u.mchk.mcic = s390int->parm64;
break;
+ case KVM_S390_INT_PFAULT_INIT:
+ irq->u.ext.ext_params = s390int->parm;
+ irq->u.ext.ext_params2 = s390int->parm64;
+ break;
+ case KVM_S390_RESTART:
+ case KVM_S390_INT_CLOCK_COMP:
+ case KVM_S390_INT_CPU_TIMER:
+ break;
+ default:
+ return -EINVAL;
}
return 0;
}
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 23911ecfbad6..14d2ca9c779e 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -2541,7 +2541,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
}
case KVM_S390_INTERRUPT: {
struct kvm_s390_interrupt s390int;
- struct kvm_s390_irq s390irq;
+ struct kvm_s390_irq s390irq = {};
r = -EFAULT;
if (copy_from_user(&s390int, argp, sizeof(s390int)))
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index 727693e283da..bcf409997d6d 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -886,7 +886,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
break;
case BPF_ALU64 | BPF_NEG: /* dst = -dst */
/* lcgr %dst,%dst */
- EMIT4(0xb9130000, dst_reg, dst_reg);
+ EMIT4(0xb9030000, dst_reg, dst_reg);
break;
/*
* BPF_FROM_BE/LE
@@ -1067,8 +1067,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
/* llgf %w1,map.max_entries(%b2) */
EMIT6_DISP_LH(0xe3000000, 0x0016, REG_W1, REG_0, BPF_REG_2,
offsetof(struct bpf_array, map.max_entries));
- /* clgrj %b3,%w1,0xa,label0: if %b3 >= %w1 goto out */
- EMIT6_PCREL_LABEL(0xec000000, 0x0065, BPF_REG_3,
+ /* clrj %b3,%w1,0xa,label0: if (u32)%b3 >= (u32)%w1 goto out */
+ EMIT6_PCREL_LABEL(0xec000000, 0x0077, BPF_REG_3,
REG_W1, 0, 0xa);
/*
@@ -1094,8 +1094,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
* goto out;
*/
- /* sllg %r1,%b3,3: %r1 = index * 8 */
- EMIT6_DISP_LH(0xeb000000, 0x000d, REG_1, BPF_REG_3, REG_0, 3);
+ /* llgfr %r1,%b3: %r1 = (u32) index */
+ EMIT4(0xb9160000, REG_1, BPF_REG_3);
+ /* sllg %r1,%r1,3: %r1 *= 8 */
+ EMIT6_DISP_LH(0xeb000000, 0x000d, REG_1, REG_1, REG_0, 3);
/* lg %r1,prog(%b2,%r1) */
EMIT6_DISP_LH(0xe3000000, 0x0004, REG_1, BPF_REG_2,
REG_1, offsetof(struct bpf_array, ptrs));
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 063de6441f8d..0a3081d64855 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -38,6 +38,7 @@ REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -D__KERNEL__ \
REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding)
REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector)
+REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member)
REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4))
export REALMODE_CFLAGS
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 16df89c30c20..1e5b68228aff 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -11,6 +11,7 @@
#include "misc.h"
#include "../string.h"
+#include <asm/bootparam_utils.h>
/* WARNING!!
* This code is compiled with -fPIC and it is relocated dynamically
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index 4abb284a5b9c..bce182708814 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -19,7 +19,6 @@
#include <asm/page.h>
#include <asm/boot.h>
#include <asm/bootparam.h>
-#include <asm/bootparam_utils.h>
#define BOOT_BOOT_H
#include "../ctype.h"
diff --git a/arch/x86/include/asm/bootparam_utils.h b/arch/x86/include/asm/bootparam_utils.h
index 0232b5a2a2d9..588d8fbd1e6d 100644
--- a/arch/x86/include/asm/bootparam_utils.h
+++ b/arch/x86/include/asm/bootparam_utils.h
@@ -71,6 +71,7 @@ static void sanitize_boot_params(struct boot_params *boot_params)
BOOT_PARAM_PRESERVE(edd_mbr_sig_buf_entries),
BOOT_PARAM_PRESERVE(edd_mbr_sig_buffer),
BOOT_PARAM_PRESERVE(hdr),
+ BOOT_PARAM_PRESERVE(e820_map),
BOOT_PARAM_PRESERVE(eddbuf),
};
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index fd945099fc95..4d5e8ff3b5e5 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2344,7 +2344,13 @@ unsigned int arch_dynirq_lower_bound(unsigned int from)
* dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use
* gsi_top if ioapic_dynirq_base hasn't been initialized yet.
*/
- return ioapic_initialized ? ioapic_dynirq_base : gsi_top;
+ if (!ioapic_initialized)
+ return gsi_top;
+ /*
+ * For DT enabled machines ioapic_dynirq_base is irrelevant and not
+ * updated. So simply return @from if ioapic_dynirq_base == 0.
+ */
+ return ioapic_dynirq_base ? : from;
}
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 098be61a6b4c..343c8ddad86a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -7247,6 +7247,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
gva_t gva = 0;
+ struct x86_exception e;
if (!nested_vmx_check_permission(vcpu) ||
!nested_vmx_check_vmcs12(vcpu))
@@ -7273,8 +7274,10 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
vmx_instruction_info, true, &gva))
return 1;
/* _system ok, as nested_vmx_check_permission verified cpl=0 */
- kvm_write_guest_virt_system(vcpu, gva, &field_value,
- (is_long_mode(vcpu) ? 8 : 4), NULL);
+ if (kvm_write_guest_virt_system(vcpu, gva, &field_value,
+ (is_long_mode(vcpu) ? 8 : 4),
+ NULL))
+ kvm_inject_page_fault(vcpu, &e);
}
nested_vmx_succeed(vcpu);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9f70de2ca0e2..74674a6e4827 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4337,6 +4337,13 @@ static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *v
if (!system && kvm_x86_ops->get_cpl(vcpu) == 3)
access |= PFERR_USER_MASK;
+ /*
+ * FIXME: this should call handle_emulation_failure if X86EMUL_IO_NEEDED
+ * is returned, but our callers are not ready for that and they blindly
+ * call kvm_inject_page_fault. Ensure that they at least do not leak
+ * uninitialized kernel stack memory into cr2 and error code.
+ */
+ memset(exception, 0, sizeof(*exception));
return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
access, exception);
}
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index 31c60101a69a..7fa840170151 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -199,7 +199,7 @@ config ATM_NICSTAR_USE_SUNI
make the card work).
config ATM_NICSTAR_USE_IDT77105
- bool "Use IDT77015 PHY driver (25Mbps)"
+ bool "Use IDT77105 PHY driver (25Mbps)"
depends on ATM_NICSTAR
help
Support for the PHYsical layer chip in ForeRunner LE25 cards. In
diff --git a/drivers/base/core.c b/drivers/base/core.c
index cef0f5c1bf85..4e27b3abf5a5 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -862,12 +862,63 @@ static inline struct kobject *get_glue_dir(struct device *dev)
*/
static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
{
+ unsigned int ref;
+
/* see if we live in a "glue" directory */
if (!live_in_glue_dir(glue_dir, dev))
return;
mutex_lock(&gdp_mutex);
- if (!kobject_has_children(glue_dir))
+ /**
+ * There is a race condition between removing glue directory
+ * and adding a new device under the glue directory.
+ *
+ * CPU1: CPU2:
+ *
+ * device_add()
+ * get_device_parent()
+ * class_dir_create_and_add()
+ * kobject_add_internal()
+ * create_dir() // create glue_dir
+ *
+ * device_add()
+ * get_device_parent()
+ * kobject_get() // get glue_dir
+ *
+ * device_del()
+ * cleanup_glue_dir()
+ * kobject_del(glue_dir)
+ *
+ * kobject_add()
+ * kobject_add_internal()
+ * create_dir() // in glue_dir
+ * sysfs_create_dir_ns()
+ * kernfs_create_dir_ns(sd)
+ *
+ * sysfs_remove_dir() // glue_dir->sd=NULL
+ * sysfs_put() // free glue_dir->sd
+ *
+ * // sd is freed
+ * kernfs_new_node(sd)
+ * kernfs_get(glue_dir)
+ * kernfs_add_one()
+ * kernfs_put()
+ *
+ * Before CPU1 remove last child device under glue dir, if CPU2 add
+ * a new device under glue dir, the glue_dir kobject reference count
+ * will be increase to 2 in kobject_get(k). And CPU2 has been called
+ * kernfs_create_dir_ns(). Meanwhile, CPU1 call sysfs_remove_dir()
+ * and sysfs_put(). This result in glue_dir->sd is freed.
+ *
+ * Then the CPU2 will see a stale "empty" but still potentially used
+ * glue dir around in kernfs_new_node().
+ *
+ * In order to avoid this happening, we also should make sure that
+ * kernfs_node for glue_dir is released in CPU1 only when refcount
+ * for glue_dir kobj is 1.
+ */
+ ref = atomic_read(&glue_dir->kref.refcount);
+ if (!kobject_has_children(glue_dir) && !--ref)
kobject_del(glue_dir);
kobject_put(glue_dir);
mutex_unlock(&gdp_mutex);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index a04810837234..a12a163c6e6d 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3784,7 +3784,7 @@ static int compat_getdrvprm(int drive,
v.native_format = UDP->native_format;
mutex_unlock(&floppy_mutex);
- if (copy_from_user(arg, &v, sizeof(struct compat_floppy_drive_params)))
+ if (copy_to_user(arg, &v, sizeof(struct compat_floppy_drive_params)))
return -EFAULT;
return 0;
}
@@ -3820,7 +3820,7 @@ static int compat_getdrvstat(int drive, bool poll,
v.bufblocks = UDRS->bufblocks;
mutex_unlock(&floppy_mutex);
- if (copy_from_user(arg, &v, sizeof(struct compat_floppy_drive_struct)))
+ if (copy_to_user(arg, &v, sizeof(struct compat_floppy_drive_struct)))
return -EFAULT;
return 0;
Eintr:
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index ec3013c5fd85..775a66db30f7 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -901,7 +901,8 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
goto end;
if (mask_size + write_len > dest_len)
mask_size = dest_len - write_len;
- memcpy(dest_buf + write_len, src_buf + header_len, mask_size);
+ if (mask_size && src_len >= header_len + mask_size)
+ memcpy(dest_buf + write_len, src_buf + header_len, mask_size);
write_len += mask_size;
for (i = 0; i < NUM_PERIPHERALS; i++) {
if (!diag_check_update(i, pid))
diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c
index 785864893f9a..14af5c916c9c 100644
--- a/drivers/clk/clk-s2mps11.c
+++ b/drivers/clk/clk-s2mps11.c
@@ -307,7 +307,7 @@ MODULE_DEVICE_TABLE(platform, s2mps11_clk_id);
* This requires of_device_id table. In the same time this will not change the
* actual *device* matching so do not add .of_match_table.
*/
-static const struct of_device_id s2mps11_dt_match[] = {
+static const struct of_device_id s2mps11_dt_match[] __used = {
{
.compatible = "samsung,s2mps11-clk",
.data = (void *)S2MPS11X,
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index b840e4ace623..2b289581d570 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -61,10 +61,8 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw)
u32 delay_num = 0;
/* See the comment for rockchip_mmc_set_phase below */
- if (!rate) {
- pr_err("%s: invalid clk rate\n", __func__);
+ if (!rate)
return -EINVAL;
- }
raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index a000c2667392..014745271bb4 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1426,6 +1426,18 @@ static void unmap_sg_talitos_ptr(struct device *dev, struct scatterlist *src,
}
}
+static int ablkcipher_aes_setkey(struct crypto_ablkcipher *cipher,
+ const u8 *key, unsigned int keylen)
+{
+ if (keylen == AES_KEYSIZE_128 || keylen == AES_KEYSIZE_192 ||
+ keylen == AES_KEYSIZE_256)
+ return ablkcipher_setkey(cipher, key, keylen);
+
+ crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
+
+ return -EINVAL;
+}
+
static void common_nonsnoop_unmap(struct device *dev,
struct talitos_edesc *edesc,
struct ablkcipher_request *areq)
@@ -1629,6 +1641,14 @@ static int ablkcipher_encrypt(struct ablkcipher_request *areq)
struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
struct talitos_edesc *edesc;
+ unsigned int blocksize =
+ crypto_tfm_alg_blocksize(crypto_ablkcipher_tfm(cipher));
+
+ if (!areq->nbytes)
+ return 0;
+
+ if (areq->nbytes % blocksize)
+ return -EINVAL;
/* allocate extended descriptor */
edesc = ablkcipher_edesc_alloc(areq, true);
@@ -1646,6 +1666,14 @@ static int ablkcipher_decrypt(struct ablkcipher_request *areq)
struct crypto_ablkcipher *cipher = crypto_ablkcipher_reqtfm(areq);
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
struct talitos_edesc *edesc;
+ unsigned int blocksize =
+ crypto_tfm_alg_blocksize(crypto_ablkcipher_tfm(cipher));
+
+ if (!areq->nbytes)
+ return 0;
+
+ if (areq->nbytes % blocksize)
+ return -EINVAL;
/* allocate extended descriptor */
edesc = ablkcipher_edesc_alloc(areq, false);
@@ -2379,6 +2407,7 @@ static struct talitos_alg_template driver_algs[] = {
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
+ .setkey = ablkcipher_aes_setkey,
}
},
.desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
diff --git a/drivers/devfreq/governor_gpubw_mon.c b/drivers/devfreq/governor_gpubw_mon.c
index 8234d30dc644..e121657800ca 100644
--- a/drivers/devfreq/governor_gpubw_mon.c
+++ b/drivers/devfreq/governor_gpubw_mon.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016,2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -213,10 +213,11 @@ static int devfreq_gpubw_event_handler(struct devfreq *devfreq,
case DEVFREQ_GOV_SUSPEND:
{
struct devfreq_msm_adreno_tz_data *priv = devfreq->data;
-
- priv->bus.total_time = 0;
- priv->bus.gpu_time = 0;
- priv->bus.ram_time = 0;
+ if (priv) {
+ priv->bus.total_time = 0;
+ priv->bus.gpu_time = 0;
+ priv->bus.ram_time = 0;
+ }
}
break;
default:
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 1dfc71c90123..57b6e6ca14a8 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -1199,8 +1199,10 @@ static int omap_dma_probe(struct platform_device *pdev)
rc = devm_request_irq(&pdev->dev, irq, omap_dma_irq,
IRQF_SHARED, "omap-dma-engine", od);
- if (rc)
+ if (rc) {
+ omap_dma_free(od);
return rc;
+ }
}
rc = dma_async_device_register(&od->ddev);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 417d8c61109e..90d9bd2339eb 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -3342,11 +3342,15 @@ long kgsl_ioctl_sparse_phys_alloc(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data)
{
struct kgsl_process_private *process = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_phys_alloc *param = data;
struct kgsl_mem_entry *entry;
int ret;
int id;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
ret = _sparse_alloc_param_sanity_check(param->size, param->pagesize);
if (ret)
return ret;
@@ -3425,9 +3429,13 @@ long kgsl_ioctl_sparse_phys_free(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data)
{
struct kgsl_process_private *process = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_phys_free *param = data;
struct kgsl_mem_entry *entry;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
entry = kgsl_sharedmem_find_id_flags(process, param->id,
KGSL_MEMFLAGS_SPARSE_PHYS);
if (entry == NULL)
@@ -3457,10 +3465,14 @@ long kgsl_ioctl_sparse_virt_alloc(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data)
{
struct kgsl_process_private *private = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_virt_alloc *param = data;
struct kgsl_mem_entry *entry;
int ret;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
ret = _sparse_alloc_param_sanity_check(param->size, param->pagesize);
if (ret)
return ret;
@@ -3500,9 +3512,13 @@ long kgsl_ioctl_sparse_virt_free(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data)
{
struct kgsl_process_private *process = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_virt_free *param = data;
struct kgsl_mem_entry *entry = NULL;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
entry = kgsl_sharedmem_find_id_flags(process, param->id,
KGSL_MEMFLAGS_SPARSE_VIRT);
if (entry == NULL)
@@ -3849,6 +3865,7 @@ long kgsl_ioctl_sparse_bind(struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data)
{
struct kgsl_process_private *private = dev_priv->process_priv;
+ struct kgsl_device *device = dev_priv->device;
struct kgsl_sparse_bind *param = data;
struct kgsl_sparse_binding_object obj;
struct kgsl_mem_entry *virt_entry;
@@ -3857,6 +3874,9 @@ long kgsl_ioctl_sparse_bind(struct kgsl_device_private *dev_priv,
int ret = 0;
int i = 0;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
ptr = (void __user *) (uintptr_t) param->list;
if (param->size > sizeof(struct kgsl_sparse_binding_object) ||
@@ -3912,6 +3932,9 @@ long kgsl_ioctl_gpu_sparse_command(struct kgsl_device_private *dev_priv,
long result;
unsigned int i = 0;
+ if (!(device->flags & KGSL_FLAG_SPARSE))
+ return -ENOTSUPP;
+
/* Make sure sparse and syncpoint count isn't too big */
if (param->numsparse > KGSL_MAX_SPARSE ||
param->numsyncs > KGSL_MAX_SYNCPOINTS)
@@ -4720,6 +4743,9 @@ int kgsl_device_platform_probe(struct kgsl_device *device)
/* Initialize logging first, so that failures below actually print. */
kgsl_device_debugfs_init(device);
+ /* Disable the sparse ioctl invocation as they are not used */
+ device->flags &= ~KGSL_FLAG_SPARSE;
+
status = kgsl_pwrctrl_init(device);
if (status)
goto error;
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 549e23cfc273..0ab6041b3bbd 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -61,6 +61,7 @@ enum kgsl_event_results {
};
#define KGSL_FLAG_WAKE_ON_TOUCH BIT(0)
+#define KGSL_FLAG_SPARSE BIT(1)
/*
* "list" of event types for ftrace symbolic magic
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 6a2df3297e77..691ad069444d 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -687,6 +687,9 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
if (!cdev->ap.applid)
return -ENODEV;
+ if (count < CAPIMSG_BASELEN)
+ return -EINVAL;
+
skb = alloc_skb(count, GFP_USER);
if (!skb)
return -ENOMEM;
@@ -697,7 +700,8 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
}
mlen = CAPIMSG_LEN(skb->data);
if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
- if ((size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
+ if (count < CAPI_DATA_B3_REQ_LEN ||
+ (size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
kfree_skb(skb);
return -EINVAL;
}
@@ -710,6 +714,10 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
+ if (count < CAPI_DISCONNECT_B3_RESP_LEN) {
+ kfree_skb(skb);
+ return -EINVAL;
+ }
mutex_lock(&cdev->lock);
capincci_free(cdev, CAPIMSG_NCCI(skb->data));
mutex_unlock(&cdev->lock);
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 83abaea1fa44..d75af08846cd 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1498,8 +1498,6 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
uint32_t i;
int rc = -1;
- int counter = 0;
- u32 result = 0;
struct cpp_device *cpp_dev = NULL;
struct msm_device_queue *processing_q = NULL;
struct msm_device_queue *eventData_q = NULL;
@@ -1581,54 +1579,6 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
pr_debug("DEBUG_R1: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x8C));
- /* mask IRQ status */
- msm_camera_io_w(0xB, cpp_dev->cpp_hw_base + 0xC);
-
- /* clear IRQ status */
- msm_camera_io_w(0xFFFFF, cpp_dev->cpp_hw_base + 0x14);
-
- /* MMSS_A_CPP_AXI_CMD = 0x16C, reset 0x1*/
- msm_camera_io_w(0x1, cpp_dev->cpp_hw_base + 0x16C);
-
- while (counter < MSM_CPP_POLL_RETRIES) {
- result = msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10);
- if (result & 0x2)
- break;
- /*
- * Below usleep values are chosen based on experiments
- * and this was the smallest number which works. This
- * sleep is needed to leave enough time for hardware
- * to update status register.
- */
- usleep_range(200, 250);
- counter++;
- }
-
- pr_debug("CPP AXI done counter %d result 0x%x\n",
- counter, result);
-
- /* clear IRQ status */
- msm_camera_io_w(0xFFFFF, cpp_dev->cpp_hw_base + 0x14);
- counter = 0;
- /* MMSS_A_CPP_RST_CMD_0 = 0x8, firmware reset = 0x3DF77 */
- msm_camera_io_w(0x3DF77, cpp_dev->cpp_hw_base + 0x8);
-
- while (counter < MSM_CPP_POLL_RETRIES) {
- result = msm_camera_io_r(cpp_dev->cpp_hw_base + 0x10);
- if (result & 0x1)
- break;
- /*
- * Below usleep values are chosen based on experiments
- * and this was the smallest number which works. This
- * sleep is needed to leave enough time for hardware
- * to update status register.
- */
- usleep_range(200, 250);
- counter++;
- }
- pr_debug("CPP reset done counter %d result 0x%x\n",
- counter, result);
-
msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
msm_cpp_clear_timer(cpp_dev);
cpp_release_hardware(cpp_dev);
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
index 6c3c47722955..30a8c21ed736 100644
--- a/drivers/media/usb/dvb-usb/technisat-usb2.c
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -594,9 +594,9 @@ static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
static int technisat_usb2_get_ir(struct dvb_usb_device *d)
{
- u8 buf[62], *b;
- int ret;
+ u8 buf[62];
struct ir_raw_event ev;
+ int i, ret;
buf[0] = GET_IR_DATA_VENDOR_REQUEST;
buf[1] = 0x08;
@@ -632,26 +632,25 @@ unlock:
return 0; /* no key pressed */
/* decoding */
- b = buf+1;
#if 0
deb_rc("RC: %d ", ret);
- debug_dump(b, ret, deb_rc);
+ debug_dump(buf + 1, ret, deb_rc);
#endif
ev.pulse = 0;
- while (1) {
- ev.pulse = !ev.pulse;
- ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
- ir_raw_event_store(d->rc_dev, &ev);
-
- b++;
- if (*b == 0xff) {
+ for (i = 1; i < ARRAY_SIZE(buf); i++) {
+ if (buf[i] == 0xff) {
ev.pulse = 0;
ev.duration = 888888*2;
ir_raw_event_store(d->rc_dev, &ev);
break;
}
+
+ ev.pulse = !ev.pulse;
+ ev.duration = (buf[i] * FIRMWARE_CLOCK_DIVISOR *
+ FIRMWARE_CLOCK_TICK) / 1000;
+ ir_raw_event_store(d->rc_dev, &ev);
}
ir_raw_event_handle(d->rc_dev);
diff --git a/drivers/media/usb/tm6000/tm6000-dvb.c b/drivers/media/usb/tm6000/tm6000-dvb.c
index 4f317e2686e9..87401b18d85a 100644
--- a/drivers/media/usb/tm6000/tm6000-dvb.c
+++ b/drivers/media/usb/tm6000/tm6000-dvb.c
@@ -111,6 +111,7 @@ static void tm6000_urb_received(struct urb *urb)
printk(KERN_ERR "tm6000: error %s\n", __func__);
kfree(urb->transfer_buffer);
usb_free_urb(urb);
+ dev->dvb->bulk_urb = NULL;
}
}
}
@@ -143,6 +144,7 @@ static int tm6000_start_stream(struct tm6000_core *dev)
dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
if (dvb->bulk_urb->transfer_buffer == NULL) {
usb_free_urb(dvb->bulk_urb);
+ dvb->bulk_urb = NULL;
printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
return -ENOMEM;
}
@@ -170,6 +172,7 @@ static int tm6000_start_stream(struct tm6000_core *dev)
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
+ dvb->bulk_urb = NULL;
return ret;
}
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index f4aed78cac92..dfa3bb6b186f 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -3265,6 +3265,33 @@ int __boundary_checks_offset(struct qseecom_send_modfd_cmd_req *req,
return 0;
}
+static int __boundary_checks_offset_64(struct qseecom_send_modfd_cmd_req *req,
+ struct qseecom_send_modfd_listener_resp *lstnr_resp,
+ struct qseecom_dev_handle *data, int i)
+{
+
+ if ((data->type != QSEECOM_LISTENER_SERVICE) &&
+ (req->ifd_data[i].fd > 0)) {
+ if ((req->cmd_req_len < sizeof(uint64_t)) ||
+ (req->ifd_data[i].cmd_buf_offset >
+ req->cmd_req_len - sizeof(uint64_t))) {
+ pr_err("Invalid offset (req len) 0x%x\n",
+ req->ifd_data[i].cmd_buf_offset);
+ return -EINVAL;
+ }
+ } else if ((data->type == QSEECOM_LISTENER_SERVICE) &&
+ (lstnr_resp->ifd_data[i].fd > 0)) {
+ if ((lstnr_resp->resp_len < sizeof(uint64_t)) ||
+ (lstnr_resp->ifd_data[i].cmd_buf_offset >
+ lstnr_resp->resp_len - sizeof(uint64_t))) {
+ pr_err("Invalid offset (lstnr resp len) 0x%x\n",
+ lstnr_resp->ifd_data[i].cmd_buf_offset);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
struct qseecom_dev_handle *data)
{
@@ -3622,7 +3649,8 @@ static int __qseecom_update_cmd_buf_64(void *msg, bool cleanup,
sg = sg_ptr->sgl;
if (sg_ptr->nents == 1) {
uint64_t *update_64bit;
- if (__boundary_checks_offset(req, lstnr_resp, data, i))
+ if (__boundary_checks_offset_64(req, lstnr_resp,
+ data, i))
goto err;
/* 64bit app uses 64bit address */
update_64bit = (uint64_t *) field;
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index dcd72b2a3715..8ba9eadc2079 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4946,6 +4946,13 @@ static const struct dmi_system_id msi_blacklist[] = {
DMI_MATCH(DMI_BOARD_NAME, "P6T"),
},
},
+ {
+ .ident = "ASUS P6X",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "P6X"),
+ },
+ },
{}
};
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c
index ca7336605748..2e5f7bbd30bf 100644
--- a/drivers/net/ethernet/seeq/sgiseeq.c
+++ b/drivers/net/ethernet/seeq/sgiseeq.c
@@ -792,15 +792,16 @@ static int sgiseeq_probe(struct platform_device *pdev)
printk(KERN_ERR "Sgiseeq: Cannot register net device, "
"aborting.\n");
err = -ENODEV;
- goto err_out_free_page;
+ goto err_out_free_attrs;
}
printk(KERN_INFO "%s: %s %pM\n", dev->name, sgiseeqstr, dev->dev_addr);
return 0;
-err_out_free_page:
- free_page((unsigned long) sp->srings);
+err_out_free_attrs:
+ dma_free_attrs(&pdev->dev, sizeof(*sp->srings), sp->srings,
+ sp->srings_dma, DMA_ATTR_NON_CONSISTENT);
err_out_free_dev:
free_netdev(dev);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index d235d186df5e..93c7024fcc67 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -597,7 +597,8 @@ static void tun_detach_all(struct net_device *dev)
module_put(THIS_MODULE);
}
-static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filter)
+static int tun_attach(struct tun_struct *tun, struct file *file,
+ bool skip_filter, bool publish_tun)
{
struct tun_file *tfile = file->private_data;
int err;
@@ -630,7 +631,8 @@ static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filte
}
tfile->queue_index = tun->numqueues;
tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN;
- rcu_assign_pointer(tfile->tun, tun);
+ if (publish_tun)
+ rcu_assign_pointer(tfile->tun, tun);
rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
tun->numqueues++;
@@ -1642,7 +1644,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
if (err < 0)
return err;
- err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER);
+ err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER, true);
if (err < 0)
return err;
@@ -1723,13 +1725,17 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
NETIF_F_HW_VLAN_STAG_TX);
INIT_LIST_HEAD(&tun->disabled);
- err = tun_attach(tun, file, false);
+ err = tun_attach(tun, file, false, false);
if (err < 0)
goto err_free_flow;
err = register_netdevice(tun->dev);
if (err < 0)
goto err_detach;
+ /* free_netdev() won't check refcnt, to aovid race
+ * with dev_put() we need publish tun after registration.
+ */
+ rcu_assign_pointer(tfile->tun, tun);
}
netif_carrier_on(tun->dev);
@@ -1868,7 +1874,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
ret = security_tun_dev_attach_queue(tun->security);
if (ret < 0)
goto unlock;
- ret = tun_attach(tun, file, false);
+ ret = tun_attach(tun, file, false, true);
} else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
tun = rtnl_dereference(tfile->tun);
if (!tun || !(tun->flags & IFF_MULTI_QUEUE) || tfile->detached)
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index f71abe50ea6f..3707aab2423b 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -212,9 +212,16 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
goto bad_desc;
}
skip:
- if ( rndis &&
- header.usb_cdc_acm_descriptor &&
- header.usb_cdc_acm_descriptor->bmCapabilities) {
+ /* Communcation class functions with bmCapabilities are not
+ * RNDIS. But some Wireless class RNDIS functions use
+ * bmCapabilities for their own purpose. The failsafe is
+ * therefore applied only to Communication class RNDIS
+ * functions. The rndis test is redundant, but a cheap
+ * optimization.
+ */
+ if (rndis && is_rndis(&intf->cur_altsetting->desc) &&
+ header.usb_cdc_acm_descriptor &&
+ header.usb_cdc_acm_descriptor->bmCapabilities) {
dev_dbg(&intf->dev,
"ACM capabilities %02x, not really RNDIS?\n",
header.usb_cdc_acm_descriptor->bmCapabilities);
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 2d83689374bb..10dd307593e8 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -671,8 +671,11 @@ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0),
RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
value, index, tmp, size, 500);
+ if (ret < 0)
+ memset(data, 0xff, size);
+ else
+ memcpy(data, tmp, size);
- memcpy(data, tmp, size);
kfree(tmp);
return ret;
diff --git a/drivers/net/wireless/cnss2/Makefile b/drivers/net/wireless/cnss2/Makefile
index a4b177e7a981..b1c8c5e6461e 100644
--- a/drivers/net/wireless/cnss2/Makefile
+++ b/drivers/net/wireless/cnss2/Makefile
@@ -5,6 +5,7 @@ cnss2-y += bus.o
cnss2-y += debug.o
cnss2-y += pci.o
cnss2-y += usb.o
+cnss2-$(CONFIG_SDIO_QCN) += sdio.o
cnss2-y += power.o
cnss2-y += qmi.o
cnss2-y += wlan_firmware_service_v01.o
diff --git a/drivers/net/wireless/cnss2/bus.c b/drivers/net/wireless/cnss2/bus.c
index 088593f9ae1c..e33eb647d9bb 100644
--- a/drivers/net/wireless/cnss2/bus.c
+++ b/drivers/net/wireless/cnss2/bus.c
@@ -14,6 +14,7 @@
#include "debug.h"
#include "pci.h"
#include "usb.h"
+#include "sdio.h"
enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
{
@@ -27,6 +28,8 @@ enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
return CNSS_BUS_PCI;
else if (memcmp(dev->bus->name, "usb", 3) == 0)
return CNSS_BUS_USB;
+ else if (memcmp(dev->bus->name, "sdio", 4) == 0)
+ return CNSS_BUS_SDIO;
else
return CNSS_BUS_NONE;
}
@@ -44,20 +47,14 @@ enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id)
case QCN7605_VER20_STANDALONE_DEVICE_ID:
case QCN7605_VER20_COMPOSITE_DEVICE_ID:
return CNSS_BUS_USB;
+ case QCN7605_SDIO_DEVICE_ID:
+ return CNSS_BUS_SDIO;
default:
cnss_pr_err("Unknown device_id: 0x%lx\n", device_id);
return CNSS_BUS_NONE;
}
}
-bool cnss_bus_req_mem_ind_valid(struct cnss_plat_data *plat_priv)
-{
- if (cnss_get_bus_type(plat_priv->device_id) == CNSS_BUS_USB)
- return false;
- else
- return true;
-}
-
void *cnss_bus_dev_to_bus_priv(struct device *dev)
{
if (!dev)
@@ -89,6 +86,8 @@ struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev)
return cnss_pci_priv_to_plat_priv(bus_priv);
case CNSS_BUS_USB:
return cnss_usb_priv_to_plat_priv(bus_priv);
+ case CNSS_BUS_SDIO:
+ return cnss_get_plat_priv(NULL);
default:
return NULL;
}
@@ -104,6 +103,8 @@ int cnss_bus_init(struct cnss_plat_data *plat_priv)
return cnss_pci_init(plat_priv);
case CNSS_BUS_USB:
return cnss_usb_init(plat_priv);
+ case CNSS_BUS_SDIO:
+ return cnss_sdio_init(plat_priv);
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
@@ -119,13 +120,18 @@ void cnss_bus_deinit(struct cnss_plat_data *plat_priv)
switch (plat_priv->bus_type) {
case CNSS_BUS_PCI:
cnss_pci_deinit(plat_priv);
+ break;
case CNSS_BUS_USB:
cnss_usb_deinit(plat_priv);
+ break;
+ case CNSS_BUS_SDIO:
+ cnss_sdio_deinit(plat_priv);
+ break;
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
- return;
}
+ return;
}
int cnss_bus_load_m3(struct cnss_plat_data *plat_priv)
@@ -200,6 +206,8 @@ void cnss_bus_fw_boot_timeout_hdlr(unsigned long data)
return cnss_pci_fw_boot_timeout_hdlr(plat_priv->bus_priv);
case CNSS_BUS_USB:
return cnss_usb_fw_boot_timeout_hdlr(plat_priv->bus_priv);
+ case CNSS_BUS_SDIO:
+ return cnss_sdio_fw_boot_timeout_hdlr(plat_priv->bus_priv);
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
@@ -240,6 +248,8 @@ int cnss_bus_call_driver_probe(struct cnss_plat_data *plat_priv)
return cnss_pci_call_driver_probe(plat_priv->bus_priv);
case CNSS_BUS_USB:
return cnss_usb_call_driver_probe(plat_priv->bus_priv);
+ case CNSS_BUS_SDIO:
+ return cnss_sdio_call_driver_probe(plat_priv->bus_priv);
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
@@ -257,6 +267,8 @@ int cnss_bus_call_driver_remove(struct cnss_plat_data *plat_priv)
return cnss_pci_call_driver_remove(plat_priv->bus_priv);
case CNSS_BUS_USB:
return cnss_usb_call_driver_remove(plat_priv->bus_priv);
+ case CNSS_BUS_SDIO:
+ return cnss_sdio_call_driver_remove(plat_priv->bus_priv);
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
@@ -274,6 +286,8 @@ int cnss_bus_dev_powerup(struct cnss_plat_data *plat_priv)
return cnss_pci_dev_powerup(plat_priv->bus_priv);
case CNSS_BUS_USB:
return cnss_usb_dev_powerup(plat_priv);
+ case CNSS_BUS_SDIO:
+ return cnss_sdio_dev_powerup(plat_priv->bus_priv);
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
@@ -291,6 +305,8 @@ int cnss_bus_dev_shutdown(struct cnss_plat_data *plat_priv)
return cnss_pci_dev_shutdown(plat_priv->bus_priv);
case CNSS_BUS_USB:
return 0;
+ case CNSS_BUS_SDIO:
+ return cnss_sdio_dev_shutdown(plat_priv->bus_priv);
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
@@ -338,6 +354,9 @@ int cnss_bus_register_driver_hdlr(struct cnss_plat_data *plat_priv, void *data)
return cnss_pci_register_driver_hdlr(plat_priv->bus_priv, data);
case CNSS_BUS_USB:
return cnss_usb_register_driver_hdlr(plat_priv->bus_priv, data);
+ case CNSS_BUS_SDIO:
+ return cnss_sdio_register_driver_hdlr(plat_priv->bus_priv,
+ data);
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
@@ -355,6 +374,8 @@ int cnss_bus_unregister_driver_hdlr(struct cnss_plat_data *plat_priv)
return cnss_pci_unregister_driver_hdlr(plat_priv->bus_priv);
case CNSS_BUS_USB:
return cnss_usb_unregister_driver_hdlr(plat_priv->bus_priv);
+ case CNSS_BUS_SDIO:
+ return cnss_sdio_unregister_driver_hdlr(plat_priv->bus_priv);
default:
cnss_pr_err("Unsupported bus type: %d\n",
plat_priv->bus_type);
diff --git a/drivers/net/wireless/cnss2/bus.h b/drivers/net/wireless/cnss2/bus.h
index 1100fd66482a..30a93a06549f 100644
--- a/drivers/net/wireless/cnss2/bus.h
+++ b/drivers/net/wireless/cnss2/bus.h
@@ -26,6 +26,8 @@
#define QCA6290_EMULATION_DEVICE_ID 0xABCD
#define QCN7605_VENDOR_ID 0x17CB
#define QCN7605_DEVICE_ID 0x1102
+#define QCN7605_SDIO_VENDOR_ID 0x70
+#define QCN7605_SDIO_DEVICE_ID 0x400B
#define QCN7605_USB_VENDOR_ID 0x05C6
#define QCN7605_COMPOSITE_DEVICE_ID QCN7605_COMPOSITE_PRODUCT_ID
@@ -62,5 +64,4 @@ int cnss_bus_unregister_driver_hdlr(struct cnss_plat_data *plat_priv);
int cnss_bus_call_driver_modem_status(struct cnss_plat_data *plat_priv,
int modem_current_status);
int cnss_bus_recovery_update_status(struct cnss_plat_data *plat_priv);
-bool cnss_bus_req_mem_ind_valid(struct cnss_plat_data *plat_priv);
#endif /* _CNSS_BUS_H */
diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c
index 498650e08d2a..4507f57f5bd8 100644
--- a/drivers/net/wireless/cnss2/main.c
+++ b/drivers/net/wireless/cnss2/main.c
@@ -61,6 +61,40 @@ module_param(quirks, ulong, 0600);
MODULE_PARM_DESC(quirks, "Debug quirks for the driver");
#endif
+static unsigned int wow_wake_gpionum;
+#ifdef CONFIG_CNSS2_DEBUG
+module_param(wow_wake_gpionum, uint, 0600);
+MODULE_PARM_DESC(wow_wake_gpionum, "configure gpio number for wow wake");
+#endif
+
+static unsigned int wow_wake_enable;
+int cnss_enable_wow_wake(const char *val, const struct kernel_param *kp)
+{
+ int ret;
+ unsigned int prev_val;
+
+ prev_val = *(unsigned int *)kp->arg;
+ ret = param_set_uint(val, kp);
+ if (ret || prev_val == wow_wake_enable) {
+ cnss_pr_err("failed set new wow_enable ret = %d", ret);
+ return ret;
+ }
+ if (wow_wake_enable) {
+ if (!wow_wake_gpionum)
+ wow_wake_gpionum = HOST_WAKE_GPIO_IN;
+ cnss_set_wlan_chip_to_host_wakeup(wow_wake_gpionum);
+ }
+ return 0;
+}
+
+static const struct kernel_param_ops cnss_param_ops_uint = {
+ .set = &cnss_enable_wow_wake,
+ .get = &param_get_uint
+};
+
+module_param_cb(wow_wake_enable, &cnss_param_ops_uint,
+ &wow_wake_enable, 0600);
+
static struct cnss_fw_files FW_FILES_QCA6174_FW_3_0 = {
"qwlan30.bin", "bdwlan30.bin", "otp30.bin", "utf30.bin",
"utfbd30.bin", "epping30.bin", "evicted30.bin"
@@ -248,7 +282,7 @@ int cnss_wlan_enable(struct device *dev,
enum cnss_driver_mode mode,
const char *host_version)
{
- struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
+ struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
struct wlfw_wlan_cfg_req_msg_v01 req;
u32 i, ce_id, num_vectors, user_base_data, base_vector;
int ret = 0;
@@ -259,7 +293,8 @@ int cnss_wlan_enable(struct device *dev,
if (qmi_bypass)
return 0;
- if (cnss_get_bus_type(plat_priv->device_id) == CNSS_BUS_USB)
+ if (plat_priv->bus_type == CNSS_BUS_USB ||
+ plat_priv->bus_type == CNSS_BUS_SDIO)
goto skip_cfg;
if (!config || !host_version) {
@@ -364,7 +399,7 @@ EXPORT_SYMBOL(cnss_wlan_enable);
int cnss_wlan_disable(struct device *dev, enum cnss_driver_mode mode)
{
- struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
+ struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
if (plat_priv->device_id == QCA6174_DEVICE_ID)
return 0;
@@ -1254,7 +1289,8 @@ static int cnss_wlfw_server_arrive_hdlr(struct cnss_plat_data *plat_priv)
if (ret)
goto out;
- if (!cnss_bus_req_mem_ind_valid(plat_priv)) {
+ if (plat_priv->bus_type == CNSS_BUS_USB ||
+ plat_priv->bus_type == CNSS_BUS_SDIO) {
ret = cnss_wlfw_tgt_cap_send_sync(plat_priv);
if (ret)
goto out;
@@ -1274,7 +1310,7 @@ static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
if (test_bit(CNSS_DEV_REMOVED, &plat_priv->driver_state))
pwr_up_reqd = true;
- if (pwr_up_reqd || plat_priv->bus_type != CNSS_BUS_USB)
+ if (pwr_up_reqd || plat_priv->bus_type == CNSS_BUS_PCI)
ret = cnss_bus_dev_powerup(plat_priv);
if (ret)
@@ -1433,6 +1469,7 @@ int cnss_register_subsys(struct cnss_plat_data *plat_priv)
case QCN7605_COMPOSITE_DEVICE_ID:
case QCN7605_VER20_STANDALONE_DEVICE_ID:
case QCN7605_VER20_COMPOSITE_DEVICE_ID:
+ case QCN7605_SDIO_DEVICE_ID:
subsys_info->subsys_desc.name = "QCN7605";
break;
default:
@@ -1769,6 +1806,18 @@ static ssize_t cnss_fs_ready_store(struct device *dev,
return count;
}
+#ifdef CONFIG_SDIO_QCN
+static void cnss_set_card_state(bool state)
+{
+ qcn_sdio_card_state(state);
+}
+#else
+static void cnss_set_card_state(bool state)
+{
+ /* no op */
+}
+#endif
+
static DEVICE_ATTR(fs_ready, 0220, NULL, cnss_fs_ready_store);
static ssize_t cnss_wl_pwr_on(struct device *dev,
@@ -1789,12 +1838,14 @@ static ssize_t cnss_wl_pwr_on(struct device *dev,
timeout = cnss_get_qmi_timeout();
if (pwr_state) {
cnss_power_on_device(plat_priv);
+ cnss_set_card_state(true);
if (timeout) {
mod_timer(&plat_priv->fw_boot_timer,
jiffies + msecs_to_jiffies(timeout));
}
} else {
cnss_power_off_device(plat_priv);
+ cnss_set_card_state(false);
del_timer(&plat_priv->fw_boot_timer);
}
return count;
@@ -1887,6 +1938,7 @@ static const struct platform_device_id cnss_platform_id_table[] = {
{ .name = "qca6174", .driver_data = QCA6174_DEVICE_ID, },
{ .name = "qca6290", .driver_data = QCA6290_DEVICE_ID, },
{ .name = "qcn7605", .driver_data = QCN7605_DEVICE_ID, },
+ { .name = "qcn7605_sdio", .driver_data = QCN7605_SDIO_DEVICE_ID, },
};
static const struct of_device_id cnss_of_match_table[] = {
@@ -1896,6 +1948,12 @@ static const struct of_device_id cnss_of_match_table[] = {
{
.compatible = "qcom,cnss-qca6290",
.data = (void *)&cnss_platform_id_table[1]},
+ {
+ .compatible = "qcom,cnss",
+ .data = (void *)&cnss_platform_id_table[2]},
+ {
+ .compatible = "qcom,cnss-sdio",
+ .data = (void *)&cnss_platform_id_table[3]},
{ },
};
MODULE_DEVICE_TABLE(of, cnss_of_match_table);
@@ -1946,7 +2004,9 @@ static int cnss_probe(struct platform_device *plat_dev)
goto free_res;
ret = cnss_bus_init(plat_priv);
- if (ret)
+ if (ret == -EPROBE_DEFER)
+ goto free_res;
+ else if (ret)
goto power_off;
}
diff --git a/drivers/net/wireless/cnss2/main.h b/drivers/net/wireless/cnss2/main.h
index 1b7c67b90795..969ff00b85ae 100644
--- a/drivers/net/wireless/cnss2/main.h
+++ b/drivers/net/wireless/cnss2/main.h
@@ -31,11 +31,13 @@
#define CNSS_EVENT_SYNC_UNINTERRUPTIBLE (CNSS_EVENT_SYNC | \
CNSS_EVENT_UNINTERRUPTIBLE)
#define QCN7605_CALDB_SIZE 614400
+#define HOST_WAKE_GPIO_IN 144
enum cnss_dev_bus_type {
CNSS_BUS_NONE = -1,
CNSS_BUS_PCI,
CNSS_BUS_USB,
+ CNSS_BUS_SDIO,
};
struct cnss_vreg_info {
@@ -259,4 +261,6 @@ void cnss_set_pin_connect_status(struct cnss_plat_data *plat_priv);
u32 cnss_get_wake_msi(struct cnss_plat_data *plat_priv);
bool *cnss_get_qmi_bypass(void);
bool is_qcn7605_device(u16 device_id);
+void cnss_set_wlan_chip_to_host_wakeup(unsigned int wakeup_gpio_num);
+int cnss_enable_wow_wake(const char *val, const struct kernel_param *kp);
#endif /* _CNSS_MAIN_H */
diff --git a/drivers/net/wireless/cnss2/power.c b/drivers/net/wireless/cnss2/power.c
index 8a58a5357765..ed145d7049be 100644
--- a/drivers/net/wireless/cnss2/power.c
+++ b/drivers/net/wireless/cnss2/power.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,7 @@
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
#include "main.h"
#include "debug.h"
@@ -388,3 +389,52 @@ void cnss_set_pin_connect_status(struct cnss_plat_data *plat_priv)
plat_priv->pin_result.host_pin_result = pin_status;
}
+
+static irqreturn_t wlan_wakeup_interrupt(int irq, void *dev_id)
+{
+ return IRQ_HANDLED;
+}
+
+void cnss_set_wlan_chip_to_host_wakeup(unsigned int wakeup_gpio_num)
+{
+ int ret = 0;
+ int wakeup_irq_num;
+
+ ret = gpio_request(wakeup_gpio_num, "qcom_wlan_wakeup");
+ if (ret)
+ cnss_pr_err("wakeup gpio request failed\n");
+
+ ret = gpio_direction_input(wakeup_gpio_num);
+ if (ret) {
+ cnss_pr_err("wake gpio set dir output failed\n");
+ goto free_gpio;
+ }
+
+ wakeup_irq_num = gpio_to_irq(wakeup_gpio_num);
+ if (wakeup_irq_num < 0) {
+ cnss_pr_err("wake gpio_to_irq err %d\n", wakeup_irq_num);
+ goto free_gpio;
+ }
+ ret = request_irq(wakeup_irq_num, wlan_wakeup_interrupt,
+ IRQF_TRIGGER_FALLING, "qcom_wlan_wakeup_irq", NULL);
+ if (ret) {
+ cnss_pr_err("request_irq err %d\n", ret);
+ goto free_gpio;
+ }
+
+ ret = enable_irq_wake(wakeup_irq_num);
+ if (!ret) {
+ cnss_pr_err("enable irq wakeup success %d\n", ret);
+ } else {
+ cnss_pr_err("enable irq wakeup FAILURE %d\n", ret);
+ goto irq_free;
+ }
+ ret = gpio_get_value(wakeup_gpio_num);
+ cnss_pr_err("gpio get val ret = %d wakeup_gpio_num %d\n", ret,
+ wakeup_gpio_num);
+ return;
+irq_free:
+ free_irq(wakeup_irq_num, NULL);
+free_gpio:
+ gpio_free(wakeup_gpio_num);
+}
diff --git a/drivers/net/wireless/cnss2/qmi.c b/drivers/net/wireless/cnss2/qmi.c
index 7945f59439f7..489a28e478bd 100644
--- a/drivers/net/wireless/cnss2/qmi.c
+++ b/drivers/net/wireless/cnss2/qmi.c
@@ -797,7 +797,8 @@ int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv)
plat_priv->device_id == QCN7605_COMPOSITE_DEVICE_ID ||
plat_priv->device_id == QCN7605_STANDALONE_DEVICE_ID ||
plat_priv->device_id == QCN7605_VER20_STANDALONE_DEVICE_ID ||
- plat_priv->device_id == QCN7605_VER20_COMPOSITE_DEVICE_ID)
+ plat_priv->device_id == QCN7605_VER20_COMPOSITE_DEVICE_ID ||
+ plat_priv->device_id == QCN7605_SDIO_DEVICE_ID)
bdf_type = CNSS_BDF_BIN;
if (plat_priv->board_info.board_id == 0xFF) {
diff --git a/drivers/net/wireless/cnss2/sdio.c b/drivers/net/wireless/cnss2/sdio.c
new file mode 100644
index 000000000000..f25a2b0aaaa8
--- /dev/null
+++ b/drivers/net/wireless/cnss2/sdio.c
@@ -0,0 +1,410 @@
+/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <soc/qcom/subsystem_restart.h>
+#include <soc/qcom/subsystem_notif.h>
+#include <net/cnss2.h>
+#include <linux/qcn_sdio_al.h>
+#include "main.h"
+#include "sdio.h"
+#include "debug.h"
+#include "bus.h"
+
+int cnss_sdio_call_driver_probe(struct cnss_sdio_data *sdio_priv)
+{
+ int ret = 0;
+ struct cnss_plat_data *plat_priv = sdio_priv->plat_priv;
+
+ if ((!sdio_priv->al_client_handle) ||
+ (!sdio_priv->al_client_handle->func)) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!sdio_priv->ops) {
+ cnss_pr_err("driver_ops is NULL\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) &&
+ test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
+ ret = sdio_priv->ops->reinit(sdio_priv->al_client_handle->func,
+ sdio_priv->device_id);
+ if (ret) {
+ cnss_pr_err("Failed to reinit host driver, err = %d\n",
+ ret);
+ goto out;
+ }
+ clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
+ } else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)) {
+ ret = sdio_priv->ops->probe(sdio_priv->al_client_handle->func,
+ sdio_priv->device_id);
+ if (ret) {
+ cnss_pr_err("Failed to probe host driver, err = %d\n",
+ ret);
+ goto out;
+ }
+ clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
+ clear_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
+ set_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state);
+ }
+
+ return 0;
+
+out:
+ return ret;
+}
+
+int cnss_sdio_call_driver_remove(struct cnss_sdio_data *sdio_priv)
+{
+ struct cnss_plat_data *plat_priv = sdio_priv->plat_priv;
+
+ if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state) ||
+ test_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state) ||
+ test_bit(CNSS_DRIVER_DEBUG, &plat_priv->driver_state)) {
+ cnss_pr_dbg("Skip driver remove\n");
+ return 0;
+ }
+
+ if (!sdio_priv->ops) {
+ cnss_pr_err("driver_ops is NULL\n");
+ return -EINVAL;
+ }
+
+ if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) &&
+ test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
+ cnss_pr_dbg("Recovery set after driver probed.Call shutdown\n");
+ sdio_priv->ops->shutdown(sdio_priv->al_client_handle->func);
+ } else if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
+ cnss_pr_dbg("driver_ops->remove\n");
+ sdio_priv->ops->remove(sdio_priv->al_client_handle->func);
+ clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state);
+ }
+ return 0;
+}
+
+/**
+ * cnss_sdio_wlan_register_driver() - cnss wlan register API
+ * @driver: sdio wlan driver interface from wlan driver.
+ *
+ * wlan sdio function driver uses this API to register callback
+ * functions to cnss_sido platform driver. The callback will
+ * be invoked by corresponding wrapper function of this cnss
+ * platform driver.
+ */
+int cnss_sdio_wlan_register_driver(struct cnss_sdio_wlan_driver *driver_ops)
+{
+ struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
+ struct cnss_sdio_data *cnss_info;
+ int ret = 0;
+
+ if (!plat_priv) {
+ cnss_pr_err("plat_priv is NULL\n");
+ return -ENODEV;
+ }
+
+ cnss_info = plat_priv->bus_priv;
+ if ((!cnss_info) ||
+ (!cnss_info->al_client_handle) ||
+ (!cnss_info->al_client_handle->func)) {
+ cnss_pr_err("cnss_info is NULL\n");
+ return -ENODEV;
+ }
+
+ if (cnss_info->ops) {
+ cnss_pr_err("Driver has already registered\n");
+ return -EEXIST;
+ }
+ cnss_info->ops = driver_ops;
+
+ ret = cnss_driver_event_post(plat_priv,
+ CNSS_DRIVER_EVENT_REGISTER_DRIVER,
+ CNSS_EVENT_SYNC_UNINTERRUPTIBLE,
+ driver_ops);
+ return ret;
+}
+EXPORT_SYMBOL(cnss_sdio_wlan_register_driver);
+
+/**
+ * cnss_sdio_wlan_unregister_driver() - cnss wlan unregister API
+ * @driver: sdio wlan driver interface from wlan driver.
+ *
+ * wlan sdio function driver uses this API to detach it from cnss_sido
+ * platform driver.
+ */
+void cnss_sdio_wlan_unregister_driver(struct cnss_sdio_wlan_driver *driver_ops)
+{
+ struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
+
+ if (!plat_priv) {
+ cnss_pr_err("plat_priv is NULL\n");
+ return;
+ }
+
+ cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_UNREGISTER_DRIVER,
+ CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
+}
+EXPORT_SYMBOL(cnss_sdio_wlan_unregister_driver);
+
+struct sdio_al_client_handle *cnss_sdio_wlan_get_sdio_al_client_handle(
+ struct sdio_func *func)
+{
+ struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
+ struct cnss_sdio_data *cnss_info = plat_priv->bus_priv;
+
+ return cnss_info->al_client_handle;
+}
+EXPORT_SYMBOL(cnss_sdio_wlan_get_sdio_al_client_handle);
+
+struct sdio_al_channel_handle *cnss_sdio_wlan_register_sdio_al_channel(
+ struct sdio_al_channel_data *channel_data)
+{
+ struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
+ struct cnss_sdio_data *cnss_info = plat_priv->bus_priv;
+
+ return sdio_al_register_channel(cnss_info->al_client_handle,
+ channel_data);
+}
+EXPORT_SYMBOL(cnss_sdio_wlan_register_sdio_al_channel);
+
+void cnss_sdio_wlan_unregister_sdio_al_channel(
+ struct sdio_al_channel_handle *ch_handle)
+{
+ sdio_al_deregister_channel(ch_handle);
+}
+EXPORT_SYMBOL(cnss_sdio_wlan_unregister_sdio_al_channel);
+
+int cnss_sdio_register_driver_hdlr(struct cnss_sdio_data *cnss_info,
+ void *data)
+{
+ struct cnss_plat_data *plat_priv = cnss_info->plat_priv;
+ int ret = 0;
+ unsigned int timeout;
+
+ set_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
+ if (test_bit(CNSS_FW_READY, &plat_priv->driver_state)) {
+ cnss_pr_info("CNSS SDIO driver register in FW_Ready state");
+ cnss_sdio_call_driver_probe(cnss_info);
+ } else if ((*cnss_get_qmi_bypass()) &&
+ (cnss_info->al_client_handle->func)) {
+ cnss_pr_info("qmi bypass enabled");
+ cnss_sdio_call_driver_probe(cnss_info);
+ } else {
+ cnss_pr_info("Wait for FW_Ready");
+ ret = cnss_power_on_device(plat_priv);
+ if (ret) {
+ cnss_pr_err("Failed to power on device, err = %d\n",
+ ret);
+ return ret;
+ }
+
+ qcn_sdio_card_state(true);
+ timeout = cnss_get_qmi_timeout();
+ if (timeout) {
+ mod_timer(&plat_priv->fw_boot_timer,
+ jiffies + msecs_to_jiffies(timeout << 1));
+ }
+ }
+ return 0;
+}
+
+int cnss_sdio_unregister_driver_hdlr(struct cnss_sdio_data *cnss_info)
+{
+ struct cnss_plat_data *plat_priv = cnss_info->plat_priv;
+
+ set_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
+ cnss_sdio_call_driver_remove(cnss_info);
+ cnss_request_bus_bandwidth(&plat_priv->plat_dev->dev,
+ CNSS_BUS_WIDTH_NONE);
+ qcn_sdio_card_state(false);
+ cnss_power_off_device(plat_priv);
+ clear_bit(CNSS_FW_READY, &plat_priv->driver_state);
+ clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
+
+ cnss_info->ops = NULL;
+ return 0;
+}
+
+int cnss_sdio_dev_powerup(struct cnss_sdio_data *cnss_info)
+{
+ struct cnss_plat_data *plat_priv = cnss_info->plat_priv;
+ int ret = 0;
+ unsigned int timeout;
+
+ switch (plat_priv->device_id) {
+ case QCN7605_SDIO_DEVICE_ID:
+ ret = cnss_power_on_device(plat_priv);
+ if (ret) {
+ cnss_pr_err("Failed to power on device, err = %d\n",
+ ret);
+ goto out;
+ }
+
+ qcn_sdio_card_state(true);
+ timeout = cnss_get_qmi_timeout();
+ mod_timer(&plat_priv->fw_boot_timer,
+ jiffies + msecs_to_jiffies(timeout >> 1));
+ cnss_set_pin_connect_status(plat_priv);
+ break;
+ default:
+ cnss_pr_err("Unknown device_id found: 0x%lx\n",
+ plat_priv->device_id);
+ ret = -ENODEV;
+ }
+out:
+ return ret;
+}
+
+int cnss_sdio_dev_shutdown(struct cnss_sdio_data *cnss_info)
+{
+ struct cnss_plat_data *plat_priv = cnss_info->plat_priv;
+
+ cnss_sdio_call_driver_remove(cnss_info);
+ cnss_request_bus_bandwidth(&plat_priv->plat_dev->dev,
+ CNSS_BUS_WIDTH_NONE);
+ /*qcn_sdio_card_state(false);*/
+ cnss_power_off_device(plat_priv);
+ clear_bit(CNSS_FW_READY, &plat_priv->driver_state);
+ clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state);
+
+ return 0;
+}
+
+void cnss_sdio_fw_boot_timeout_hdlr(void *bus_priv)
+{
+ cnss_pr_err("Timeout waiting for FW ready indication\n");
+}
+
+static int cnss_sdio_probe(struct sdio_al_client_handle *pal_cli_handle)
+{
+ struct cnss_sdio_data *sdio_info = pal_cli_handle->client_priv;
+ struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL);
+ struct sdio_device_id *device_id;
+
+ device_id = devm_kzalloc(&plat_priv->plat_dev->dev,
+ sizeof(struct sdio_device_id),
+ GFP_KERNEL);
+ device_id->class = pal_cli_handle->func->class;
+ device_id->vendor = pal_cli_handle->func->vendor;
+ device_id->device = pal_cli_handle->func->device;
+ sdio_info->device_id = device_id;
+
+ if (pal_cli_handle->func)
+ cnss_pr_info("CNSS SDIO AL Probe for device Id: 0x%x\n",
+ pal_cli_handle->func->device);
+ clear_bit(CNSS_DEV_REMOVED, &plat_priv->driver_state);
+ plat_priv->device_id = pal_cli_handle->func->device;
+ cnss_register_subsys(sdio_info->plat_priv);
+ return 0;
+}
+
+static int cnss_sdio_remove(struct sdio_al_client_handle *pal_cli_handle)
+{
+ struct cnss_sdio_data *sdio_info = pal_cli_handle->client_priv;
+ struct cnss_plat_data *plat_priv = sdio_info->plat_priv;
+
+ if (pal_cli_handle->func)
+ cnss_pr_err(
+ "SDIO AL remove for device Id: 0x%x in driver state %lu\n",
+ pal_cli_handle->func->device,
+ plat_priv->driver_state);
+
+ clear_bit(CNSS_FW_READY, &plat_priv->driver_state);
+ set_bit(CNSS_DEV_REMOVED, &plat_priv->driver_state);
+ if (sdio_info->ops &&
+ test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) {
+ cnss_pr_err("Triggering driver_ops remove\n");
+ sdio_info->ops->update_status(
+ sdio_info->al_client_handle->func,
+ CNSS_FW_DOWN);
+ sdio_info->ops->remove(sdio_info->al_client_handle->func);
+ clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state);
+ }
+
+ cnss_unregister_subsys(plat_priv);
+ devm_kfree(&plat_priv->plat_dev->dev, (void *)sdio_info->device_id);
+
+ return 0;
+}
+
+static void cnss_sdio_pm(struct sdio_al_client_handle *pal_cli_handle,
+ enum sdio_al_lpm_event event)
+{
+ struct cnss_sdio_data *sdio_info = pal_cli_handle->client_priv;
+ struct sdio_func *func = sdio_info->al_client_handle->func;
+
+ if (!sdio_info->ops) {
+ cnss_pr_err("Ignore LPM event\n");
+ return;
+ }
+
+ if (event == LPM_ENTER) {
+ cnss_pr_info("Entering LPM\n");
+ sdio_info->ops->suspend(&func->dev);
+ } else {
+ cnss_pr_info("Exiting LPM\n");
+ sdio_info->ops->resume(&func->dev);
+ }
+}
+
+struct sdio_al_client_data al_cli_data = {
+ .name = "SDIO_AL_CLIENT_WLAN",
+ .probe = cnss_sdio_probe,
+ .remove = cnss_sdio_remove,
+ .lpm_notify_cb = cnss_sdio_pm,
+};
+
+int cnss_sdio_init(struct cnss_plat_data *plat_priv)
+{
+ struct cnss_sdio_data *sdio_info;
+ struct sdio_al_client_handle *al_client_handle;
+ int ret = 0;
+
+ if (sdio_al_is_ready()) {
+ cnss_pr_err("sdio_al not ready, defer probe\n");
+ ret = -EPROBE_DEFER;
+ goto out;
+ }
+
+ al_client_handle = sdio_al_register_client(&al_cli_data);
+ if (!al_client_handle) {
+ cnss_pr_err("sdio al registration failed!\n");
+ ret = -ENODEV;
+ goto out;
+ }
+ sdio_info = devm_kzalloc(&plat_priv->plat_dev->dev, sizeof(*sdio_info),
+ GFP_KERNEL);
+ if (!sdio_info) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ al_client_handle->client_priv = sdio_info;
+ sdio_info->al_client_handle = al_client_handle;
+ sdio_info->plat_priv = plat_priv;
+ plat_priv->bus_priv = sdio_info;
+
+out:
+ return ret;
+}
+
+int cnss_sdio_deinit(struct cnss_plat_data *plat_priv)
+{
+ struct cnss_sdio_data *sdio_info = plat_priv->bus_priv;
+
+ sdio_al_deregister_client(sdio_info->al_client_handle);
+ return 0;
+}
diff --git a/drivers/net/wireless/cnss2/sdio.h b/drivers/net/wireless/cnss2/sdio.h
new file mode 100644
index 000000000000..1f782fa61f79
--- /dev/null
+++ b/drivers/net/wireless/cnss2/sdio.h
@@ -0,0 +1,86 @@
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CNSS_SDIO_H
+#define _CNSS_SDIO_H
+
+#include "main.h"
+#ifdef CONFIG_SDIO_QCN
+#include <linux/qcn_sdio_al.h>
+
+struct cnss_sdio_data {
+ struct cnss_plat_data *plat_priv;
+ struct sdio_al_client_handle *al_client_handle;
+ struct cnss_sdio_wlan_driver *ops;
+ struct sdio_device_id *device_id;
+ void *client_priv;
+};
+
+int cnss_sdio_init(struct cnss_plat_data *plat_priv);
+int cnss_sdio_deinit(struct cnss_plat_data *plat_priv);
+int cnss_sdio_register_driver_hdlr(struct cnss_sdio_data *sdio_info,
+ void *data);
+int cnss_sdio_unregister_driver_hdlr(struct cnss_sdio_data *sdio_info);
+int cnss_sdio_dev_powerup(struct cnss_sdio_data *cnss_info);
+int cnss_sdio_dev_shutdown(struct cnss_sdio_data *cnss_info);
+int cnss_sdio_call_driver_probe(struct cnss_sdio_data *sdio_priv);
+int cnss_sdio_call_driver_remove(struct cnss_sdio_data *sdio_priv);
+void cnss_sdio_fw_boot_timeout_hdlr(void *bus_priv);
+#else
+inline int cnss_sdio_init(void *plat_priv)
+{
+ return -EINVAL;
+}
+
+inline int cnss_sdio_deinit(void *plat_priv)
+{
+ return -EINVAL;
+}
+
+inline int cnss_sdio_register_driver_hdlr(void *sdio_info,
+ void *data)
+{
+ return -EINVAL;
+}
+
+inline int cnss_sdio_unregister_driver_hdlr(void *sdio_info)
+{
+ return -EINVAL;
+}
+
+inline int cnss_sdio_dev_powerup(void *cnss_info)
+{
+ return -EINVAL;
+}
+
+inline int cnss_sdio_dev_shutdown(void *cnss_info)
+{
+ return -EINVAL;
+}
+
+inline int cnss_sdio_call_driver_probe(void *sdio_priv)
+{
+ return -EINVAL;
+}
+
+inline int cnss_sdio_call_driver_remove(void *sdio_priv)
+{
+ return -EINVAL;
+}
+
+inline void cnss_sdio_fw_boot_timeout_hdlr(void *bus_priv)
+{
+ /* no op */
+}
+#endif
+
+#endif
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index de8435709735..4255fb8dd58a 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -240,6 +240,9 @@ static int mwifiex_update_vs_ie(const u8 *ies, int ies_len,
}
vs_ie = (struct ieee_types_header *)vendor_ie;
+ if (le16_to_cpu(ie->ie_length) + vs_ie->len + 2 >
+ IEEE_MAX_IE_SIZE)
+ return -EINVAL;
memcpy(ie->ie_buffer + le16_to_cpu(ie->ie_length),
vs_ie, vs_ie->len + 2);
le16_add_cpu(&ie->ie_length, vs_ie->len + 2);
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 759a6ada5b0f..60bba1ca24e6 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -286,6 +286,8 @@ mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
rate_ie = (void *)cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len);
if (rate_ie) {
+ if (rate_ie->len > MWIFIEX_SUPPORTED_RATES)
+ return;
memcpy(bss_cfg->rates, rate_ie + 1, rate_ie->len);
rate_len = rate_ie->len;
}
@@ -293,8 +295,11 @@ mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
rate_ie = (void *)cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES,
params->beacon.tail,
params->beacon.tail_len);
- if (rate_ie)
+ if (rate_ie) {
+ if (rate_ie->len > MWIFIEX_SUPPORTED_RATES - rate_len)
+ return;
memcpy(bss_cfg->rates + rate_len, rate_ie + 1, rate_ie->len);
+ }
return;
}
@@ -412,6 +417,8 @@ mwifiex_set_wmm_params(struct mwifiex_private *priv,
params->beacon.tail_len);
if (vendor_ie) {
wmm_ie = (struct ieee_types_header *)vendor_ie;
+ if (*(vendor_ie + 1) > sizeof(struct mwifiex_types_wmm_info))
+ return;
memcpy(&bss_cfg->wmm_info, wmm_ie + 1,
sizeof(bss_cfg->wmm_info));
priv->wmm_enabled = 1;
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 6f55ab4f7959..574c93a24180 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -893,7 +893,7 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
}
if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) {
- queue->rx.rsp_cons = ++cons;
+ queue->rx.rsp_cons = ++cons + skb_queue_len(list);
kfree_skb(nskb);
return ~0U;
}
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index b180e67acafb..98aac17a91b5 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2447,6 +2447,11 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
break;
case 13: /* dump all registers of base_sel */
+ if (!base_sel) {
+ PCIE_DBG_FS(dev, "Invalid base_sel: 0x%x\n", base_sel);
+ break;
+ }
+
if (((base_sel - 1) >= MSM_PCIE_MAX_RES) ||
(!dev->res[base_sel - 1].resource)) {
PCIE_DBG_FS(dev, "PCIe: RC%d Resource does not exist\n",
@@ -2454,10 +2459,7 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
break;
}
- if (!base_sel) {
- PCIE_DBG_FS(dev, "Invalid base_sel: 0x%x\n", base_sel);
- break;
- } else if (base_sel - 1 == MSM_PCIE_RES_PARF) {
+ if (base_sel - 1 == MSM_PCIE_RES_PARF) {
pcie_parf_dump(dev);
break;
} else if (base_sel - 1 == MSM_PCIE_RES_PHY) {
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
index 9afdfdb9292a..060b40a3acc6 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -51,7 +51,7 @@ static int ipa3_generate_flt_hw_rule(enum ipa_ip_type ip,
memset(&gen_params, 0, sizeof(gen_params));
gen_params.ipt = ip;
- if (entry->rt_tbl)
+ if (entry->rt_tbl && (!ipa3_check_idr_if_freed(entry->rt_tbl)))
gen_params.rt_tbl_idx = entry->rt_tbl->idx;
else
gen_params.rt_tbl_idx = entry->rule.rt_tbl_idx;
@@ -1402,7 +1402,9 @@ int ipa3_reset_flt(enum ipa_ip_type ip, bool user_only)
entry->ipacm_installed) {
list_del(&entry->link);
entry->tbl->rule_cnt--;
- if (entry->rt_tbl)
+ if (entry->rt_tbl &&
+ (!ipa3_check_idr_if_freed(
+ entry->rt_tbl)))
entry->rt_tbl->ref_cnt--;
/* if rule id was allocated from idr, remove */
rule_id = entry->rule_id;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 4d6bc6fc859e..7691aa93d544 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -2125,5 +2125,6 @@ struct dentry *ipa_debugfs_get_root(void);
bool ipa3_is_msm_device(void);
struct device *ipa3_get_pdev(void);
int ipa3_allocate_dma_task_for_gsi(void);
+bool ipa3_check_idr_if_freed(void *ptr);
void ipa3_free_dma_task_for_gsi(void);
#endif /* _IPA3_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index 659d38e90108..5413e62a75d8 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -94,6 +94,7 @@ static int ipa_generate_rt_hw_rule(enum ipa_ip_type ip,
struct ipa3_hdr_proc_ctx_entry *proc_ctx;
proc_ctx = (entry->proc_ctx) ? : entry->hdr->proc_ctx;
if ((proc_ctx == NULL) ||
+ ipa3_check_idr_if_freed(proc_ctx) ||
(proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
gen_params.hdr_type = IPAHAL_RT_RULE_HDR_NONE;
gen_params.hdr_ofst = 0;
@@ -731,7 +732,8 @@ struct ipa3_rt_tbl *__ipa3_find_rt_tbl(enum ipa_ip_type ip, const char *name)
set = &ipa3_ctx->rt_tbl_set[ip];
list_for_each_entry(entry, &set->head_rt_tbl_list, link) {
- if (!strcmp(name, entry->name))
+ if (!ipa3_check_idr_if_freed(entry) &&
+ !strcmp(name, entry->name))
return entry;
}
@@ -1366,7 +1368,8 @@ int __ipa3_del_rt_rule(u32 rule_hdl)
if (entry->hdr)
__ipa3_release_hdr(entry->hdr->id);
- else if (entry->proc_ctx)
+ else if (entry->proc_ctx &&
+ (!ipa3_check_idr_if_freed(entry->proc_ctx)))
__ipa3_release_hdr_proc_ctx(entry->proc_ctx->id);
list_del(&entry->link);
entry->tbl->rule_cnt--;
@@ -1567,7 +1570,9 @@ int ipa3_reset_rt(enum ipa_ip_type ip, bool user_only)
tbl->rule_cnt--;
if (rule->hdr)
__ipa3_release_hdr(rule->hdr->id);
- else if (rule->proc_ctx)
+ else if (rule->proc_ctx &&
+ (!ipa3_check_idr_if_freed(
+ rule->proc_ctx)))
__ipa3_release_hdr_proc_ctx(
rule->proc_ctx->id);
rule->cookie = 0;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index f4bce295311c..a00fcaeb8d8f 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -3865,3 +3865,19 @@ struct device *ipa3_get_pdev(void)
return ipa3_ctx->pdev;
}
+
+bool ipa3_check_idr_if_freed(void *ptr)
+{
+ int id;
+ void *iter_ptr;
+
+ spin_lock(&ipa3_ctx->idr_lock);
+ idr_for_each_entry(&ipa3_ctx->ipa_idr, iter_ptr, id) {
+ if ((uintptr_t)ptr == (uintptr_t)iter_ptr) {
+ spin_unlock(&ipa3_ctx->idr_lock);
+ return false;
+ }
+ }
+ spin_unlock(&ipa3_ctx->idr_lock);
+ return true;
+}
diff --git a/drivers/soc/qcom/hab/ghs_comm.c b/drivers/soc/qcom/hab/ghs_comm.c
index fbd579793879..023417292b74 100644
--- a/drivers/soc/qcom/hab/ghs_comm.c
+++ b/drivers/soc/qcom/hab/ghs_comm.c
@@ -53,6 +53,12 @@ int physical_channel_send(struct physical_channel *pchan,
GIPC_Result result = GIPC_Success;
uint8_t *msg = NULL;
+ if (!dev) {
+ pr_err("no send pchan %s has been de-alloced msg for %zd bytes\n",
+ pchan->name);
+ return -ENODEV;
+ }
+
spin_lock_bh(&dev->io_lock);
result = GIPC_PrepareMessage(dev->endpoint, sizebytes+sizeof(*header),
@@ -104,10 +110,15 @@ void physical_channel_rx_dispatch(unsigned long physical_channel)
(struct physical_channel *)physical_channel;
struct ghs_vdev *dev = (struct ghs_vdev *)pchan->hyp_data;
GIPC_Result result = GIPC_Success;
-
uint32_t events;
unsigned long flags;
+ if (!dev) {
+ pr_err("no recv pchan %s has been de-alloced msg for %zd bytes\n",
+ pchan->name);
+ return;
+ }
+
spin_lock_irqsave(&pchan->rxbuf_lock, flags);
events = kgipc_dequeue_events(dev->endpoint);
spin_unlock_irqrestore(&pchan->rxbuf_lock, flags);
diff --git a/drivers/soc/qcom/hab/hab_ghs.c b/drivers/soc/qcom/hab/hab_ghs.c
index 2c8fb14dad1f..f479d69b9e38 100644
--- a/drivers/soc/qcom/hab/hab_ghs.c
+++ b/drivers/soc/qcom/hab/hab_ghs.c
@@ -263,7 +263,8 @@ int habhyp_commdev_dealloc(void *commdev)
kgipc_endpoint_free(dev->endpoint);
kfree(dev->read_data);
kfree(dev);
-
+ pchan->closed = 1;
+ pchan->hyp_data = NULL;
if (get_refcnt(pchan->refcount) > 1) {
pr_warn("potential leak pchan %s vchans %d refcnt %d\n",
pchan->name, pchan->vcnt, get_refcnt(pchan->refcount));
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index fc46c8cf5fcd..3bd19de7df71 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -1275,7 +1275,6 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending)
atmel_port->hd_start_rx = false;
atmel_start_rx(port);
- return;
}
tasklet_schedule(&atmel_port->tasklet);
diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c
index ba9374ee6665..f8f9927dc0a4 100644
--- a/drivers/tty/serial/sprd_serial.c
+++ b/drivers/tty/serial/sprd_serial.c
@@ -240,7 +240,7 @@ static inline void sprd_rx(struct uart_port *port)
if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE |
SPRD_LSR_FE | SPRD_LSR_OE))
- if (handle_lsr_errors(port, &lsr, &flag))
+ if (handle_lsr_errors(port, &flag, &lsr))
continue;
if (uart_handle_sysrq_char(port, ch))
continue;
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 421f1d3fbdb8..126987c9da75 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -894,7 +894,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
struct usb_bos_descriptor *bos;
struct usb_dev_cap_header *cap;
struct usb_ssp_cap_descriptor *ssp_cap;
- unsigned char *buffer;
+ unsigned char *buffer, *buffer0;
int length, total_len, num, i, ssac;
__u8 cap_type;
int ret;
@@ -939,10 +939,12 @@ int usb_get_bos_descriptor(struct usb_device *dev)
ret = -ENOMSG;
goto err;
}
+
+ buffer0 = buffer;
total_len -= length;
+ buffer += length;
for (i = 0; i < num; i++) {
- buffer += length;
cap = (struct usb_dev_cap_header *)buffer;
if (total_len < sizeof(*cap) || total_len < cap->bLength) {
@@ -956,8 +958,6 @@ int usb_get_bos_descriptor(struct usb_device *dev)
break;
}
- total_len -= length;
-
if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
dev_warn(ddev, "descriptor type invalid, skip\n");
continue;
@@ -1001,7 +1001,11 @@ int usb_get_bos_descriptor(struct usb_device *dev)
default:
break;
}
+
+ total_len -= length;
+ buffer += length;
}
+ dev->bos->desc->wTotalLength = cpu_to_le16(buffer - buffer0);
return 0;
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 0650f0b69de7..b6b25c75b80c 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -276,6 +276,8 @@ struct dwc3_msm {
struct mutex suspend_resume_mutex;
enum usb_device_speed override_usb_speed;
+
+ bool core_init_failed;
};
#define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */
@@ -1953,12 +1955,20 @@ static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc)
ret = dwc3_core_pre_init(dwc);
if (ret) {
dev_err(mdwc->dev, "dwc3_core_pre_init failed\n");
+ mdwc->core_init_failed = true;
return;
}
mdwc->init = true;
}
- dwc3_core_init(dwc);
+ ret = dwc3_core_init(dwc);
+ if (ret) {
+ dev_err(mdwc->dev, "dwc3_core_init failed\n");
+ mdwc->core_init_failed = true;
+ return;
+ }
+
+ mdwc->core_init_failed = false;
/* Re-configure event buffers */
dwc3_event_buffers_setup(dwc);
@@ -2229,7 +2239,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool hibernation)
/* kick_sm if it is waiting for lpm sequence to finish */
if (test_and_clear_bit(WAIT_FOR_LPM, &mdwc->inputs))
- schedule_delayed_work(&mdwc->sm_work, 0);
+ queue_delayed_work(mdwc->sm_usb_wq, &mdwc->sm_work, 0);
mutex_unlock(&mdwc->suspend_resume_mutex);
@@ -2325,6 +2335,12 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc)
/* Resume HS PHY */
usb_phy_set_suspend(mdwc->hs_phy, 0);
+ /* Disable HSPHY auto suspend */
+ dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
+ dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) &
+ ~(DWC3_GUSB2PHYCFG_ENBLSLPM |
+ DWC3_GUSB2PHYCFG_SUSPHY));
+
/* Recover from controller power collapse */
if (mdwc->lpm_flags & MDWC3_POWER_COLLAPSE) {
dev_dbg(mdwc->dev, "%s: exit power collapse\n", __func__);
@@ -2339,12 +2355,6 @@ static int dwc3_msm_resume(struct dwc3_msm *mdwc)
/* enable power evt irq for IN P3 detection */
enable_irq(mdwc->pwr_event_irq);
- /* Disable HSPHY auto suspend */
- dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
- dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) &
- ~(DWC3_GUSB2PHYCFG_ENBLSLPM |
- DWC3_GUSB2PHYCFG_SUSPHY));
-
/* Disable wakeup capable for HS_PHY IRQ & SS_PHY_IRQ if enabled */
if (mdwc->lpm_flags & MDWC3_ASYNC_IRQ_WAKE_CAPABILITY) {
if (!mdwc->no_wakeup_src_in_hostmode)
@@ -3602,6 +3612,12 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
dev_dbg(mdwc->dev, "%s: turn on host\n", __func__);
pm_runtime_get_sync(mdwc->dev);
+ if (mdwc->core_init_failed) {
+ dev_err(mdwc->dev, "%s: Core init failed\n", __func__);
+ pm_runtime_put_sync_suspend(mdwc->dev);
+ return -EAGAIN;
+ }
+
mdwc->hs_phy->flags |= PHY_HOST_MODE;
if (dwc->maximum_speed == USB_SPEED_SUPER) {
mdwc->ss_phy->flags |= PHY_HOST_MODE;
@@ -3748,8 +3764,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
/* wait for LPM, to ensure h/w is reset after stop_host */
set_bit(WAIT_FOR_LPM, &mdwc->inputs);
- pm_runtime_mark_last_busy(mdwc->dev);
- pm_runtime_put_sync_autosuspend(mdwc->dev);
+ pm_runtime_put_sync_suspend(mdwc->dev);
dbg_event(0xFF, "StopHost psync",
atomic_read(&mdwc->dev->power.usage_count));
}
@@ -4076,6 +4091,10 @@ static void dwc3_otg_sm_work(struct work_struct *w)
delay = VBUS_REG_CHECK_DELAY;
work = 1;
mdwc->vbus_retry_count++;
+ } else if (ret == -EAGAIN) {
+ mdwc->drd_state = DRD_STATE_HOST_IDLE;
+ dev_dbg(mdwc->dev, "Core init failed. Retrying...\n");
+ work = 1;
} else if (ret) {
dev_err(mdwc->dev, "unable to start host\n");
mdwc->drd_state = DRD_STATE_HOST_IDLE;
diff --git a/drivers/usb/phy/phy-msm-qusb.c b/drivers/usb/phy/phy-msm-qusb.c
index ae72ec6b3d19..1b09c028d098 100644
--- a/drivers/usb/phy/phy-msm-qusb.c
+++ b/drivers/usb/phy/phy-msm-qusb.c
@@ -862,7 +862,7 @@ static int qusb_phy_init(struct usb_phy *phy)
wmb();
/* Required to get PHY PLL lock successfully */
- usleep_range(100, 110);
+ usleep_range(50000, 51000);
}
if (qphy->major_rev < 2) {
@@ -881,6 +881,7 @@ static int qusb_phy_init(struct usb_phy *phy)
if (pll_lock_fail) {
dev_err(phy->dev, "QUSB PHY PLL LOCK fails:%x\n", reg);
WARN_ON(1);
+ return -ETIMEDOUT;
}
return 0;
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index 388eec4e1a90..accc88c7b29a 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -23,6 +23,12 @@
* Using this limit prevents one virtqueue from starving others. */
#define VHOST_TEST_WEIGHT 0x80000
+/* Max number of packets transferred before requeueing the job.
+ * Using this limit prevents one virtqueue from starving others with
+ * pkts.
+ */
+#define VHOST_TEST_PKT_WEIGHT 256
+
enum {
VHOST_TEST_VQ = 0,
VHOST_TEST_VQ_MAX = 1,
@@ -81,10 +87,8 @@ static void handle_vq(struct vhost_test *n)
}
vhost_add_used_and_signal(&n->dev, vq, head, 0);
total_len += len;
- if (unlikely(total_len >= VHOST_TEST_WEIGHT)) {
- vhost_poll_queue(&vq->poll);
+ if (unlikely(vhost_exceeds_weight(vq, 0, total_len)))
break;
- }
}
mutex_unlock(&vq->mutex);
@@ -116,7 +120,8 @@ static int vhost_test_open(struct inode *inode, struct file *f)
dev = &n->dev;
vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];
n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
- vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
+ vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX,
+ VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT);
f->private_data = n;
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index c76c40d1c398..310a779ddd06 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1910,7 +1910,7 @@ static int get_indirect(struct vhost_virtqueue *vq,
/* If this is an input descriptor, increment that count. */
if (access == VHOST_ACCESS_WO) {
*in_num += ret;
- if (unlikely(log)) {
+ if (unlikely(log && ret)) {
log[*log_num].addr = vhost64_to_cpu(vq, desc.addr);
log[*log_num].len = vhost32_to_cpu(vq, desc.len);
++*log_num;
@@ -2046,7 +2046,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
/* If this is an input descriptor,
* increment that count. */
*in_num += ret;
- if (unlikely(log)) {
+ if (unlikely(log && ret)) {
log[*log_num].addr = vhost64_to_cpu(vq, desc.addr);
log[*log_num].len = vhost32_to_cpu(vq, desc.len);
++*log_num;
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index 419991a98d4e..c2cfc8e0532e 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -888,7 +888,7 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
{
struct buf_data *pcmds = file->private_data;
ssize_t ret = 0;
- int blen = 0;
+ unsigned int blen = 0;
char *string_buf;
mutex_lock(&pcmds->dbg_mutex);
@@ -900,6 +900,11 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
/* Allocate memory for the received string */
blen = count + (pcmds->sblen);
+ if (blen > U32_MAX - 1) {
+ mutex_unlock(&pcmds->dbg_mutex);
+ return -EINVAL;
+ }
+
string_buf = krealloc(pcmds->string_buf, blen + 1, GFP_KERNEL);
if (!string_buf) {
pr_err("%s: Failed to allocate memory\n", __func__);
@@ -907,6 +912,7 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
return -ENOMEM;
}
+ pcmds->string_buf = string_buf;
/* Writing in batches is possible */
ret = simple_write_to_buffer(string_buf, blen, ppos, p, count);
if (ret < 0) {
@@ -916,7 +922,6 @@ static ssize_t mdss_dsi_cmd_write(struct file *file, const char __user *p,
}
string_buf[ret] = '\0';
- pcmds->string_buf = string_buf;
pcmds->sblen = count;
mutex_unlock(&pcmds->dbg_mutex);
return ret;
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 57a46093656a..f9c3907bf159 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -5133,7 +5133,7 @@ process_leaf:
}
if (btrfs_inode_in_log(di_inode, trans->transid)) {
- iput(di_inode);
+ btrfs_add_delayed_iput(di_inode);
continue;
}
@@ -5143,7 +5143,7 @@ process_leaf:
btrfs_release_path(path);
ret = btrfs_log_inode(trans, root, di_inode,
log_mode, 0, LLONG_MAX, ctx);
- iput(di_inode);
+ btrfs_add_delayed_iput(di_inode);
if (ret)
goto next_dir_inode;
if (ctx->log_new_dentries) {
@@ -5281,7 +5281,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
ret = btrfs_log_inode(trans, root, dir_inode,
LOG_INODE_ALL, 0, LLONG_MAX, ctx);
- iput(dir_inode);
+ btrfs_add_delayed_iput(dir_inode);
if (ret)
goto out;
}
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 9cb72fd40eff..63108343124a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2466,6 +2466,7 @@ static int
cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
{
int rc = 0;
+ int is_domain = 0;
const char *delim, *payload;
char *desc;
ssize_t len;
@@ -2513,6 +2514,7 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
rc = PTR_ERR(key);
goto out_err;
}
+ is_domain = 1;
}
down_read(&key->sem);
@@ -2570,6 +2572,26 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
goto out_key_put;
}
+ /*
+ * If we have a domain key then we must set the domainName in the
+ * for the request.
+ */
+ if (is_domain && ses->domainName) {
+ vol->domainname = kstrndup(ses->domainName,
+ strlen(ses->domainName),
+ GFP_KERNEL);
+ if (!vol->domainname) {
+ cifs_dbg(FYI, "Unable to allocate %zd bytes for "
+ "domain\n", len);
+ rc = -ENOMEM;
+ kfree(vol->username);
+ vol->username = NULL;
+ kzfree(vol->password);
+ vol->password = NULL;
+ goto out_key_put;
+ }
+ }
+
out_key_put:
up_read(&key->sem);
key_put(key);
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index d3e3761eacfa..c5e884585c23 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -73,13 +73,13 @@ nfs4_file_open(struct inode *inode, struct file *filp)
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
switch (err) {
- case -EPERM:
- case -EACCES:
- case -EDQUOT:
- case -ENOSPC:
- case -EROFS:
- goto out_put_ctx;
default:
+ goto out_put_ctx;
+ case -ENOENT:
+ case -ESTALE:
+ case -EISDIR:
+ case -ENOTDIR:
+ case -ELOOP:
goto out_drop;
}
}
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 8a2077408ab0..af1bb7353792 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -593,7 +593,7 @@ static void nfs_pgio_rpcsetup(struct nfs_pgio_header *hdr,
}
hdr->res.fattr = &hdr->fattr;
- hdr->res.count = count;
+ hdr->res.count = 0;
hdr->res.eof = 0;
hdr->res.verf = &hdr->verf;
nfs_fattr_init(&hdr->fattr);
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index b417bbcd9704..b83e14ad13c4 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -588,7 +588,8 @@ static int nfs_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
/* Emulate the eof flag, which isn't normally needed in NFSv2
* as it is guaranteed to always return the file attributes
*/
- if (hdr->args.offset + hdr->res.count >= hdr->res.fattr->size)
+ if ((hdr->res.count == 0 && hdr->args.count > 0) ||
+ hdr->args.offset + hdr->res.count >= hdr->res.fattr->size)
hdr->res.eof = 1;
}
return 0;
@@ -609,8 +610,10 @@ static int nfs_proc_pgio_rpc_prepare(struct rpc_task *task,
static int nfs_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
{
- if (task->tk_status >= 0)
+ if (task->tk_status >= 0) {
+ hdr->res.count = hdr->args.count;
nfs_writeback_update_inode(hdr);
+ }
return 0;
}
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 4cc40de38dff..953c88dd6519 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -407,7 +407,7 @@ static int ovl_create_or_link(struct dentry *dentry, int mode, dev_t rdev,
if (!ovl_dentry_is_opaque(dentry)) {
err = ovl_create_upper(dentry, inode, &stat, link, hardlink);
} else {
- const struct cred *old_cred;
+ const struct cred *old_cred, *hold_cred = NULL;
struct cred *override_cred;
old_cred = ovl_override_creds(dentry->d_sb);
@@ -422,13 +422,15 @@ static int ovl_create_or_link(struct dentry *dentry, int mode, dev_t rdev,
our_cred = current_cred();
override_cred->fsuid = our_cred->fsuid;
override_cred->fsgid = our_cred->fsgid;
- put_cred(override_creds(override_cred));
+ hold_cred = override_creds(override_cred);
put_cred(override_cred);
err = ovl_create_over_whiteout(dentry, inode, &stat,
link, hardlink);
}
- ovl_revert_creds(old_cred);
+ ovl_revert_creds(old_cred ?: hold_cred);
+ if (old_cred && hold_cred)
+ put_cred(hold_cred);
}
if (!err)
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 605f9731fe5d..1046fb4611bf 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -145,7 +145,7 @@ the appropriate macros. */
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
#define MSG_MASK_TBL_CNT 26
-#define APPS_EVENT_LAST_ID 0xCAA
+#define APPS_EVENT_LAST_ID 0xCB4
#define MSG_SSID_0 0
#define MSG_SSID_0_LAST 130
@@ -911,7 +911,7 @@ static const uint32_t msg_bld_masks_25[] = {
/* LOG CODES */
static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 0 */
- 0x1C9A, /* EQUIP ID 1 */
+ 0x1CB2, /* EQUIP ID 1 */
0x0, /* EQUIP ID 2 */
0x0, /* EQUIP ID 3 */
0x4910, /* EQUIP ID 4 */
diff --git a/include/net/cnss2.h b/include/net/cnss2.h
index 69b9e5d607ef..5ed1b05277b1 100644
--- a/include/net/cnss2.h
+++ b/include/net/cnss2.h
@@ -15,6 +15,10 @@
#include <linux/pci.h>
#include <linux/usb.h>
+#include <linux/mmc/sdio_func.h>
+#ifdef CONFIG_SDIO_QCN
+#include <linux/qcn_sdio_al.h>
+#endif
#define CNSS_MAX_FILE_NAME 20
#define CNSS_MAX_TIMESTAMP_LEN 32
@@ -111,6 +115,21 @@ struct cnss_usb_wlan_driver {
const struct usb_device_id *id_table;
};
+#ifdef CONFIG_SDIO_QCN
+struct cnss_sdio_wlan_driver {
+ const char *name;
+ const struct sdio_device_id *id_table;
+ int (*probe)(struct sdio_func *, const struct sdio_device_id *);
+ void (*remove)(struct sdio_func *);
+ int (*reinit)(struct sdio_func *, const struct sdio_device_id *);
+ void (*shutdown)(struct sdio_func *);
+ void (*crash_shutdown)(struct sdio_func *);
+ int (*suspend)(struct device *);
+ int (*resume)(struct device *);
+ void (*update_status)(struct sdio_func *, uint32_t status);
+};
+#endif
+
enum cnss_driver_status {
CNSS_UNINITIALIZED,
CNSS_INITIALIZED,
@@ -256,5 +275,42 @@ extern int cnss_usb_wlan_register_driver(struct cnss_usb_wlan_driver *driver);
extern void cnss_usb_wlan_unregister_driver(struct cnss_usb_wlan_driver *
driver);
extern int cnss_usb_is_device_down(struct device *dev);
+#ifdef CONFIG_SDIO_QCN
+extern int cnss_sdio_wlan_register_driver(struct cnss_sdio_wlan_driver *
+ driver_ops);
+extern void cnss_sdio_wlan_unregister_driver(struct cnss_sdio_wlan_driver *
+ driver_ops);
+extern struct sdio_al_client_handle *cnss_sdio_wlan_get_sdio_al_client_handle(
+ struct sdio_func *func);
+extern struct sdio_al_channel_handle *cnss_sdio_wlan_register_sdio_al_channel(
+ struct sdio_al_channel_data *channel_data);
+extern void cnss_sdio_wlan_unregister_sdio_al_channel(
+ struct sdio_al_channel_handle *ch_handle);
+#else
+extern inline int cnss_sdio_wlan_register_driver(void *driver_ops)
+{
+ return 0;
+}
+
+extern inline void cnss_sdio_wlan_unregister_driver(void *driver_ops)
+{
+
+}
+
+extern inline void *cnss_sdio_wlan_get_sdio_al_client_handle(void *func)
+{
+ return NULL;
+}
+
+extern inline void *cnss_sdio_wlan_register_sdio_al_channel(void *channel_data)
+{
+ return NULL;
+}
+
+extern inline void cnss_sdio_wlan_unregister_sdio_al_channel(void *ch_handle)
+{
+
+}
+#endif
#endif /* _NET_CNSS2_H */
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9e1325e36415..c5c03fa47f8c 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1304,6 +1304,23 @@ static inline int xfrm_state_kern(const struct xfrm_state *x)
return atomic_read(&x->tunnel_users);
}
+static inline bool xfrm_id_proto_valid(u8 proto)
+{
+ switch (proto) {
+ case IPPROTO_AH:
+ case IPPROTO_ESP:
+ case IPPROTO_COMP:
+#if IS_ENABLED(CONFIG_IPV6)
+ case IPPROTO_ROUTING:
+ case IPPROTO_DSTOPTS:
+#endif
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */
static inline int xfrm_id_proto_match(u8 proto, u8 userproto)
{
return (!userproto || proto == userproto ||
diff --git a/include/uapi/linux/isdn/capicmd.h b/include/uapi/linux/isdn/capicmd.h
index b58635f722da..ae1e1fba2e13 100644
--- a/include/uapi/linux/isdn/capicmd.h
+++ b/include/uapi/linux/isdn/capicmd.h
@@ -15,6 +15,7 @@
#define CAPI_MSG_BASELEN 8
#define CAPI_DATA_B3_REQ_LEN (CAPI_MSG_BASELEN+4+4+2+2+2)
#define CAPI_DATA_B3_RESP_LEN (CAPI_MSG_BASELEN+4+2)
+#define CAPI_DISCONNECT_B3_RESP_LEN (CAPI_MSG_BASELEN+4)
/*----- CAPI commands -----*/
#define CAPI_ALERT 0x01
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index b86886beee4f..867fb0ed4aa6 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -37,6 +37,8 @@ static void resend_irqs(unsigned long arg)
irq = find_first_bit(irqs_resend, nr_irqs);
clear_bit(irq, irqs_resend);
desc = irq_to_desc(irq);
+ if (!desc)
+ continue;
local_irq_disable();
desc->handle_irq(desc);
local_irq_enable();
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index cd8deea2d074..db6b65a5f811 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -256,7 +256,7 @@ static int nlmsg_populate_rtr_fill(struct sk_buff *skb,
struct nlmsghdr *nlh;
struct nlattr *nest;
- nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), NLM_F_MULTI);
+ nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), 0);
if (!nlh)
return -EMSGSIZE;
diff --git a/net/core/dev.c b/net/core/dev.c
index f67f5d903c1f..e19be0449166 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6873,6 +6873,8 @@ int register_netdevice(struct net_device *dev)
ret = notifier_to_errno(ret);
if (ret) {
rollback_registered(dev);
+ rcu_barrier();
+
dev->reg_state = NETREG_UNREGISTERED;
}
/*
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2fb43a1f259d..2f4896377fbc 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -226,7 +226,7 @@ static void tcp_ecn_accept_cwr(struct tcp_sock *tp, const struct sk_buff *skb)
static void tcp_ecn_withdraw_cwr(struct tcp_sock *tp)
{
- tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
+ tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR;
}
static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb)
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index 4c753f4a3712..40b835720722 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -231,7 +231,7 @@ static int __net_init ping_v6_proc_init_net(struct net *net)
return ping_proc_register(net, &ping_v6_seq_afinfo);
}
-static void __net_init ping_v6_proc_exit_net(struct net *net)
+static void __net_exit ping_v6_proc_exit_net(struct net *net)
{
return ping_proc_unregister(net, &ping_v6_seq_afinfo);
}
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 0b147079b0c6..b400a4cc265b 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1959,8 +1959,10 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
if (rq->sadb_x_ipsecrequest_mode == 0)
return -EINVAL;
+ if (!xfrm_id_proto_valid(rq->sadb_x_ipsecrequest_proto))
+ return -EINVAL;
- t->id.proto = rq->sadb_x_ipsecrequest_proto; /* XXX check proto */
+ t->id.proto = rq->sadb_x_ipsecrequest_proto;
if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0)
return -EINVAL;
t->mode = mode;
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index b666959f17c0..b7c13179fa40 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -334,7 +334,7 @@ static int find_pattern(const char *data, size_t dlen,
i++;
}
- pr_debug("Skipped up to `%c'!\n", skip);
+ pr_debug("Skipped up to 0x%hhx delimiter!\n", skip);
*numoff = i;
*numlen = getnum(data + i, dlen - i, cmd, term, numoff);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 5d8988185c59..0dd9fc3f57e8 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -4176,7 +4176,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
/* Opening a Tx-ring is NOT supported in TPACKET_V3 */
if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
- WARN(1, "Tx-ring is not supported.\n");
+ net_warn_ratelimited("Tx-ring is not supported.\n");
goto out;
}
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index aa4725038f94..eec6dc2d3152 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -671,7 +671,11 @@ static void qdisc_rcu_free(struct rcu_head *head)
void qdisc_destroy(struct Qdisc *qdisc)
{
- const struct Qdisc_ops *ops = qdisc->ops;
+ const struct Qdisc_ops *ops;
+
+ if (!qdisc)
+ return;
+ ops = qdisc->ops;
if (qdisc->flags & TCQ_F_BUILTIN ||
!atomic_dec_and_test(&qdisc->refcnt))
diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
index aff2a1b46f7f..dc68dccc6b0c 100644
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -552,7 +552,7 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt)
new_hhf_non_hh_weight = nla_get_u32(tb[TCA_HHF_NON_HH_WEIGHT]);
non_hh_quantum = (u64)new_quantum * new_hhf_non_hh_weight;
- if (non_hh_quantum > INT_MAX)
+ if (non_hh_quantum == 0 || non_hh_quantum > INT_MAX)
return -EINVAL;
sch_tree_lock(sch);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 247d1888c386..07c54b212cd7 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1331,7 +1331,7 @@ static int __net_init sctp_ctrlsock_init(struct net *net)
return status;
}
-static void __net_init sctp_ctrlsock_exit(struct net *net)
+static void __net_exit sctp_ctrlsock_exit(struct net *net)
{
/* Free the control endpoint. */
inet_ctl_sock_destroy(net->sctp.ctl_sock);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index e5cd14307aa5..7c220e905168 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -505,7 +505,7 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands,
*/
if ((transport->state == SCTP_ACTIVE) &&
(transport->error_count < transport->pathmaxrxt) &&
- (transport->error_count > asoc->pf_retrans)) {
+ (transport->error_count > transport->pf_retrans)) {
sctp_assoc_control_transport(asoc, transport,
SCTP_TRANSPORT_PF,
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index c4c151bc000c..b57675f81ceb 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -284,7 +284,8 @@ static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr)
publ->key);
}
- kfree_rcu(p, rcu);
+ if (p)
+ kfree_rcu(p, rcu);
}
void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 49ff7556b2b5..7d50a371574c 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2137,7 +2137,7 @@ void xfrm_state_fini(struct net *net)
unsigned int sz;
flush_work(&net->xfrm.state_hash_work);
- xfrm_state_flush(net, IPSEC_PROTO_ANY, false);
+ xfrm_state_flush(net, 0, false);
flush_work(&net->xfrm.state_gc_work);
WARN_ON(!list_empty(&net->xfrm.state_all));
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 46366810e93e..69126af39c79 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1456,20 +1456,8 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
return -EINVAL;
}
- switch (ut[i].id.proto) {
- case IPPROTO_AH:
- case IPPROTO_ESP:
- case IPPROTO_COMP:
-#if IS_ENABLED(CONFIG_IPV6)
- case IPPROTO_ROUTING:
- case IPPROTO_DSTOPTS:
-#endif
- case IPSEC_PROTO_ANY:
- break;
- default:
+ if (!xfrm_id_proto_valid(ut[i].id.proto))
return -EINVAL;
- }
-
}
return 0;
diff --git a/scripts/decode_stacktrace.sh b/scripts/decode_stacktrace.sh
index ffc46c7c3afb..4f5e76f76b9d 100755
--- a/scripts/decode_stacktrace.sh
+++ b/scripts/decode_stacktrace.sh
@@ -64,7 +64,7 @@ parse_symbol() {
fi
# Strip out the base of the path
- code=${code//^$basepath/""}
+ code=${code#$basepath/}
# In the case of inlines, move everything to same line
code=${code//$'\n'/' '}
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 8882b729924d..976deea0569e 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -71,6 +71,9 @@ static void request_key_auth_describe(const struct key *key,
{
struct request_key_auth *rka = key->payload.data[0];
+ if (!rka)
+ return;
+
seq_puts(m, "key:");
seq_puts(m, key->description);
if (key_is_positive(key))
@@ -88,6 +91,9 @@ static long request_key_auth_read(const struct key *key,
size_t datalen;
long ret;
+ if (!rka)
+ return -EKEYREVOKED;
+
datalen = rka->callout_len;
ret = datalen;
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index a03cf68d0bcd..12d87204e373 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -827,6 +827,8 @@ static void apply_fixup(struct hda_codec *codec, int id, int action, int depth)
while (id >= 0) {
const struct hda_fixup *fix = codec->fixup_list + id;
+ if (++depth > 10)
+ break;
if (fix->chained_before)
apply_fixup(codec, fix->chain_id, action, depth + 1);
@@ -866,8 +868,6 @@ static void apply_fixup(struct hda_codec *codec, int id, int action, int depth)
}
if (!fix->chained || fix->chained_before)
break;
- if (++depth > 10)
- break;
id = fix->chain_id;
}
}
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 142549bbeb53..869c322ddae3 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -5826,7 +5826,8 @@ int snd_hda_gen_init(struct hda_codec *codec)
if (spec->init_hook)
spec->init_hook(codec);
- snd_hda_apply_verbs(codec);
+ if (!spec->skip_verbs)
+ snd_hda_apply_verbs(codec);
init_multi_out(codec);
init_extra_out(codec);
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 56e4139b9032..25f2397c29f7 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -236,6 +236,7 @@ struct hda_gen_spec {
unsigned int indep_hp_enabled:1; /* independent HP enabled */
unsigned int have_aamix_ctl:1;
unsigned int hp_mic_jack_modes:1;
+ unsigned int skip_verbs:1; /* don't apply verbs at snd_hda_gen_init() */
/* additional mute flags (only effective with auto_mute_via_amp=1) */
u64 mute_bits;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 68d96c2e8cde..d5ca16048ce0 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -772,9 +772,11 @@ static int alc_init(struct hda_codec *codec)
if (spec->init_hook)
spec->init_hook(codec);
+ spec->gen.skip_verbs = 1; /* applied in below */
snd_hda_gen_init(codec);
alc_fix_pll(codec);
alc_auto_init_amp(codec, spec->init_amp);
+ snd_hda_apply_verbs(codec); /* apply verbs here after own init */
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 532e7bf06868..58cf16188722 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -3014,7 +3014,7 @@ int initialize_counters(int cpu_id)
void allocate_output_buffer()
{
- output_buffer = calloc(1, (1 + topo.num_cpus) * 1024);
+ output_buffer = calloc(1, (1 + topo.num_cpus) * 2048);
outp = output_buffer;
if (outp == NULL)
err(-1, "calloc output buffer");
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
index 571c1ce37d15..5c1efb869df2 100644
--- a/virt/kvm/coalesced_mmio.c
+++ b/virt/kvm/coalesced_mmio.c
@@ -39,7 +39,7 @@ static int coalesced_mmio_in_range(struct kvm_coalesced_mmio_dev *dev,
return 1;
}
-static int coalesced_mmio_has_room(struct kvm_coalesced_mmio_dev *dev)
+static int coalesced_mmio_has_room(struct kvm_coalesced_mmio_dev *dev, u32 last)
{
struct kvm_coalesced_mmio_ring *ring;
unsigned avail;
@@ -51,7 +51,7 @@ static int coalesced_mmio_has_room(struct kvm_coalesced_mmio_dev *dev)
* there is always one unused entry in the buffer
*/
ring = dev->kvm->coalesced_mmio_ring;
- avail = (ring->first - ring->last - 1) % KVM_COALESCED_MMIO_MAX;
+ avail = (ring->first - last - 1) % KVM_COALESCED_MMIO_MAX;
if (avail == 0) {
/* full */
return 0;
@@ -66,24 +66,27 @@ static int coalesced_mmio_write(struct kvm_vcpu *vcpu,
{
struct kvm_coalesced_mmio_dev *dev = to_mmio(this);
struct kvm_coalesced_mmio_ring *ring = dev->kvm->coalesced_mmio_ring;
+ __u32 insert;
if (!coalesced_mmio_in_range(dev, addr, len))
return -EOPNOTSUPP;
spin_lock(&dev->kvm->ring_lock);
- if (!coalesced_mmio_has_room(dev)) {
+ insert = READ_ONCE(ring->last);
+ if (!coalesced_mmio_has_room(dev, insert) ||
+ insert >= KVM_COALESCED_MMIO_MAX) {
spin_unlock(&dev->kvm->ring_lock);
return -EOPNOTSUPP;
}
/* copy data in first free entry of the ring */
- ring->coalesced_mmio[ring->last].phys_addr = addr;
- ring->coalesced_mmio[ring->last].len = len;
- memcpy(ring->coalesced_mmio[ring->last].data, val, len);
+ ring->coalesced_mmio[insert].phys_addr = addr;
+ ring->coalesced_mmio[insert].len = len;
+ memcpy(ring->coalesced_mmio[insert].data, val, len);
smp_wmb();
- ring->last = (ring->last + 1) % KVM_COALESCED_MMIO_MAX;
+ ring->last = (insert + 1) % KVM_COALESCED_MMIO_MAX;
spin_unlock(&dev->kvm->ring_lock);
return 0;
}