Merge "ARM: dts: msm: Set GPU bw voting levels for msm8905-qrd-skub_qseev4"
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index b41046b..a5225df 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -358,6 +358,7 @@
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
/sys/devices/system/cpu/vulnerabilities/l1tf
/sys/devices/system/cpu/vulnerabilities/mds
+ /sys/devices/system/cpu/vulnerabilities/srbds
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
/sys/devices/system/cpu/vulnerabilities/itlb_multihit
Date: January 2018
diff --git a/Documentation/hw-vuln/index.rst b/Documentation/hw-vuln/index.rst
index 24f53c5..b5fbc6a 100644
--- a/Documentation/hw-vuln/index.rst
+++ b/Documentation/hw-vuln/index.rst
@@ -12,4 +12,5 @@
l1tf
mds
tsx_async_abort
- multihit.rst
+ multihit
+ special-register-buffer-data-sampling
diff --git a/Documentation/hw-vuln/special-register-buffer-data-sampling.rst b/Documentation/hw-vuln/special-register-buffer-data-sampling.rst
new file mode 100644
index 0000000..47b1b3a
--- /dev/null
+++ b/Documentation/hw-vuln/special-register-buffer-data-sampling.rst
@@ -0,0 +1,149 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+SRBDS - Special Register Buffer Data Sampling
+=============================================
+
+SRBDS is a hardware vulnerability that allows MDS :doc:`mds` techniques to
+infer values returned from special register accesses. Special register
+accesses are accesses to off core registers. According to Intel's evaluation,
+the special register reads that have a security expectation of privacy are
+RDRAND, RDSEED and SGX EGETKEY.
+
+When RDRAND, RDSEED and EGETKEY instructions are used, the data is moved
+to the core through the special register mechanism that is susceptible
+to MDS attacks.
+
+Affected processors
+--------------------
+Core models (desktop, mobile, Xeon-E3) that implement RDRAND and/or RDSEED may
+be affected.
+
+A processor is affected by SRBDS if its Family_Model and stepping is
+in the following list, with the exception of the listed processors
+exporting MDS_NO while Intel TSX is available yet not enabled. The
+latter class of processors are only affected when Intel TSX is enabled
+by software using TSX_CTRL_MSR otherwise they are not affected.
+
+ ============= ============ ========
+ common name Family_Model Stepping
+ ============= ============ ========
+ IvyBridge 06_3AH All
+
+ Haswell 06_3CH All
+ Haswell_L 06_45H All
+ Haswell_G 06_46H All
+
+ Broadwell_G 06_47H All
+ Broadwell 06_3DH All
+
+ Skylake_L 06_4EH All
+ Skylake 06_5EH All
+
+ Kabylake_L 06_8EH <= 0xC
+ Kabylake 06_9EH <= 0xD
+ ============= ============ ========
+
+Related CVEs
+------------
+
+The following CVE entry is related to this SRBDS issue:
+
+ ============== ===== =====================================
+ CVE-2020-0543 SRBDS Special Register Buffer Data Sampling
+ ============== ===== =====================================
+
+Attack scenarios
+----------------
+An unprivileged user can extract values returned from RDRAND and RDSEED
+executed on another core or sibling thread using MDS techniques.
+
+
+Mitigation mechanism
+-------------------
+Intel will release microcode updates that modify the RDRAND, RDSEED, and
+EGETKEY instructions to overwrite secret special register data in the shared
+staging buffer before the secret data can be accessed by another logical
+processor.
+
+During execution of the RDRAND, RDSEED, or EGETKEY instructions, off-core
+accesses from other logical processors will be delayed until the special
+register read is complete and the secret data in the shared staging buffer is
+overwritten.
+
+This has three effects on performance:
+
+#. RDRAND, RDSEED, or EGETKEY instructions have higher latency.
+
+#. Executing RDRAND at the same time on multiple logical processors will be
+ serialized, resulting in an overall reduction in the maximum RDRAND
+ bandwidth.
+
+#. Executing RDRAND, RDSEED or EGETKEY will delay memory accesses from other
+ logical processors that miss their core caches, with an impact similar to
+ legacy locked cache-line-split accesses.
+
+The microcode updates provide an opt-out mechanism (RNGDS_MITG_DIS) to disable
+the mitigation for RDRAND and RDSEED instructions executed outside of Intel
+Software Guard Extensions (Intel SGX) enclaves. On logical processors that
+disable the mitigation using this opt-out mechanism, RDRAND and RDSEED do not
+take longer to execute and do not impact performance of sibling logical
+processors memory accesses. The opt-out mechanism does not affect Intel SGX
+enclaves (including execution of RDRAND or RDSEED inside an enclave, as well
+as EGETKEY execution).
+
+IA32_MCU_OPT_CTRL MSR Definition
+--------------------------------
+Along with the mitigation for this issue, Intel added a new thread-scope
+IA32_MCU_OPT_CTRL MSR, (address 0x123). The presence of this MSR and
+RNGDS_MITG_DIS (bit 0) is enumerated by CPUID.(EAX=07H,ECX=0).EDX[SRBDS_CTRL =
+9]==1. This MSR is introduced through the microcode update.
+
+Setting IA32_MCU_OPT_CTRL[0] (RNGDS_MITG_DIS) to 1 for a logical processor
+disables the mitigation for RDRAND and RDSEED executed outside of an Intel SGX
+enclave on that logical processor. Opting out of the mitigation for a
+particular logical processor does not affect the RDRAND and RDSEED mitigations
+for other logical processors.
+
+Note that inside of an Intel SGX enclave, the mitigation is applied regardless
+of the value of RNGDS_MITG_DS.
+
+Mitigation control on the kernel command line
+---------------------------------------------
+The kernel command line allows control over the SRBDS mitigation at boot time
+with the option "srbds=". The option for this is:
+
+ ============= =============================================================
+ off This option disables SRBDS mitigation for RDRAND and RDSEED on
+ affected platforms.
+ ============= =============================================================
+
+SRBDS System Information
+-----------------------
+The Linux kernel provides vulnerability status information through sysfs. For
+SRBDS this can be accessed by the following sysfs file:
+/sys/devices/system/cpu/vulnerabilities/srbds
+
+The possible values contained in this file are:
+
+ ============================== =============================================
+ Not affected Processor not vulnerable
+ Vulnerable Processor vulnerable and mitigation disabled
+ Vulnerable: No microcode Processor vulnerable and microcode is missing
+ mitigation
+ Mitigation: Microcode Processor is vulnerable and mitigation is in
+ effect.
+ Mitigation: TSX disabled Processor is only vulnerable when TSX is
+ enabled while this system was booted with TSX
+ disabled.
+ Unknown: Dependent on
+ hypervisor status Running on virtual guest processor that is
+ affected but with no way to know if host
+ processor is mitigated or vulnerable.
+ ============================== =============================================
+
+SRBDS Default mitigation
+------------------------
+This new microcode serializes processor access during execution of RDRAND,
+RDSEED ensures that the shared buffer is overwritten before it is released for
+reuse. Use the "srbds=off" kernel command line to disable the mitigation for
+RDRAND and RDSEED.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index cf76646..a2bff31 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -4296,6 +4296,26 @@
spia_pedr=
spia_peddr=
+ srbds= [X86,INTEL]
+ Control the Special Register Buffer Data Sampling
+ (SRBDS) mitigation.
+
+ Certain CPUs are vulnerable to an MDS-like
+ exploit which can leak bits from the random
+ number generator.
+
+ By default, this issue is mitigated by
+ microcode. However, the microcode fix can cause
+ the RDRAND and RDSEED instructions to become
+ much slower. Among other effects, this will
+ result in reduced throughput from /dev/urandom.
+
+ The microcode mitigation can be disabled with
+ the following option:
+
+ off: Disable mitigation and remove
+ performance impact to RDRAND and RDSEED
+
ssbd= [ARM64,HW]
Speculative Store Bypass Disable control
diff --git a/Makefile b/Makefile
index 35b57d3..25f9ad4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 9
-SUBLEVEL = 226
+SUBLEVEL = 227
EXTRAVERSION =
NAME = Roaring Lionus
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 9f96120..82464fa 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -12,6 +12,7 @@
#include <linux/root_dev.h>
#include <linux/console.h>
#include <linux/module.h>
+#include <linux/sizes.h>
#include <linux/cpu.h>
#include <linux/of_fdt.h>
#include <linux/of.h>
@@ -333,12 +334,12 @@
if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr)
panic("Linux built with incorrect DCCM Base address\n");
- if (CONFIG_ARC_DCCM_SZ != cpu->dccm.sz)
+ if (CONFIG_ARC_DCCM_SZ * SZ_1K != cpu->dccm.sz)
panic("Linux built with incorrect DCCM Size\n");
#endif
#ifdef CONFIG_ARC_HAS_ICCM
- if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz)
+ if (CONFIG_ARC_ICCM_SZ * SZ_1K != cpu->iccm.sz)
panic("Linux built with incorrect ICCM Size\n");
#endif
diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts
index e1f520d4..36fad2a 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard-pcie-ep.dts
@@ -37,6 +37,7 @@
&pcie_ep {
status = "okay";
+ qcom,pcie-perst-enum;
};
&ipa_hw {
diff --git a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi
index fcf3787..9391fff 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi
+++ b/arch/arm/boot/dts/qcom/sa415m-ccard.dtsi
@@ -217,8 +217,8 @@
pinctrl-1 = <&cnss_wlan_en_sleep>;
chip_cfg@0 {
- reg = <0x10000000 0x10000000>,
- <0x20000000 0x10000>;
+ reg = <0xa0000000 0x10000000>,
+ <0xb0000000 0x10000>;
reg-names = "smmu_iova_base", "smmu_iova_ipa";
supported-ids = <0x003e>;
wlan_vregs = "vdd-wlan";
diff --git a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi
index 265aba8..d0230e9 100644
--- a/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi
+++ b/arch/arm/boot/dts/qcom/sa415m-ttp.dtsi
@@ -100,8 +100,8 @@
pinctrl-1 = <&cnss_wlan_en_sleep>;
chip_cfg@0 {
- reg = <0x10000000 0x10000000>,
- <0x20000000 0x10000>;
+ reg = <0xa0000000 0x10000000>,
+ <0xb0000000 0x10000>;
reg-names = "smmu_iova_base", "smmu_iova_ipa";
supported-ids = <0x003e>;
wlan_vregs = "vdd-wlan";
diff --git a/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi b/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi
index ff35142..4593ead 100644
--- a/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8905-qrd-skub.dtsi
@@ -687,7 +687,7 @@
};
&vendor_fstab {
- status = "disabled";
+ status = "ok";
};
&system_fstab {
diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig
index c285875..9ab5bf3 100755
--- a/arch/arm64/configs/sdm670-perf_defconfig
+++ b/arch/arm64/configs/sdm670-perf_defconfig
@@ -396,6 +396,7 @@
CONFIG_DVB_MPQ_SW=y
CONFIG_QCOM_KGSL=y
CONFIG_DRM=y
+CONFIG_DRM_DP_CEC=y
CONFIG_DRM_SDE_EVTLOG_DEBUG=y
CONFIG_DRM_SDE_RSC=y
CONFIG_DRM_LT_LT9611=y
@@ -486,6 +487,8 @@
CONFIG_UIO=y
CONFIG_UIO_MSM_SHAREDMEM=y
CONFIG_STAGING=y
+CONFIG_STAGING_MEDIA=y
+CONFIG_MEDIA_CEC=y
CONFIG_ASHMEM=y
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_ION=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index 70b4d60..74a159e 100755
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -404,6 +404,7 @@
CONFIG_DVB_MPQ_SW=y
CONFIG_QCOM_KGSL=y
CONFIG_DRM=y
+CONFIG_DRM_DP_CEC=y
CONFIG_DRM_SDE_EVTLOG_DEBUG=y
CONFIG_DRM_SDE_RSC=y
CONFIG_DRM_LT_LT9611=y
@@ -499,6 +500,8 @@
CONFIG_UIO=y
CONFIG_UIO_MSM_SHAREDMEM=y
CONFIG_STAGING=y
+CONFIG_STAGING_MEDIA=y
+CONFIG_MEDIA_CEC=y
CONFIG_ASHMEM=y
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
CONFIG_ION=y
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
index 802a4de..e9df352 100644
--- a/arch/s390/kernel/mcount.S
+++ b/arch/s390/kernel/mcount.S
@@ -39,6 +39,7 @@
ENTRY(ftrace_caller)
.globl ftrace_regs_caller
.set ftrace_regs_caller,ftrace_caller
+ stg %r14,(__SF_GPRS+8*8)(%r15) # save traced function caller
lgr %r1,%r15
#ifndef CC_USING_HOTPATCH
aghi %r0,MCOUNT_RETURN_FIXUP
diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h
index ff501e5..b947385 100644
--- a/arch/x86/include/asm/cpu_device_id.h
+++ b/arch/x86/include/asm/cpu_device_id.h
@@ -8,6 +8,33 @@
#include <linux/mod_devicetable.h>
+#define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins)
+
+/**
+ * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching
+ * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY
+ * The name is expanded to X86_VENDOR_@_vendor
+ * @_family: The family number or X86_FAMILY_ANY
+ * @_model: The model number, model constant or X86_MODEL_ANY
+ * @_steppings: Bitmask for steppings, stepping constant or X86_STEPPING_ANY
+ * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY
+ * @_data: Driver specific data or NULL. The internal storage
+ * format is unsigned long. The supplied value, pointer
+ * etc. is casted to unsigned long internally.
+ *
+ * Backport version to keep the SRBDS pile consistant. No shorter variants
+ * required for this.
+ */
+#define X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \
+ _steppings, _feature, _data) { \
+ .vendor = X86_VENDOR_##_vendor, \
+ .family = _family, \
+ .model = _model, \
+ .steppings = _steppings, \
+ .feature = _feature, \
+ .driver_data = (unsigned long) _data \
+}
+
extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match);
#endif
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index fb457ba..2cd5d12 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -316,6 +316,7 @@
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
+#define X86_FEATURE_SRBDS_CTRL (18*32+ 9) /* "" SRBDS mitigation MSR available */
#define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */
#define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */
#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
@@ -346,19 +347,20 @@
*/
#define X86_BUG_ESPFIX X86_BUG(9) /* "" IRET to 16-bit SS corrupts ESP/RSP high bits */
#endif
-#define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */
-#define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */
-#define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */
-#define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */
-#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */
-#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */
-#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
-#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */
-#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
-#define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */
-#define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */
-#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
-#define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */
-#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
+#define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves the base */
+#define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS */
+#define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */
+#define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */
+#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */
+#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */
+#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
+#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */
+#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
+#define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */
+#define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */
+#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
+#define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */
+#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
+#define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
#endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 8d162e0..b12b0a5 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -103,6 +103,10 @@
#define TSX_CTRL_RTM_DISABLE BIT(0) /* Disable RTM feature */
#define TSX_CTRL_CPUID_CLEAR BIT(1) /* Disable TSX enumeration */
+/* SRBDS support */
+#define MSR_IA32_MCU_OPT_CTRL 0x00000123
+#define RNGDS_MITG_DIS BIT(0)
+
#define MSR_IA32_SYSENTER_CS 0x00000174
#define MSR_IA32_SYSENTER_ESP 0x00000175
#define MSR_IA32_SYSENTER_EIP 0x00000176
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 5736306..e638e3b 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -203,6 +203,7 @@
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+/* NOTE: when predicate huge page, consider also pmd_devmap, or use pmd_large */
static inline int pmd_trans_huge(pmd_t pmd)
{
return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 24307d5..5ef0a2b 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -40,6 +40,7 @@
static void __init mds_select_mitigation(void);
static void __init mds_print_mitigation(void);
static void __init taa_select_mitigation(void);
+static void __init srbds_select_mitigation(void);
/* The base value of the SPEC_CTRL MSR that always has to be preserved. */
u64 x86_spec_ctrl_base;
@@ -107,6 +108,7 @@
l1tf_select_mitigation();
mds_select_mitigation();
taa_select_mitigation();
+ srbds_select_mitigation();
/*
* As MDS and TAA mitigations are inter-related, print MDS
@@ -390,6 +392,97 @@
early_param("tsx_async_abort", tsx_async_abort_parse_cmdline);
#undef pr_fmt
+#define pr_fmt(fmt) "SRBDS: " fmt
+
+enum srbds_mitigations {
+ SRBDS_MITIGATION_OFF,
+ SRBDS_MITIGATION_UCODE_NEEDED,
+ SRBDS_MITIGATION_FULL,
+ SRBDS_MITIGATION_TSX_OFF,
+ SRBDS_MITIGATION_HYPERVISOR,
+};
+
+static enum srbds_mitigations srbds_mitigation __ro_after_init = SRBDS_MITIGATION_FULL;
+
+static const char * const srbds_strings[] = {
+ [SRBDS_MITIGATION_OFF] = "Vulnerable",
+ [SRBDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode",
+ [SRBDS_MITIGATION_FULL] = "Mitigation: Microcode",
+ [SRBDS_MITIGATION_TSX_OFF] = "Mitigation: TSX disabled",
+ [SRBDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status",
+};
+
+static bool srbds_off;
+
+void update_srbds_msr(void)
+{
+ u64 mcu_ctrl;
+
+ if (!boot_cpu_has_bug(X86_BUG_SRBDS))
+ return;
+
+ if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
+ return;
+
+ if (srbds_mitigation == SRBDS_MITIGATION_UCODE_NEEDED)
+ return;
+
+ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
+
+ switch (srbds_mitigation) {
+ case SRBDS_MITIGATION_OFF:
+ case SRBDS_MITIGATION_TSX_OFF:
+ mcu_ctrl |= RNGDS_MITG_DIS;
+ break;
+ case SRBDS_MITIGATION_FULL:
+ mcu_ctrl &= ~RNGDS_MITG_DIS;
+ break;
+ default:
+ break;
+ }
+
+ wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
+}
+
+static void __init srbds_select_mitigation(void)
+{
+ u64 ia32_cap;
+
+ if (!boot_cpu_has_bug(X86_BUG_SRBDS))
+ return;
+
+ /*
+ * Check to see if this is one of the MDS_NO systems supporting
+ * TSX that are only exposed to SRBDS when TSX is enabled.
+ */
+ ia32_cap = x86_read_arch_cap_msr();
+ if ((ia32_cap & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM))
+ srbds_mitigation = SRBDS_MITIGATION_TSX_OFF;
+ else if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
+ srbds_mitigation = SRBDS_MITIGATION_HYPERVISOR;
+ else if (!boot_cpu_has(X86_FEATURE_SRBDS_CTRL))
+ srbds_mitigation = SRBDS_MITIGATION_UCODE_NEEDED;
+ else if (cpu_mitigations_off() || srbds_off)
+ srbds_mitigation = SRBDS_MITIGATION_OFF;
+
+ update_srbds_msr();
+ pr_info("%s\n", srbds_strings[srbds_mitigation]);
+}
+
+static int __init srbds_parse_cmdline(char *str)
+{
+ if (!str)
+ return -EINVAL;
+
+ if (!boot_cpu_has_bug(X86_BUG_SRBDS))
+ return 0;
+
+ srbds_off = !strcmp(str, "off");
+ return 0;
+}
+early_param("srbds", srbds_parse_cmdline);
+
+#undef pr_fmt
#define pr_fmt(fmt) "Spectre V1 : " fmt
enum spectre_v1_mitigation {
@@ -1501,6 +1594,11 @@
return "";
}
+static ssize_t srbds_show_state(char *buf)
+{
+ return sprintf(buf, "%s\n", srbds_strings[srbds_mitigation]);
+}
+
static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
char *buf, unsigned int bug)
{
@@ -1542,6 +1640,9 @@
case X86_BUG_ITLB_MULTIHIT:
return itlb_multihit_show_state(buf);
+ case X86_BUG_SRBDS:
+ return srbds_show_state(buf);
+
default:
break;
}
@@ -1588,4 +1689,9 @@
{
return cpu_show_common(dev, attr, buf, X86_BUG_ITLB_MULTIHIT);
}
+
+ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return cpu_show_common(dev, attr, buf, X86_BUG_SRBDS);
+}
#endif
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index f490a4f..b16b617 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -956,9 +956,30 @@
{}
};
-static bool __init cpu_matches(unsigned long which)
+#define VULNBL_INTEL_STEPPINGS(model, steppings, issues) \
+ X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, \
+ INTEL_FAM6_##model, steppings, \
+ X86_FEATURE_ANY, issues)
+
+#define SRBDS BIT(0)
+
+static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
+ VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(HASWELL_CORE, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(HASWELL_ULT, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(HASWELL_GT3E, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(BROADWELL_GT3E, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(BROADWELL_CORE, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(SKYLAKE_MOBILE, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(SKYLAKE_DESKTOP, X86_STEPPING_ANY, SRBDS),
+ VULNBL_INTEL_STEPPINGS(KABYLAKE_MOBILE, X86_STEPPINGS(0x0, 0xC), SRBDS),
+ VULNBL_INTEL_STEPPINGS(KABYLAKE_DESKTOP,X86_STEPPINGS(0x0, 0xD), SRBDS),
+ {}
+};
+
+static bool __init cpu_matches(const struct x86_cpu_id *table, unsigned long which)
{
- const struct x86_cpu_id *m = x86_match_cpu(cpu_vuln_whitelist);
+ const struct x86_cpu_id *m = x86_match_cpu(table);
return m && !!(m->driver_data & which);
}
@@ -978,29 +999,32 @@
u64 ia32_cap = x86_read_arch_cap_msr();
/* Set ITLB_MULTIHIT bug if cpu is not in the whitelist and not mitigated */
- if (!cpu_matches(NO_ITLB_MULTIHIT) && !(ia32_cap & ARCH_CAP_PSCHANGE_MC_NO))
+ if (!cpu_matches(cpu_vuln_whitelist, NO_ITLB_MULTIHIT) &&
+ !(ia32_cap & ARCH_CAP_PSCHANGE_MC_NO))
setup_force_cpu_bug(X86_BUG_ITLB_MULTIHIT);
- if (cpu_matches(NO_SPECULATION))
+ if (cpu_matches(cpu_vuln_whitelist, NO_SPECULATION))
return;
setup_force_cpu_bug(X86_BUG_SPECTRE_V1);
setup_force_cpu_bug(X86_BUG_SPECTRE_V2);
- if (!cpu_matches(NO_SSB) && !(ia32_cap & ARCH_CAP_SSB_NO) &&
+ if (!cpu_matches(cpu_vuln_whitelist, NO_SSB) &&
+ !(ia32_cap & ARCH_CAP_SSB_NO) &&
!cpu_has(c, X86_FEATURE_AMD_SSB_NO))
setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS);
if (ia32_cap & ARCH_CAP_IBRS_ALL)
setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED);
- if (!cpu_matches(NO_MDS) && !(ia32_cap & ARCH_CAP_MDS_NO)) {
+ if (!cpu_matches(cpu_vuln_whitelist, NO_MDS) &&
+ !(ia32_cap & ARCH_CAP_MDS_NO)) {
setup_force_cpu_bug(X86_BUG_MDS);
- if (cpu_matches(MSBDS_ONLY))
+ if (cpu_matches(cpu_vuln_whitelist, MSBDS_ONLY))
setup_force_cpu_bug(X86_BUG_MSBDS_ONLY);
}
- if (!cpu_matches(NO_SWAPGS))
+ if (!cpu_matches(cpu_vuln_whitelist, NO_SWAPGS))
setup_force_cpu_bug(X86_BUG_SWAPGS);
/*
@@ -1018,7 +1042,16 @@
(ia32_cap & ARCH_CAP_TSX_CTRL_MSR)))
setup_force_cpu_bug(X86_BUG_TAA);
- if (cpu_matches(NO_MELTDOWN))
+ /*
+ * SRBDS affects CPUs which support RDRAND or RDSEED and are listed
+ * in the vulnerability blacklist.
+ */
+ if ((cpu_has(c, X86_FEATURE_RDRAND) ||
+ cpu_has(c, X86_FEATURE_RDSEED)) &&
+ cpu_matches(cpu_vuln_blacklist, SRBDS))
+ setup_force_cpu_bug(X86_BUG_SRBDS);
+
+ if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
return;
/* Rogue Data Cache Load? No! */
@@ -1027,7 +1060,7 @@
setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN);
- if (cpu_matches(NO_L1TF))
+ if (cpu_matches(cpu_vuln_whitelist, NO_L1TF))
return;
setup_force_cpu_bug(X86_BUG_L1TF);
@@ -1450,6 +1483,7 @@
mtrr_ap_init();
validate_apic_and_package_id(c);
x86_spec_ctrl_setup_ap();
+ update_srbds_msr();
}
struct msr_range {
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index 4350f50..fdeeab6 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -66,6 +66,7 @@
extern int detect_ht_early(struct cpuinfo_x86 *c);
extern void x86_spec_ctrl_setup_ap(void);
+extern void update_srbds_msr(void);
extern u64 x86_read_arch_cap_msr(void);
diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
index e42117d..f46ffb3 100644
--- a/arch/x86/kernel/cpu/match.c
+++ b/arch/x86/kernel/cpu/match.c
@@ -33,13 +33,18 @@
const struct x86_cpu_id *m;
struct cpuinfo_x86 *c = &boot_cpu_data;
- for (m = match; m->vendor | m->family | m->model | m->feature; m++) {
+ for (m = match;
+ m->vendor | m->family | m->model | m->steppings | m->feature;
+ m++) {
if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
continue;
if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
continue;
if (m->model != X86_MODEL_ANY && c->x86_model != m->model)
continue;
+ if (m->steppings != X86_STEPPING_ANY &&
+ !(BIT(c->x86_stepping) & m->steppings))
+ continue;
if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))
continue;
return m;
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index bef3662..abd4fa5 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -385,7 +385,7 @@
int cpu;
int err;
- if (downed_cpus == NULL &&
+ if (!cpumask_available(downed_cpus) &&
!alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) {
pr_notice("Failed to allocate mask\n");
goto out;
@@ -415,7 +415,7 @@
int cpu;
int err;
- if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0)
+ if (!cpumask_available(downed_cpus) || cpumask_weight(downed_cpus) == 0)
return;
pr_notice("Re-enabling CPUs...\n");
for_each_cpu(cpu, downed_cpus) {
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 7fc1353..0ffd860 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -641,6 +641,12 @@
return sprintf(buf, "Not affected\n");
}
+ssize_t __weak cpu_show_srbds(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "Not affected\n");
+}
+
static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
@@ -649,6 +655,7 @@
static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL);
static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL);
static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL);
+static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL);
static struct attribute *cpu_root_vulnerabilities_attrs[] = {
&dev_attr_meltdown.attr,
@@ -659,6 +666,7 @@
&dev_attr_mds.attr,
&dev_attr_tsx_async_abort.attr,
&dev_attr_itlb_multihit.attr,
+ &dev_attr_srbds.attr,
NULL
};
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 4335ad4..149d573 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2020, 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
@@ -202,7 +202,7 @@
}
memcpy(buf, &ctrl_pkt, header_len);
- if (mask_size > 0 && mask_size <= LOG_MASK_SIZE)
+ if (mask_size > 0)
memcpy(buf + header_len, mask->ptr, mask_size);
mutex_unlock(&mask->lock);
@@ -304,7 +304,7 @@
buf = temp;
}
}
- if (num_bytes > 0 && num_bytes < mask_info->mask_len)
+ if (num_bytes > 0)
memcpy(buf + sizeof(header), mask_info->ptr, num_bytes);
else {
pr_err("diag: num_bytes(%d) is not satisfying length condition\n",
diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/drm_dp_cec.c
index ddb1c5a..f40b24c 100644
--- a/drivers/gpu/drm/drm_dp_cec.c
+++ b/drivers/gpu/drm/drm_dp_cec.c
@@ -289,7 +289,7 @@
*/
void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
{
- u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD;
+ u32 cec_caps = CEC_CAP_DEFAULTS;
unsigned int num_las = 1;
u8 cap;
@@ -335,12 +335,12 @@
/* Create a new adapter */
aux->cec.adap = cec_allocate_adapter(&drm_dp_cec_adap_ops,
aux, aux->cec.name, cec_caps,
- num_las);
+ num_las, aux->cec.parent);
if (IS_ERR(aux->cec.adap)) {
aux->cec.adap = NULL;
goto unlock;
}
- if (cec_register_adapter(aux->cec.adap, aux->cec.parent)) {
+ if (cec_register_adapter(aux->cec.adap)) {
cec_delete_adapter(aux->cec.adap);
aux->cec.adap = NULL;
} else {
@@ -403,7 +403,10 @@
void drm_dp_cec_register_connector(struct drm_dp_aux *aux, const char *name,
struct device *parent)
{
- WARN_ON(aux->cec.adap);
+ if (aux->cec.adap) {
+ WARN_ON(aux->cec.adap);
+ return;
+ }
aux->cec.name = name;
aux->cec.parent = parent;
INIT_DELAYED_WORK(&aux->cec.unregister_work,
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index dde0623..8164c6f 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1080,3 +1080,38 @@
EXPORT_SYMBOL(drm_dp_psr_setup_time);
#undef PSR_SETUP_TIME
+
+/**
+ * drm_dp_read_desc - read sink/branch descriptor from DPCD
+ * @aux: DisplayPort AUX channel
+ * @desc: Device decriptor to fill from DPCD
+ * @is_branch: true for branch devices, false for sink devices
+ *
+ * Read DPCD 0x400 (sink) or 0x500 (branch) into @desc. Also debug log the
+ * identification.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc,
+ bool is_branch)
+{
+ struct drm_dp_dpcd_ident *ident = &desc->ident;
+ unsigned int offset = is_branch ? DP_BRANCH_OUI : DP_SINK_OUI;
+ int ret, dev_id_len;
+
+ ret = drm_dp_dpcd_read(aux, offset, ident, sizeof(*ident));
+ if (ret < 0)
+ return ret;
+
+ dev_id_len = strnlen(ident->device_id, sizeof(ident->device_id));
+
+ DRM_DEBUG_KMS("DP %s: OUI %*phD dev-ID %*pE HW-rev %d.%d SW-rev %d.%d\n",
+ is_branch ? "branch" : "sink",
+ (int)sizeof(ident->oui), ident->oui,
+ dev_id_len, ident->device_id,
+ ident->hw_rev >> 4, ident->hw_rev & 0xf,
+ ident->sw_major_rev, ident->sw_minor_rev);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_dp_read_desc);
diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index 8952fc9..e60131b 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, 2020, 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
@@ -608,6 +608,8 @@
aux->catalog->enable(aux->catalog, true);
atomic_set(&aux->aborted, 0);
aux->retry_cnt = 0;
+
+ drm_dp_cec_register_connector(&aux->drm_aux, "sde_dp_cec", aux->dev);
}
static void dp_aux_deinit(struct dp_aux *dp_aux)
@@ -623,6 +625,7 @@
atomic_set(&aux->aborted, 1);
aux->catalog->enable(aux->catalog, false);
+ drm_dp_cec_unregister_connector(&aux->drm_aux);
}
static int dp_aux_register(struct dp_aux *dp_aux)
diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c
index 05629dd..a188cfa 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, 2020, 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
@@ -790,6 +790,8 @@
pr_debug("device service irq vector = 0x%x\n", data);
+ drm_dp_cec_irq(link->aux->drm_aux);
+
if (!(data & DP_AUTOMATED_TEST_REQUEST)) {
pr_debug("no test requested\n");
return 0;
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c b/drivers/gpu/drm/msm/dp/dp_panel.c
index 5379823..7e6c44a 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -458,6 +458,7 @@
struct drm_connector *connector, struct dp_display_mode *mode)
{
struct dp_panel_private *panel;
+ int rc = 0;
if (!dp_panel) {
pr_err("invalid input\n");
@@ -470,12 +471,18 @@
dp_panel_set_test_mode(panel, mode);
return 1;
} else if (dp_panel->edid_ctrl->edid) {
- return _sde_edid_update_modes(connector, dp_panel->edid_ctrl);
+ rc = _sde_edid_update_modes(connector, dp_panel->edid_ctrl);
} else { /* fail-safe mode */
memcpy(&mode->timing, &fail_safe,
sizeof(fail_safe));
return 1;
}
+
+ if (rc)
+ drm_dp_cec_set_edid(panel->aux->drm_aux,
+ dp_panel->edid_ctrl->edid);
+
+ return rc;
}
static void dp_panel_handle_sink_request(struct dp_panel *dp_panel)
@@ -762,6 +769,7 @@
panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
hdr = &panel->catalog->hdr_data;
+ drm_dp_cec_unset_edid(panel->aux->drm_aux);
if (!panel->custom_edid)
sde_free_edid((void **)&dp_panel->edid_ctrl);
diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
index 9505237..681ac9b 100644
--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
+++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
@@ -381,6 +381,14 @@
},
.driver_data = (void *)&sipodev_desc
},
+ {
+ .ident = "Schneider SCL142ALM",
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SCHNEIDER"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SCL142ALM"),
+ },
+ .driver_data = (void *)&sipodev_desc
+ },
{ } /* Terminate list */
};
diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
index 360b6e9..5a3a532 100644
--- a/drivers/iio/light/vcnl4000.c
+++ b/drivers/iio/light/vcnl4000.c
@@ -61,7 +61,6 @@
u8 rdy_mask, u8 data_reg, int *val)
{
int tries = 20;
- __be16 buf;
int ret;
mutex_lock(&data->lock);
@@ -88,13 +87,12 @@
goto fail;
}
- ret = i2c_smbus_read_i2c_block_data(data->client,
- data_reg, sizeof(buf), (u8 *) &buf);
+ ret = i2c_smbus_read_word_swapped(data->client, data_reg);
if (ret < 0)
goto fail;
mutex_unlock(&data->lock);
- *val = be16_to_cpu(buf);
+ *val = ret;
return 0;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 7a0a069..ed71208 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 2020, 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
@@ -783,7 +783,12 @@
state = buf_info->state;
if (BUF_SRC(bufq->stream_id) == MSM_ISP_BUFFER_SRC_HAL) {
+#ifdef CONFIG_MSM_ISP_V1
+ if (state == MSM_ISP_BUFFER_STATE_DEQUEUED ||
+ state == MSM_ISP_BUFFER_STATE_DIVERTED) {
+#else
if (state == MSM_ISP_BUFFER_STATE_DEQUEUED) {
+#endif
buf_info->state = MSM_ISP_BUFFER_STATE_DISPATCHED;
spin_unlock_irqrestore(&bufq->bufq_lock, flags);
buf_mgr->vb2_ops->buf_done(buf_info->vb2_v4l2_buf,
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 7671049..9e8d1c5 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -5271,6 +5271,58 @@
return retval;
}
+/**************************************************************************
+ * File Operations Interface
+ **************************************************************************
+ *
+ * iris_fops_read - read event data
+ */
+static ssize_t iris_fops_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct iris_device *radio = video_get_drvdata(video_devdata(file));
+ enum iris_buf_t buf_type = -1;
+ unsigned char buf_fifo[STD_BUF_SIZE] = {0};
+ struct kfifo *data_fifo = NULL;
+ unsigned char *buf = NULL;
+ unsigned int len = 0, retval = -1;
+ u32 bytesused = 0;
+
+ FMDBG("buffer %pK", buffer);
+
+ if ((radio == NULL) || (buffer == NULL)) {
+ FMDERR("radio/buffer is NULL\n");
+ return -ENXIO;
+ }
+ buf_type = count;
+ len = STD_BUF_SIZE;
+
+ if ((buf_type < IRIS_BUF_MAX) && (buf_type >= 0)) {
+ data_fifo = &radio->data_buf[buf_type];
+ if (buf_type == IRIS_BUF_EVENTS)
+ if (wait_event_interruptible(radio->event_queue,
+ kfifo_len(data_fifo)) < 0)
+ return -EINTR;
+ } else {
+ FMDERR("invalid buffer type\n");
+ return -EINVAL;
+ }
+ if (len <= STD_BUF_SIZE) {
+ bytesused = kfifo_out_locked(data_fifo, &buf_fifo[0],
+ len, &radio->buf_lock[buf_type]);
+ } else {
+ FMDERR("kfifo_out_locked can not use len more than 128\n");
+ return -EINVAL;
+ }
+ retval = copy_to_user(buffer, &buf_fifo[0], bytesused);
+ if (retval > 0) {
+ FMDERR("Failed to copy %d bytes of data\n", retval);
+ return -EAGAIN;
+ }
+ retval = bytesused;
+ return retval;
+}
+
static int iris_vidioc_dqbuf(struct file *file, void *priv,
struct v4l2_buffer *buffer)
{
@@ -5365,7 +5417,9 @@
strlcpy(radio->g_cap.card, DRIVER_CARD, sizeof(radio->g_cap.card));
radio->g_cap.capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
- capability->capabilities = radio->g_cap.capabilities;
+ capability->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ capability->capabilities = capability->device_caps |
+ V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -5475,6 +5529,7 @@
static const struct v4l2_file_operations iris_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = video_ioctl2,
+ .read = iris_fops_read,
#ifdef CONFIG_COMPAT
.compat_ioctl32 = v4l2_compat_ioctl32,
#endif
@@ -5524,6 +5579,7 @@
sizeof(iris_viddev_template));
strlcpy(radio->v4l2_dev.name, DRIVER_NAME,
sizeof(radio->v4l2_dev.name));
+ radio->videodev->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
retval = v4l2_device_register(NULL, &radio->v4l2_dev);
if (retval)
return -EINVAL;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 2a88ae0..d173fc7 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1720,8 +1720,8 @@
if ((req.ifd_data_fd <= 0) || (req.virt_sb_base == NULL) ||
(req.sb_len == 0)) {
- pr_err("Inavlid input(s)ion_fd(%d), sb_len(%d), vaddr(0x%pK)\n",
- req.ifd_data_fd, req.sb_len, req.virt_sb_base);
+ pr_err("Invalid input(s)ion_fd(%d), sb_len(%d)\n",
+ req.ifd_data_fd, req.sb_len);
return -EFAULT;
}
if (!access_ok(VERIFY_WRITE, (void __user *)req.virt_sb_base,
diff --git a/drivers/misc/vxr7200.c b/drivers/misc/vxr7200.c
index 7388ade..21d54b4 100644
--- a/drivers/misc/vxr7200.c
+++ b/drivers/misc/vxr7200.c
@@ -29,6 +29,12 @@
#include <linux/regulator/consumer.h>
#include <linux/rwlock.h>
#include <linux/leds.h>
+#include "vxr7200.h"
+
+enum power_state {
+ POWER_STATE_POWERKEY = 0,
+ POWER_STATE_ENABLE = 1,
+};
struct vxr7200 {
struct device *dev;
@@ -43,7 +49,6 @@
u32 display_1v8_en;
u32 mipi_switch_1v8_en;
u32 display_res1;
- bool gpioInit;
struct i2c_client *i2c_client;
@@ -52,9 +57,13 @@
struct regulator *ibb;
bool power_on;
+ bool enable;
+ bool usb_plugged;
+ enum power_state state;
};
static bool dsi_way;
+static struct vxr7200 *pdata;
static int vxr7200_read(struct vxr7200 *pdata, u8 *reg, u8 *buf, u32 size)
{
@@ -75,107 +84,123 @@
};
if (i2c_transfer(client->adapter, msg, 2) != 2) {
- pr_err("i2c read failed\n");
+ pr_err("%s i2c read failed\n", __func__);
return -EIO;
}
return 0;
}
-static int turnGpio(struct vxr7200 *pdata, int gpio, char *name, bool on)
+static void turn_gpio(struct vxr7200 *pdata, int gpio, bool on)
{
- int ret = -1;
- pr_info("%s vxr7200 gpio:%d, name:%s, on:%d\n", __func__, gpio,
- name, on);
- if (!pdata->gpioInit) {
- ret = gpio_request(gpio, name);
- if (ret) {
- pr_err("vxr7200 %s gpio request failed\n", name);
- goto error;
- }
- }
+ pr_debug("%s vxr7200_turn_gpio gpio:%d, on:%d\n", __func__, gpio, on);
+
if (on) {
- ret = gpio_direction_output(gpio, 0);
- if (ret) {
- pr_err("vxr7200 gpio direction failed\n");
- goto error;
- }
+ gpio_direction_output(gpio, 0);
gpio_set_value(gpio, 1);
- msleep(20);
pr_debug("%s vxr7200 gpio:%d set to high\n", __func__, gpio);
} else {
- ret = gpio_direction_output(gpio, 1);
- if (ret) {
- pr_err("vxr7200 gpio direction failed\n");
- goto error;
- }
+ gpio_direction_output(gpio, 1);
gpio_set_value(gpio, 0);
- msleep(20);
pr_debug("%s vxr7200 gpio:%d set to low\n", __func__, gpio);
}
- return 0;
-error:
- return -EINVAL;
}
-static void vxr7200_set_gpios(struct vxr7200 *pdata, bool turnOn)
+static void vxr7200_set_gpios(struct vxr7200 *pdata, bool turn_on)
{
- int rc;
-
- pr_debug("%s, turnOn:%d\n", __func__, turnOn);
+ pr_debug("%s, turn_on:%d\n", __func__, turn_on);
if (pdata) {
- rc = turnGpio(pdata, pdata->vxr_3v3_en, "vxr_3v3_en", turnOn);
- if (rc)
- goto gpio1Fail;
-
- rc = turnGpio(pdata, pdata->display_res1,
- "display_res1", turnOn);
- if (rc)
- goto gpio2Fail;
-
- rc = turnGpio(pdata, pdata->display_1v8_en,
- "disp_1v8_en", turnOn);
- if (rc)
- goto gpio3Fail;
-
- rc = turnGpio(pdata, pdata->mipi_switch_1v8_en,
- "mipi_switch_1v8_en", turnOn);
- if (rc)
- goto gpio4Fail;
-
- rc = turnGpio(pdata, pdata->led_5v_en, "led_5v_en", turnOn);
- if (rc)
- goto gpio5Fail;
-
- rc = turnGpio(pdata, pdata->led_drive_en1,
- "led_drive_en1", turnOn);
- if (rc)
- goto gpio6Fail;
-
- rc = turnGpio(pdata, pdata->led_drive_en2,
- "led_drive_en2", turnOn);
- if (rc)
- goto gpio7Fail;
+ if (pdata->state == POWER_STATE_POWERKEY) {
+ turn_gpio(pdata, pdata->vxr_3v3_en, turn_on);
+ turn_gpio(pdata, pdata->display_res1, turn_on);
+ turn_gpio(pdata, pdata->display_1v8_en, turn_on);
+ turn_gpio(pdata, pdata->mipi_switch_1v8_en, turn_on);
+ if (!pdata->enable && turn_on)
+ return;
+ }
+ turn_gpio(pdata, pdata->led_5v_en, turn_on);
+ turn_gpio(pdata, pdata->led_drive_en1, turn_on);
+ turn_gpio(pdata, pdata->led_drive_en2, turn_on);
}
return;
-
-gpio7Fail:
- gpio_free(pdata->led_drive_en2);
-gpio6Fail:
- gpio_free(pdata->led_drive_en1);
-gpio5Fail:
- gpio_free(pdata->led_5v_en);
-gpio4Fail:
- gpio_free(pdata->mipi_switch_1v8_en);
-gpio3Fail:
- gpio_free(pdata->display_1v8_en);
-gpio2Fail:
- gpio_free(pdata->display_res1);
-gpio1Fail:
- gpio_free(pdata->vxr_3v3_en);
}
+static ssize_t vxr7200_enable_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int ret;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct vxr7200 *pdata = i2c_get_clientdata(client);
+
+
+ if (pdata->enable)
+ ret = scnprintf(buf, PAGE_SIZE, "display on\n");
+ else
+ ret = scnprintf(buf, PAGE_SIZE, "display off\n");
+
+ return ret;
+}
+
+static ssize_t vxr7200_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct vxr7200 *pdata = i2c_get_clientdata(client);
+ long val;
+ int ret;
+
+ ret = kstrtol(buf, 0, &val);
+ pr_debug("%s, count:%d val:%lx, buf:%s\n",
+ __func__, (int)count, val, buf);
+
+ if (val == 0x1) {
+ pr_debug("%s Turning on Display\n", __func__);
+ pdata->enable = true;
+ pdata->state = POWER_STATE_ENABLE;
+ vxr7200_set_gpios(pdata, true);
+ } else if (val == 0x0) {
+ pr_debug("%s Turning off Display\n",
+ __func__);
+ pdata->state = POWER_STATE_ENABLE;
+ pdata->enable = false;
+ vxr7200_set_gpios(pdata, false);
+ } else
+ pr_err("%s Invalid value. Valid vals(1-on,0-off)\n",
+ __func__);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(vxr7200_enable);
+
+static struct attribute *vxr7200_fs_attrs[] = {
+ &dev_attr_vxr7200_enable.attr,
+ NULL
+};
+
+static struct attribute_group vxr7200_fs_attr_group = {
+ .attrs = vxr7200_fs_attrs,
+};
+
+void vxr7200_usb_event(bool cable_plug)
+{
+ pr_debug("%s, cable_plug:%d\n", __func__, cable_plug);
+ if (pdata) {
+ pdata->state = POWER_STATE_POWERKEY;
+ if (cable_plug) {
+ pdata->usb_plugged = true;
+ vxr7200_set_gpios(pdata, true);
+ } else {
+ pdata->usb_plugged = false;
+ vxr7200_set_gpios(pdata, false);
+ }
+ }
+}
+EXPORT_SYMBOL(vxr7200_usb_event);
+
static int vxr7200_parse_dt(struct device *dev,
struct vxr7200 *pdata)
{
@@ -185,57 +210,102 @@
pdata->vxr_3v3_en =
of_get_named_gpio(np, "qcom,vxr_3v3_en", 0);
if (!gpio_is_valid(pdata->vxr_3v3_en)) {
- pr_err("vxr_3v3_en gpio not specified\n");
+ pr_err("vxr7200_3v3_en gpio not specified\n");
rc = -EINVAL;
}
+ if (gpio_request(pdata->vxr_3v3_en, "vxr_3v3_en")) {
+ pr_err("vxr7200_3v3_en request gpio failed\n");
+ rc = -EINVAL;
+ goto gpio1Fail;
+ }
pdata->led_5v_en =
of_get_named_gpio(np, "qcom,led-5v-en-gpio", 0);
if (!gpio_is_valid(pdata->led_5v_en)) {
- pr_err("led_5v_en gpio not specified\n");
+ pr_err("vxr7200_led_5v_en gpio not specified\n");
rc = -EINVAL;
}
+ if (gpio_request(pdata->led_5v_en, "led_5v_en")) {
+ pr_err("vxr7200_led_5v_en request gpio failed\n");
+ rc = -EINVAL;
+ goto gpio2Fail;
+ }
pdata->led_drive_en1 =
of_get_named_gpio(np, "qcom,led-driver-en1-gpio", 0);
if (!gpio_is_valid(pdata->led_drive_en1)) {
- pr_err("led_drive_en1 gpio not specified\n");
+ pr_err("vxr7200_led_drive_en1 gpio not specified\n");
rc = -EINVAL;
}
+ if (gpio_request(pdata->led_drive_en1, "led_drive_en1")) {
+ pr_err("vxr7200_led_drive_en1 request gpio failed\n");
+ rc = -EINVAL;
+ goto gpio3Fail;
+ }
pdata->led_drive_en2 =
of_get_named_gpio(np, "qcom,led-driver-en2-gpio", 0);
if (!gpio_is_valid(pdata->led_drive_en2)) {
- pr_err("led_drive_en2 gpio not specified\n");
+ pr_err("vxr7200_led_drive_en2 gpio not specified\n");
rc = -EINVAL;
}
+ if (gpio_request(pdata->led_drive_en2, "led_drive_en2")) {
+ pr_err("vxr7200_led_drive_en2 request gpio failed\n");
+ rc = -EINVAL;
+ goto gpio4Fail;
+ }
pdata->display_1v8_en =
of_get_named_gpio(np, "qcom,1p8-en-gpio", 0);
if (!gpio_is_valid(pdata->display_1v8_en)) {
- pr_err("display_1v8_en gpio not specified\n");
+ pr_err("vxr7200_display_1v8_en gpio not specified\n");
rc = -EINVAL;
}
+ if (gpio_request(pdata->display_1v8_en, "display_1v8_en")) {
+ pr_err("vxr7200_display_1v8_en request gpio failed\n");
+ rc = -EINVAL;
+ goto gpio5Fail;
+ }
pdata->mipi_switch_1v8_en =
of_get_named_gpio(np, "qcom,switch-power-gpio", 0);
if (!gpio_is_valid(pdata->mipi_switch_1v8_en)) {
- pr_err("mipi_switch_1v8_en gpio not specified\n");
+ pr_err("vxr7200_mipi_switch_1v8_en gpio not specified\n");
rc = -EINVAL;
}
+ if (gpio_request(pdata->mipi_switch_1v8_en, "mipi_switch_1v8_en")) {
+ pr_err("vxr7200_mipi_switch_1v8_en request gpio failed\n");
+ rc = -EINVAL;
+ goto gpio6Fail;
+ }
pdata->display_res1 =
of_get_named_gpio(np, "qcom,platform-reset-gpio", 0);
if (!gpio_is_valid(pdata->display_res1)) {
- pr_err("display_res1 gpio not specified\n");
+ pr_err("vxr7200_display_res1 gpio not specified\n");
rc = -EINVAL;
}
+ if (gpio_request(pdata->display_res1, "display_res1")) {
+ pr_err("vxr7200_display_res1 request gpio failed\n");
+ rc = -EINVAL;
+ goto gpio7Fail;
+ }
+ return rc;
- if (!rc)
- vxr7200_set_gpios(pdata, true);
-
- if (!pdata->gpioInit)
- pdata->gpioInit = true;
+gpio7Fail:
+ gpio_free(pdata->display_res1);
+gpio6Fail:
+ gpio_free(pdata->mipi_switch_1v8_en);
+gpio5Fail:
+ gpio_free(pdata->display_1v8_en);
+gpio4Fail:
+ gpio_free(pdata->led_drive_en2);
+gpio3Fail:
+ gpio_free(pdata->led_drive_en1);
+gpio2Fail:
+ gpio_free(pdata->led_5v_en);
+gpio1Fail:
+ gpio_free(pdata->vxr_3v3_en);
return rc;
}
@@ -319,7 +389,6 @@
const struct i2c_device_id *id)
{
int rc;
- struct vxr7200 *pdata;
u8 reg[4] = {0x00, 0x20, 0x01, 0x60};
u8 buf[4] = {0x00, 0x0, 0x0, 0x0};
@@ -341,7 +410,8 @@
if (!pdata)
return -ENOMEM;
- pdata->gpioInit = false;
+ pdata->state = POWER_STATE_POWERKEY;
+ pdata->enable = true;
rc = vxr7200_parse_dt(&client->dev, pdata);
if (rc) {
@@ -351,6 +421,14 @@
pdata->dev = &client->dev;
pdata->i2c_client = client;
+ rc = sysfs_create_group(&pdata->dev->kobj, &vxr7200_fs_attr_group);
+ if (rc) {
+ pr_err("%s unable to register vxr7200 sysfs nodes\n",
+ __func__);
+ goto err_dt_parse;
+ }
+
+
vxr7200_display_pwr_enable_vregs(pdata);
i2c_set_clientdata(client, pdata);
@@ -359,6 +437,8 @@
//vxr7200_write(pdata, 0x0A, 0x02);//Enable 4-lane DP
vxr7200_read(pdata, reg, buf, 4);//Enable 4-lane DP
+ return rc;
+
err_dt_parse:
devm_kfree(&client->dev, pdata);
@@ -369,8 +449,10 @@
{
struct vxr7200 *pdata = i2c_get_clientdata(client);
- if (pdata)
+ if (pdata) {
+ sysfs_remove_group(&pdata->dev->kobj, &vxr7200_fs_attr_group);
devm_kfree(&client->dev, pdata);
+ }
return 0;
}
@@ -380,30 +462,13 @@
dev_info(&(client->dev), "shutdown");
}
-static int vxr7200_pm_freeze(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct vxr7200 *pdata = i2c_get_clientdata(client);
-
- dev_info(dev, "freeze");
- vxr7200_set_gpios(pdata, false);
- return 0;
-}
-static int vxr7200_pm_restore(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct vxr7200 *pdata = i2c_get_clientdata(client);
-
- dev_info(dev, "restore");
- vxr7200_set_gpios(pdata, true);
- return 0;
-}
static int vxr7200_pm_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct vxr7200 *pdata = i2c_get_clientdata(client);
dev_info(dev, "suspend");
+ pdata->state = POWER_STATE_POWERKEY;
vxr7200_set_gpios(pdata, false);
return 0;
}
@@ -414,6 +479,7 @@
struct vxr7200 *pdata = i2c_get_clientdata(client);
dev_info(dev, "resume");
+ pdata->state = POWER_STATE_POWERKEY;
vxr7200_set_gpios(pdata, true);
return 0;
}
@@ -421,10 +487,7 @@
static const struct dev_pm_ops vxr7200_dev_pm_ops = {
.suspend = vxr7200_pm_suspend,
.resume = vxr7200_pm_resume,
- .freeze = vxr7200_pm_freeze,
- .restore = vxr7200_pm_restore,
- .thaw = vxr7200_pm_restore,
- .poweroff = vxr7200_pm_suspend,
+ .poweroff = vxr7200_pm_suspend,
};
static const struct i2c_device_id vxr7200_id_table[] = {
diff --git a/drivers/misc/vxr7200.h b/drivers/misc/vxr7200.h
new file mode 100644
index 0000000..35987fe
--- /dev/null
+++ b/drivers/misc/vxr7200.h
@@ -0,0 +1,18 @@
+/* Copyright (c) 2020 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 __VXR7200_H_
+#define __VXR7200_H_
+
+void vxr7200_usb_event(bool usb_plug);
+
+#endif /* __VXR7200_H_ */
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index d0435c7..9c938f9 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -618,10 +618,9 @@
sl->tty = NULL;
tty->disc_data = NULL;
clear_bit(SLF_INUSE, &sl->flags);
- slc_free_netdev(sl->dev);
/* do not call free_netdev before rtnl_unlock */
rtnl_unlock();
- free_netdev(sl->dev);
+ slc_free_netdev(sl->dev);
return err;
err_exit:
diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c
index a65d7a6..ffa7e7e 100644
--- a/drivers/net/ethernet/apple/bmac.c
+++ b/drivers/net/ethernet/apple/bmac.c
@@ -1187,7 +1187,7 @@
int i;
unsigned short data;
- for (i = 0; i < 6; i++)
+ for (i = 0; i < 3; i++)
{
reset_and_select_srom(dev);
data = read_srom(dev, i + EnetAddressOffset/2, SROMAddressBits);
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 7145930..af922ba 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -45,6 +45,7 @@
#include <soc/fsl/qe/ucc.h>
#include <soc/fsl/qe/ucc_fast.h>
#include <asm/machdep.h>
+#include <net/sch_generic.h>
#include "ucc_geth.h"
@@ -1551,11 +1552,8 @@
static void ugeth_quiesce(struct ucc_geth_private *ugeth)
{
- /* Prevent any further xmits, plus detach the device. */
- netif_device_detach(ugeth->ndev);
-
- /* Wait for any current xmits to finish. */
- netif_tx_disable(ugeth->ndev);
+ /* Prevent any further xmits */
+ netif_tx_stop_all_queues(ugeth->ndev);
/* Disable the interrupt to avoid NAPI rescheduling. */
disable_irq(ugeth->ug_info->uf_info.irq);
@@ -1568,7 +1566,10 @@
{
napi_enable(&ugeth->napi);
enable_irq(ugeth->ug_info->uf_info.irq);
- netif_device_attach(ugeth->ndev);
+
+ /* allow to xmit again */
+ netif_tx_wake_all_queues(ugeth->ndev);
+ __netdev_watchdog_up(ugeth->ndev);
}
/* Called every time the controller might need to be made
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 4143659..264136d 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -2506,20 +2506,20 @@
retval = smsc911x_init(dev);
if (retval < 0)
- goto out_disable_resources;
+ goto out_init_fail;
netif_carrier_off(dev);
retval = smsc911x_mii_init(pdev, dev);
if (retval) {
SMSC_WARN(pdata, probe, "Error %i initialising mii", retval);
- goto out_disable_resources;
+ goto out_init_fail;
}
retval = register_netdev(dev);
if (retval) {
SMSC_WARN(pdata, probe, "Error %i registering device", retval);
- goto out_disable_resources;
+ goto out_init_fail;
} else {
SMSC_TRACE(pdata, probe,
"Network interface: \"%s\"", dev->name);
@@ -2560,9 +2560,10 @@
return 0;
-out_disable_resources:
+out_init_fail:
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+out_disable_resources:
(void)smsc911x_disable_resources(pdev);
out_enable_resources_fail:
smsc911x_free_resources(pdev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
index 11a4a81b..bcc5d1e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
@@ -330,6 +330,19 @@
/* Enable PTP clock */
regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
+ switch (gmac->phy_mode) {
+ case PHY_INTERFACE_MODE_RGMII:
+ val |= NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
+ NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ val |= NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
+ NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
+ break;
+ default:
+ /* We don't get here; the switch above will have errored out */
+ unreachable();
+ }
regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index fa8f7c4..804c52c 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -494,6 +494,9 @@
if (!skb)
goto out;
+ if (skb->pkt_type != PACKET_HOST)
+ goto abort;
+
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
goto abort;
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index cc84112..f870396 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -867,7 +867,10 @@
sl->tty = NULL;
tty->disc_data = NULL;
clear_bit(SLF_INUSE, &sl->flags);
+ /* do not call free_netdev before rtnl_unlock */
+ rtnl_unlock();
sl_free_netdev(sl->dev);
+ return err;
err_exit:
rtnl_unlock();
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 5755eec..9a87361 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -921,6 +921,7 @@
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
+ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */
diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c
index a8d4700..ea609dc7 100644
--- a/drivers/net/wireless/cisco/airo.c
+++ b/drivers/net/wireless/cisco/airo.c
@@ -1928,6 +1928,10 @@
airo_print_err(dev->name, "%s: skb == NULL!",__func__);
return NETDEV_TX_OK;
}
+ if (skb_padto(skb, ETH_ZLEN)) {
+ dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
+ }
npacks = skb_queue_len (&ai->txq);
if (npacks >= MAXTXQ - 1) {
@@ -2130,6 +2134,10 @@
airo_print_err(dev->name, "%s: skb == NULL!", __func__);
return NETDEV_TX_OK;
}
+ if (skb_padto(skb, ETH_ZLEN)) {
+ dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
+ }
/* Find a vacant FID */
for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
@@ -2204,6 +2212,10 @@
airo_print_err(dev->name, "%s: skb == NULL!", __func__);
return NETDEV_TX_OK;
}
+ if (skb_padto(skb, ETH_ZLEN)) {
+ dev->stats.tx_dropped++;
+ return NETDEV_TX_OK;
+ }
/* Find a vacant FID */
for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
diff --git a/drivers/net/wireless/intersil/p54/p54usb.c b/drivers/net/wireless/intersil/p54/p54usb.c
index 4a197a3..979fcef 100644
--- a/drivers/net/wireless/intersil/p54/p54usb.c
+++ b/drivers/net/wireless/intersil/p54/p54usb.c
@@ -64,6 +64,7 @@
{USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */
{USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */
{USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
+ {USB_DEVICE(0x124a, 0x4026)}, /* AirVasT USB wireless device */
{USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */
{USB_DEVICE(0x15a9, 0x0002)}, /* Gemtek WUBI-100GW 802.11g */
{USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */
diff --git a/drivers/nfc/st21nfca/dep.c b/drivers/nfc/st21nfca/dep.c
index 2062852..6338492 100644
--- a/drivers/nfc/st21nfca/dep.c
+++ b/drivers/nfc/st21nfca/dep.c
@@ -184,8 +184,10 @@
memcpy(atr_res->gbi, atr_req->gbi, gb_len);
r = nfc_set_remote_general_bytes(hdev->ndev, atr_res->gbi,
gb_len);
- if (r < 0)
+ if (r < 0) {
+ kfree_skb(skb);
return r;
+ }
}
info->dep_info.curr_nfc_dep_pni = 0;
diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
index c25d7dc..54be83a 100644
--- a/drivers/nvmem/qfprom.c
+++ b/drivers/nvmem/qfprom.c
@@ -30,19 +30,6 @@
return 0;
}
-static int qfprom_reg_write(void *context,
- unsigned int reg, void *_val, size_t bytes)
-{
- void __iomem *base = context;
- u32 *val = _val;
- int i = 0, words = bytes / 4;
-
- while (words--)
- writel(*val++, base + reg + (i++ * 4));
-
- return 0;
-}
-
static int qfprom_remove(struct platform_device *pdev)
{
struct nvmem_device *nvmem = platform_get_drvdata(pdev);
@@ -56,7 +43,6 @@
.stride = 4,
.word_size = 1,
.reg_read = qfprom_reg_read,
- .reg_write = qfprom_reg_write,
};
static int qfprom_probe(struct platform_device *pdev)
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 1fab25f..bd96095 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -4951,13 +4951,45 @@
{
}
+static void msm_mask_msi_irq(struct irq_data *data)
+{
+ struct msi_desc *desc = irq_data_get_msi_desc(data);
+ struct pci_dev *pdev;
+ struct msm_pcie_dev_t *pcie_dev;
+ void __iomem *intr_en_addr;
+ uint32_t offset = 0;
+
+ pdev = msi_desc_to_pci_dev(desc);
+ pcie_dev = PCIE_BUS_PRIV_DATA(pdev->bus);
+ offset = data->irq - desc->irq;
+ intr_en_addr = pcie_dev->dm_core + PCIE20_MSI_CTRL_INTR_EN;
+ msm_pcie_write_mask(intr_en_addr, BIT(offset), 0);
+ pci_msi_mask_irq(data);
+}
+
+static void msm_unmask_msi_irq(struct irq_data *data)
+{
+ struct msi_desc *desc = irq_data_get_msi_desc(data);
+ struct pci_dev *pdev;
+ struct msm_pcie_dev_t *pcie_dev;
+ void __iomem *intr_en_addr;
+ uint32_t offset = 0;
+
+ pci_msi_unmask_irq(data);
+ pdev = msi_desc_to_pci_dev(desc);
+ pcie_dev = PCIE_BUS_PRIV_DATA(pdev->bus);
+ offset = data->irq - desc->irq;
+ intr_en_addr = pcie_dev->dm_core + PCIE20_MSI_CTRL_INTR_EN;
+ msm_pcie_write_mask(intr_en_addr, 0, BIT(offset));
+}
+
static struct irq_chip pcie_msi_chip = {
.name = "msm-pcie-msi",
.irq_ack = msm_pcie_msi_nop,
- .irq_enable = unmask_msi_irq,
- .irq_disable = mask_msi_irq,
- .irq_mask = mask_msi_irq,
- .irq_unmask = unmask_msi_irq,
+ .irq_enable = msm_unmask_msi_irq,
+ .irq_disable = msm_mask_msi_irq,
+ .irq_mask = msm_mask_msi_irq,
+ .irq_unmask = msm_unmask_msi_irq,
};
static int msm_pcie_create_irq(struct msm_pcie_dev_t *dev)
diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_com.h b/drivers/platform/msm/ep_pcie/ep_pcie_com.h
index 38e6f49..710c180 100644
--- a/drivers/platform/msm/ep_pcie/ep_pcie_com.h
+++ b/drivers/platform/msm/ep_pcie/ep_pcie_com.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, 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
@@ -90,8 +90,8 @@
#define PCIE20_CAP_LINKCTRLSTATUS 0x80
#define PCIE20_DEVICE_CONTROL2_STATUS2 0x98
#define PCIE20_LINK_CONTROL2_LINK_STATUS2 0xA0
-#define PCIE20_L1SUB_CAPABILITY 0x154
-#define PCIE20_L1SUB_CONTROL1 0x158
+#define PCIE20_L1SUB_CAPABILITY 0x1E0
+#define PCIE20_L1SUB_CONTROL1 0x1E4
#define PCIE20_ACK_F_ASPM_CTRL_REG 0x70C
#define PCIE20_MASK_ACK_N_FTS 0xff00
#define PCIE20_MISC_CONTROL_1 0x8BC
diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c
index 10fa11a..de517f6 100644
--- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c
+++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c
@@ -1661,6 +1661,13 @@
ep_pcie_vreg_deinit(dev);
out:
mutex_unlock(&dev->setup_mtx);
+
+ if (atomic_read(&dev->ep_pcie_dev_wake)) {
+ EP_PCIE_DBG(dev, "PCIe V%d: Released wakelock\n", dev->rev);
+ atomic_set(&dev->ep_pcie_dev_wake, 0);
+ pm_relax(&dev->pdev->dev);
+ }
+
return rc;
}
@@ -1971,6 +1978,17 @@
"PCIe V%d: No. %ld PERST assertion.\n",
dev->rev, dev->perst_ast_counter);
+ if (dev->in_d3hot_sleep) {
+ /*
+ * Perst was asserted when device was in d3hot sleep,
+ * disable clkreq irq
+ */
+ EP_PCIE_DBG(dev,
+ "PCIe V%d: Disable clkreq irq\n", dev->rev);
+ disable_irq_nosync(clkreq_irq);
+ dev->in_d3hot_sleep = false;
+ }
+
if (dev->client_ready) {
ep_pcie_notify_event(dev, EP_PCIE_EVENT_PM_D3_COLD);
} else {
diff --git a/drivers/power/supply/qcom/qpnp-vm-bms.c b/drivers/power/supply/qcom/qpnp-vm-bms.c
index 9caced7..3146b42 100644
--- a/drivers/power/supply/qcom/qpnp-vm-bms.c
+++ b/drivers/power/supply/qcom/qpnp-vm-bms.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, 2018-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2016, 2018-2020, 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
@@ -2416,6 +2416,7 @@
pr_debug("IBATT = %d\n", val->intval);
break;
case POWER_SUPPLY_PROP_VOLTAGE_OCV:
+ pm_relax(chip->dev);
cancel_delayed_work_sync(&chip->monitor_soc_work);
chip->last_ocv_uv = val->intval;
pr_debug("OCV = %d\n", val->intval);
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 9d555b6..d596b76 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -394,8 +394,8 @@
/**
* scsi_dev_info_list_find - find a matching dev_info list entry.
- * @vendor: vendor string
- * @model: model (product) string
+ * @vendor: full vendor string
+ * @model: full model (product) string
* @key: specify list to use
*
* Description:
@@ -410,7 +410,7 @@
struct scsi_dev_info_list *devinfo;
struct scsi_dev_info_list_table *devinfo_table =
scsi_devinfo_lookup_by_key(key);
- size_t vmax, mmax;
+ size_t vmax, mmax, mlen;
const char *vskip, *mskip;
if (IS_ERR(devinfo_table))
@@ -449,15 +449,18 @@
dev_info_list) {
if (devinfo->compatible) {
/*
- * Behave like the older version of get_device_flags.
+ * vendor strings must be an exact match
*/
- if (memcmp(devinfo->vendor, vskip, vmax) ||
- (vmax < sizeof(devinfo->vendor) &&
- devinfo->vendor[vmax]))
+ if (vmax != strlen(devinfo->vendor) ||
+ memcmp(devinfo->vendor, vskip, vmax))
continue;
- if (memcmp(devinfo->model, mskip, mmax) ||
- (mmax < sizeof(devinfo->model) &&
- devinfo->model[mmax]))
+
+ /*
+ * @model specifies the full string, and
+ * must be larger or equal to devinfo->model
+ */
+ mlen = strlen(devinfo->model);
+ if (mmax < mlen || memcmp(devinfo->model, mskip, mlen))
continue;
return devinfo;
} else {
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 07aeda6..b211394 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -284,6 +284,15 @@
If unsure, say N.
+config QTI_NOTIFY_SIDEBAND
+ tristate "QCOM sideband signalling helper"
+ help
+ This provides helper APIs and a header file through which
+ transport layer driver can talk to the sideband driver to
+ assert appropriate sideband signal.
+
+ If unsure, say N.
+
config PANIC_ON_GLADIATOR_ERROR
depends on MSM_GLADIATOR_ERP
bool "Panic on GLADIATOR error report"
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index c61594b..f972584 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -79,6 +79,7 @@
obj-$(CONFIG_MSM_PERFORMANCE) += msm_performance.o
obj-$(CONFIG_SDX_EXT_IPC) += sdx_ext_ipc.o
+obj-$(CONFIG_QTI_NOTIFY_SIDEBAND) += sideband_notify.o
ifdef CONFIG_MSM_SUBSYSTEM_RESTART
obj-y += subsystem_notif.o
diff --git a/drivers/soc/qcom/sideband_notify.c b/drivers/soc/qcom/sideband_notify.c
new file mode 100644
index 0000000..1907203
--- /dev/null
+++ b/drivers/soc/qcom/sideband_notify.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2020, 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/notifier.h>
+#include <soc/qcom/sb_notification.h>
+
+static BLOCKING_NOTIFIER_HEAD(sb_notifier_list);
+
+/**
+ * sb_register_evt_listener - registers a notifier callback
+ * @nb: pointer to the notifier block for the callback events
+ */
+int sb_register_evt_listener(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&sb_notifier_list, nb);
+}
+EXPORT_SYMBOL(sb_register_evt_listener);
+
+/**
+ * sb_unregister_evt_listener - un-registers a notifier callback
+ * registered previously.
+ * @nb: pointer to the notifier block for the callback events
+ */
+int sb_unregister_evt_listener(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&sb_notifier_list, nb);
+}
+EXPORT_SYMBOL(sb_unregister_evt_listener);
+
+/**
+ * sb_notifier_call_chain - send events to all registered listeners
+ * as received from publishers.
+ * @nb: pointer to the notifier block for the callback events
+ */
+int sb_notifier_call_chain(unsigned long val, void *v)
+{
+ return blocking_notifier_call_chain(&sb_notifier_list, val, v);
+}
+EXPORT_SYMBOL(sb_notifier_call_chain);
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index 16f0def..babf0a3 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -305,6 +305,9 @@
dws->len = transfer->len;
spin_unlock_irqrestore(&dws->buf_lock, flags);
+ /* Ensure dw->rx and dw->rx_end are visible */
+ smp_mb();
+
spi_enable_chip(dws, 0);
/* Handle per transfer options for bpw and speed */
diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h
index b8af965..f97275b 100644
--- a/drivers/staging/rtl8712/wifi.h
+++ b/drivers/staging/rtl8712/wifi.h
@@ -471,7 +471,7 @@
/* block-ack parameters */
#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
-#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
+#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0
#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
@@ -565,13 +565,6 @@
#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004
#define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010
-/* block-ack parameters */
-#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
-#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
-#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
-#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
-#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
-
/*
* A-PMDU buffer sizes
* According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2)
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index f8964247..985f49a 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -358,15 +358,14 @@
* tty fields and return the kref reference.
*/
if (rc) {
- tty_port_tty_set(&hp->port, NULL);
- tty->driver_data = NULL;
- tty_port_put(&hp->port);
printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
- } else
+ } else {
/* We are ready... raise DTR/RTS */
if (C_BAUD(tty))
if (hp->ops->dtr_rts)
hp->ops->dtr_rts(hp, 1);
+ tty_port_set_initialized(&hp->port, true);
+ }
/* Force wakeup of the polling thread */
hvc_kick();
@@ -376,22 +375,12 @@
static void hvc_close(struct tty_struct *tty, struct file * filp)
{
- struct hvc_struct *hp;
+ struct hvc_struct *hp = tty->driver_data;
unsigned long flags;
if (tty_hung_up_p(filp))
return;
- /*
- * No driver_data means that this close was issued after a failed
- * hvc_open by the tty layer's release_dev() function and we can just
- * exit cleanly because the kref reference wasn't made.
- */
- if (!tty->driver_data)
- return;
-
- hp = tty->driver_data;
-
spin_lock_irqsave(&hp->port.lock, flags);
if (--hp->port.count == 0) {
@@ -399,6 +388,9 @@
/* We are done with the tty pointer now. */
tty_port_tty_set(&hp->port, NULL);
+ if (!tty_port_initialized(&hp->port))
+ return;
+
if (C_HUPCL(tty))
if (hp->ops->dtr_rts)
hp->ops->dtr_rts(hp, 0);
@@ -415,6 +407,7 @@
* waking periodically to check chars_in_buffer().
*/
tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
+ tty_port_set_initialized(&hp->port, false);
} else {
if (hp->port.count < 0)
printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c
index c9f8af1..c82e4c9 100644
--- a/drivers/tty/serial/msm_smd_tty.c
+++ b/drivers/tty/serial/msm_smd_tty.c
@@ -1,5 +1,5 @@
/* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2015, 2017, 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2015, 2017, 2019-2020, The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -37,7 +37,7 @@
#define MODULE_NAME "msm_smdtty"
#define MAX_SMD_TTYS 37
#define MAX_TTY_BUF_SIZE 2048
-#define TTY_PUSH_WS_DELAY 500
+#define TTY_PUSH_WS_DELAY 100
#define TTY_PUSH_WS_POST_SUSPEND_DELAY 100
#define MAX_RA_WAKE_LOCK_NAME_LEN 32
#define SMD_TTY_LOG_PAGES 2
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index b4e7a73..d9eba79 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -125,7 +125,11 @@
static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
static bool dead_key_next;
-static int npadch = -1; /* -1 or number assembled on pad */
+
+/* Handles a number being assembled on the number pad */
+static bool npadch_active;
+static unsigned int npadch_value;
+
static unsigned int diacr;
static char rep; /* flag telling character repeat */
@@ -815,12 +819,12 @@
shift_state &= ~(1 << value);
/* kludge */
- if (up_flag && shift_state != old_state && npadch != -1) {
+ if (up_flag && shift_state != old_state && npadch_active) {
if (kbd->kbdmode == VC_UNICODE)
- to_utf8(vc, npadch);
+ to_utf8(vc, npadch_value);
else
- put_queue(vc, npadch & 0xff);
- npadch = -1;
+ put_queue(vc, npadch_value & 0xff);
+ npadch_active = false;
}
}
@@ -838,7 +842,7 @@
static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
{
- int base;
+ unsigned int base;
if (up_flag)
return;
@@ -852,10 +856,12 @@
base = 16;
}
- if (npadch == -1)
- npadch = value;
- else
- npadch = npadch * base + value;
+ if (!npadch_active) {
+ npadch_value = 0;
+ npadch_active = true;
+ }
+
+ npadch_value = npadch_value * base + value;
}
static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 3da2d22..57ce198 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -57,6 +57,9 @@
#ifdef CONFIG_TUSB1064_XR_MISC
#include "../../misc/tusb1064.h"
#endif
+#ifdef CONFIG_VXR200_XR_MISC
+#include "../../misc/vxr7200.h"
+#endif
#define SDP_CONNETION_CHECK_TIME 10000 /* in ms */
@@ -2966,6 +2969,10 @@
#ifdef CONFIG_TUSB1064_XR_MISC
tusb1064_usb_event(val.intval ? true : false);
#endif
+#ifdef CONFIG_VXR200_XR_MISC
+ vxr7200_usb_event(true);
+#endif
+
}
dbg_event(0xFF, "cc_state", mdwc->typec_orientation);
@@ -4658,6 +4665,10 @@
} else {
dwc3_msm_gadget_vbus_draw(mdwc, 0);
dev_dbg(mdwc->dev, "Cable disconnected\n");
+#ifdef CONFIG_VXR200_XR_MISC
+ vxr7200_usb_event(false);
+#endif
+
}
break;
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 38d8b25..9db175e 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, 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
@@ -3125,7 +3125,7 @@
info.out_epname = "gsi-epout";
info.in_req_buf_len = GSI_IN_BUFF_SIZE;
gsi->d_port.in_aggr_size = GSI_IN_RNDIS_AGGR_SIZE;
- info.in_req_num_buf = GSI_NUM_IN_RNDIS_BUFFERS;
+ info.in_req_num_buf = GSI_NUM_IN_RNDIS_RMNET_ECM_BUFFERS;
gsi->d_port.out_aggr_size = GSI_OUT_AGGR_SIZE;
info.out_req_buf_len = GSI_OUT_AGGR_SIZE;
info.out_req_num_buf = GSI_NUM_OUT_BUFFERS;
@@ -3316,7 +3316,7 @@
info.out_epname = "gsi-epout";
gsi->d_port.in_aggr_size = GSI_IN_RMNET_AGGR_SIZE;
info.in_req_buf_len = GSI_IN_BUFF_SIZE;
- info.in_req_num_buf = GSI_NUM_IN_BUFFERS;
+ info.in_req_num_buf = GSI_NUM_IN_RNDIS_RMNET_ECM_BUFFERS;
gsi->d_port.out_aggr_size = GSI_OUT_AGGR_SIZE;
info.out_req_buf_len = GSI_OUT_RMNET_BUF_LEN;
info.out_req_num_buf = GSI_NUM_OUT_BUFFERS;
@@ -3349,7 +3349,7 @@
info.out_epname = "gsi-epout";
gsi->d_port.in_aggr_size = GSI_ECM_AGGR_SIZE;
info.in_req_buf_len = GSI_IN_BUFF_SIZE;
- info.in_req_num_buf = GSI_NUM_IN_BUFFERS;
+ info.in_req_num_buf = GSI_NUM_IN_RNDIS_RMNET_ECM_BUFFERS;
gsi->d_port.out_aggr_size = GSI_ECM_AGGR_SIZE;
info.out_req_buf_len = GSI_OUT_ECM_BUF_LEN;
info.out_req_num_buf = GSI_NUM_OUT_BUFFERS;
diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h
index 02be58d..3118f0a 100644
--- a/drivers/usb/gadget/function/f_gsi.h
+++ b/drivers/usb/gadget/function/f_gsi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, 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
@@ -43,7 +43,7 @@
#define GSI_MAX_CTRL_PKT_SIZE 8192
#define GSI_CTRL_DTR (1 << 0)
-#define GSI_NUM_IN_RNDIS_BUFFERS 50
+#define GSI_NUM_IN_RNDIS_RMNET_ECM_BUFFERS 50
#define GSI_NUM_IN_BUFFERS 15
#define GSI_IN_BUFF_SIZE 2048
#define GSI_NUM_OUT_BUFFERS 14
diff --git a/drivers/usb/gadget/function/f_ipc.c b/drivers/usb/gadget/function/f_ipc.c
index d74d673..bd8c726 100644
--- a/drivers/usb/gadget/function/f_ipc.c
+++ b/drivers/usb/gadget/function/f_ipc.c
@@ -21,6 +21,7 @@
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/usb/ipc_bridge.h>
+#include <soc/qcom/sb_notification.h>
#define MAX_INST_NAME_LEN 40
@@ -270,23 +271,35 @@
reinit_completion(&ipc_dev->write_done);
+ /* Notify the GPIO driver to wakup the host if
+ * host is in suspend mode
+ */
if (usb_ep_queue(in, req, GFP_KERNEL)) {
+ sb_notifier_call_chain(EVT_WAKE_UP, NULL);
wait_event_interruptible(ipc_dev->state_wq, ipc_dev->online ||
ipc_dev->current_state == IPC_DISCONNECTED);
pr_debug("%s: Interface ready, Retry IN request\n", __func__);
goto retry_write;
}
+retry_write_done:
ret = wait_for_completion_interruptible_timeout(&ipc_dev->write_done,
msecs_to_jiffies(IPC_WRITE_WAIT_TIMEOUT));
if (ret < 0) {
pr_err("%s: Interruption triggered\n", __func__);
ret = -EINTR;
goto fail;
- } else if (ret == 0) {
+ } else if (ret == 0 && ipc_dev->online) {
pr_err("%s: Request timed out\n", __func__);
ret = -ETIMEDOUT;
goto fail;
+ /* Notify the GPIO driver to wakeup the host and reintialize the
+ * completion structure.
+ */
+ } else if (!ipc_dev->online) {
+ sb_notifier_call_chain(EVT_WAKE_UP, NULL);
+ reinit_completion(&ipc_dev->write_done);
+ goto retry_write_done;
}
return !req->status ? req->actual : req->status;
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
index 15dfbae..e887eaf 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -1189,14 +1189,14 @@
agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);
if (!agdev->out_ep) {
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
- return ret;
+ return -ENODEV;
}
}
agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
if (!agdev->in_ep) {
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
- return ret;
+ return -ENODEV;
}
uac2->p_prm.uac2 = uac2;
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c
index 534a3f6..474bb13 100644
--- a/drivers/usb/musb/musb_debugfs.c
+++ b/drivers/usb/musb/musb_debugfs.c
@@ -200,6 +200,11 @@
u8 test;
char buf[18];
+ memset(buf, 0x00, sizeof(buf));
+
+ if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+ return -EFAULT;
+
pm_runtime_get_sync(musb->controller);
test = musb_readb(musb->mregs, MUSB_TESTMODE);
if (test) {
@@ -208,11 +213,6 @@
goto ret;
}
- memset(buf, 0x00, sizeof(buf));
-
- if (copy_from_user(buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
- return -EFAULT;
-
if (strstarts(buf, "force host"))
test = MUSB_TEST_FORCE_HOST;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 737b665..326e710 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1146,6 +1146,10 @@
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1031, 0xff), /* Telit LE910C1-EUX */
+ .driver_info = NCTRL(0) | RSVD(3) },
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */
+ .driver_info = NCTRL(0) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0),
.driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1),
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 06916dd..c59e6d4 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -177,6 +177,7 @@
{DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
{DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */
{DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */
+ {DEVICE_SWI(0x413c, 0x81cb)}, /* Dell Wireless 5816e QDL */
{DEVICE_SWI(0x413c, 0x81cc)}, /* Dell Wireless 5816e */
{DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */
{DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 93c696e..0fbb34f 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -305,6 +305,10 @@
if (status) {
dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n",
__func__, status, endpoint);
+
+ /* don't resubmit on fatal errors */
+ if (status == -ESHUTDOWN || status == -ENOENT)
+ return;
} else {
if (urb->actual_length) {
tty_insert_flip_string(&port->port, data,
diff --git a/drivers/video/fbdev/msm/mdp3_layer.c b/drivers/video/fbdev/msm/mdp3_layer.c
index 98b5c19..d32497a9 100644
--- a/drivers/video/fbdev/msm/mdp3_layer.c
+++ b/drivers/video/fbdev/msm/mdp3_layer.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 2020, 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
@@ -236,7 +236,7 @@
pr_err("buf size(0x%lx) is smaller than dma config(0x%x)\n",
data.len, (dma->source_config.stride *
dma->source_config.height));
- mdp3_put_img(&data, MDP3_CLIENT_DMA_P);
+ mdp3_put_img(&data, intf_type);
rc = -EINVAL;
goto err;
}
@@ -244,13 +244,13 @@
rc = mdp3_bufq_push(&mdp3_session->bufq_in, &data);
if (rc) {
pr_err("fail to queue the overlay buffer, buffer drop\n");
- mdp3_put_img(&data, MDP3_CLIENT_DMA_P);
+ mdp3_put_img(&data, intf_type);
goto err;
}
rc = 0;
err:
if (is_panel_type_cmd)
- mdp3_iommu_disable(MDP3_CLIENT_DMA_P);
+ mdp3_iommu_disable(intf_type);
return rc;
}
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index f305e81..9d829e4 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -2949,15 +2949,7 @@
mdss_fb_free_fb_ion_memory(mfd);
atomic_set(&mfd->ioctl_ref_cnt, 0);
- } else {
- if (mfd->mdp.release_fnc)
- ret = mfd->mdp.release_fnc(mfd, file);
-
- /* display commit is needed to release resources */
- if (ret)
- mdss_fb_pan_display(&mfd->fbi->var, mfd->fbi);
}
-
return ret;
}
diff --git a/gen_headers_arm.bp b/gen_headers_arm.bp
index e8d2f2f..230ca68 100644
--- a/gen_headers_arm.bp
+++ b/gen_headers_arm.bp
@@ -187,6 +187,8 @@
"linux/cciss_defs.h",
"linux/cciss_ioctl.h",
"linux/cdrom.h",
+ "linux/cec-funcs.h",
+ "linux/cec.h",
"linux/cgroupstats.h",
"linux/chio.h",
"linux/cm4000_cs.h",
diff --git a/gen_headers_arm64.bp b/gen_headers_arm64.bp
index 5060c14..cc42a61 100644
--- a/gen_headers_arm64.bp
+++ b/gen_headers_arm64.bp
@@ -186,6 +186,8 @@
"linux/cciss_defs.h",
"linux/cciss_ioctl.h",
"linux/cdrom.h",
+ "linux/cec-funcs.h",
+ "linux/cec.h",
"linux/cgroupstats.h",
"linux/chio.h",
"linux/cm4000_cs.h",
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index eab0f17..4d8f7a1 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1029,4 +1029,23 @@
#endif
+struct drm_dp_dpcd_ident {
+ u8 oui[3];
+ u8 device_id[6];
+ u8 hw_rev;
+ u8 sw_major_rev;
+ u8 sw_minor_rev;
+} __packed;
+
+/**
+ * struct drm_dp_desc - DP branch/sink device descriptor
+ * @ident: DP device identification from DPCD 0x400 (sink) or 0x500 (branch).
+ */
+struct drm_dp_desc {
+ struct drm_dp_dpcd_ident ident;
+};
+
+int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc,
+ bool is_branch);
+
#endif /* _DRM_DP_HELPER_H_ */
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 6b54319..6060969 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -590,6 +590,10 @@
/*
* MODULE_DEVICE_TABLE expects this struct to be called x86cpu_device_id.
* Although gcc seems to ignore this error, clang fails without this define.
+ *
+ * Note: The ordering of the struct is different from upstream because the
+ * static initializers in kernels < 5.7 still use C89 style while upstream
+ * has been converted to proper C99 initializers.
*/
#define x86cpu_device_id x86_cpu_id
struct x86_cpu_id {
@@ -598,6 +602,7 @@
__u16 model;
__u16 feature; /* bit index */
kernel_ulong_t driver_data;
+ __u16 steppings;
};
#define X86_FEATURE_MATCH(x) \
@@ -606,6 +611,7 @@
#define X86_VENDOR_ANY 0xffff
#define X86_FAMILY_ANY 0
#define X86_MODEL_ANY 0
+#define X86_STEPPING_ANY 0
#define X86_FEATURE_ANY 0 /* Same as FPU, you can't test for that */
/*
diff --git a/include/media/cec.h b/include/media/cec.h
index 2f90e25..a22cf34 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -31,6 +31,9 @@
#include <media/rc-core.h>
#include <media/cec-edid.h>
+#define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \
+ CEC_CAP_PASSTHROUGH | CEC_CAP_RC)
+
/**
* struct cec_devnode - cec device node
* @dev: cec device
diff --git a/include/soc/qcom/sb_notification.h b/include/soc/qcom/sb_notification.h
new file mode 100644
index 0000000..f9b4740
--- /dev/null
+++ b/include/soc/qcom/sb_notification.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2020, 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 _SB_NOTIFICATION_H
+#define _SB_NOTIFICATION_H
+
+/* Indicates a system wake up event */
+#define EVT_WAKE_UP 0x01
+
+#ifdef CONFIG_QTI_NOTIFY_SIDEBAND
+/**
+ * sb_register_evt_listener - registers a notifier callback
+ * @nb: pointer to the notifier block for the callback events
+ */
+int sb_register_evt_listener(struct notifier_block *nb);
+
+/**
+ * sb_unregister_evt_listener - un-registers a notifier callback
+ * registered previously.
+ * @nb: pointer to the notifier block for the callback events
+ */
+int sb_unregister_evt_listener(struct notifier_block *nb);
+
+/**
+ * sb_notifier_call_chain - send events to all registered listeners
+ * as received from publishers.
+ * @nb: pointer to the notifier block for the callback events
+ */
+int sb_notifier_call_chain(unsigned long val, void *v);
+#else
+static inline int sb_register_evt_listener(struct notifier_block *nb)
+{
+ return -EINVAL;
+}
+static inline int sb_unregister_evt_listener(struct notifier_block *nb)
+{
+ return -EINVAL;
+}
+static inline int sb_notifier_call_chain(unsigned long val, void *v)
+{
+ return -EINVAL;
+}
+#endif /* !CONFIG_QTI_NOTIFY_SIDEBAND */
+
+#endif /* _SB_NOTIFICATION_H */
diff --git a/include/uapi/linux/mmc/ioctl.h b/include/uapi/linux/mmc/ioctl.h
index 8fec144..c74c521 100644
--- a/include/uapi/linux/mmc/ioctl.h
+++ b/include/uapi/linux/mmc/ioctl.h
@@ -2,6 +2,7 @@
#define LINUX_MMC_IOCTL_H
#include <linux/types.h>
+#include <linux/major.h>
struct mmc_ioc_cmd {
/* Implies direction of data. true = write, false = read */
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 8ddd294..1fcaa17 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -604,10 +604,6 @@
if (ret)
goto out;
- /* uprobe_write_opcode() assumes we don't cross page boundary */
- BUG_ON((uprobe->offset & ~PAGE_MASK) +
- UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
-
smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */
set_bit(UPROBE_COPY_INSN, &uprobe->flags);
@@ -886,6 +882,13 @@
if (offset > i_size_read(inode))
return -EINVAL;
+ /*
+ * This ensures that copy_from_page() and copy_to_page()
+ * can't cross page boundary.
+ */
+ if (!IS_ALIGNED(offset, UPROBE_SWBP_INSN_SIZE))
+ return -EINVAL;
+
retry:
uprobe = alloc_uprobe(inode, offset);
if (!uprobe)
@@ -1696,6 +1699,9 @@
uprobe_opcode_t opcode;
int result;
+ if (WARN_ON_ONCE(!IS_ALIGNED(vaddr, UPROBE_SWBP_INSN_SIZE)))
+ return -EINVAL;
+
pagefault_disable();
result = __get_user(opcode, (uprobe_opcode_t __user *)vaddr);
pagefault_enable();
diff --git a/kernel/relay.c b/kernel/relay.c
index 91e8fbf..5034cb3 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -578,6 +578,11 @@
return NULL;
chan->buf = alloc_percpu(struct rchan_buf *);
+ if (!chan->buf) {
+ kfree(chan);
+ return NULL;
+ }
+
chan->version = RELAYFS_CHANNEL_VERSION;
chan->n_subbufs = n_subbufs;
chan->subbuf_size = subbuf_size;
diff --git a/mm/mremap.c b/mm/mremap.c
index 0c2bac5..5686685 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -212,7 +212,7 @@
new_pmd = alloc_new_pmd(vma->vm_mm, vma, new_addr);
if (!new_pmd)
break;
- if (pmd_trans_huge(*old_pmd)) {
+ if (pmd_trans_huge(*old_pmd) || pmd_devmap(*old_pmd)) {
if (extent == HPAGE_PMD_SIZE) {
bool moved;
/* See comment in move_ptes() */
diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c
index 828ed3d..beca506 100644
--- a/net/ipc_router/ipc_router_core.c
+++ b/net/ipc_router/ipc_router_core.c
@@ -999,7 +999,6 @@
return -EINVAL;
}
xprt_version = temp_skb->data[0];
- pr_err("app:%s version recv %d\n", __func__, xprt_version);
}
if (xprt_version == IPC_ROUTER_V1)
@@ -4187,8 +4186,8 @@
up_write(&routing_table_lock_lha3);
xprt->priv = xprt_info;
- send_hello_msg(xprt_info);
complete_all(&xprt->xprt_init_complete);
+ send_hello_msg(xprt_info);
return 0;
}
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 02f6dc8..a57d3b4 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -262,6 +262,7 @@
err = devinet_sysctl_register(in_dev);
if (err) {
in_dev->dead = 1;
+ neigh_parms_release(&arp_tbl, in_dev->arp_parms);
in_dev_put(in_dev);
in_dev = NULL;
goto out;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 44a2010..37268a37 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -426,8 +426,10 @@
sg_init_table(sg, nfrags);
ret = skb_to_sgvec(skb, sg, 0, skb->len);
- if (unlikely(ret < 0))
+ if (unlikely(ret < 0)) {
+ kfree(tmp);
goto out;
+ }
aead_request_set_crypt(req, sg, sg, elen + ivlen, iv);
aead_request_set_ad(req, assoclen);
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 39590e3..3305183 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1560,6 +1560,8 @@
tunnel_id, fd);
goto err;
}
+ if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
+ goto err;
switch (encap) {
case L2TP_ENCAPTYPE_UDP:
if (sk->sk_protocol != IPPROTO_UDP) {
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index b63d504..aa85e13 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -24,7 +24,6 @@
#include <net/icmp.h>
#include <net/udp.h>
#include <net/inet_common.h>
-#include <net/inet_hashtables.h>
#include <net/tcp_states.h>
#include <net/protocol.h>
#include <net/xfrm.h>
@@ -208,15 +207,31 @@
return 0;
}
+static int l2tp_ip_hash(struct sock *sk)
+{
+ if (sk_unhashed(sk)) {
+ write_lock_bh(&l2tp_ip_lock);
+ sk_add_node(sk, &l2tp_ip_table);
+ write_unlock_bh(&l2tp_ip_lock);
+ }
+ return 0;
+}
+
+static void l2tp_ip_unhash(struct sock *sk)
+{
+ if (sk_unhashed(sk))
+ return;
+ write_lock_bh(&l2tp_ip_lock);
+ sk_del_node_init(sk);
+ write_unlock_bh(&l2tp_ip_lock);
+}
+
static int l2tp_ip_open(struct sock *sk)
{
/* Prevent autobind. We don't have ports. */
inet_sk(sk)->inet_num = IPPROTO_L2TP;
- write_lock_bh(&l2tp_ip_lock);
- sk_add_node(sk, &l2tp_ip_table);
- write_unlock_bh(&l2tp_ip_lock);
-
+ l2tp_ip_hash(sk);
return 0;
}
@@ -598,8 +613,8 @@
.sendmsg = l2tp_ip_sendmsg,
.recvmsg = l2tp_ip_recvmsg,
.backlog_rcv = l2tp_ip_backlog_recv,
- .hash = inet_hash,
- .unhash = inet_unhash,
+ .hash = l2tp_ip_hash,
+ .unhash = l2tp_ip_unhash,
.obj_size = sizeof(struct l2tp_ip_sock),
#ifdef CONFIG_COMPAT
.compat_setsockopt = compat_ip_setsockopt,
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 5a3667c..bdd9c97 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -24,8 +24,6 @@
#include <net/icmp.h>
#include <net/udp.h>
#include <net/inet_common.h>
-#include <net/inet_hashtables.h>
-#include <net/inet6_hashtables.h>
#include <net/tcp_states.h>
#include <net/protocol.h>
#include <net/xfrm.h>
@@ -220,15 +218,31 @@
return 0;
}
+static int l2tp_ip6_hash(struct sock *sk)
+{
+ if (sk_unhashed(sk)) {
+ write_lock_bh(&l2tp_ip6_lock);
+ sk_add_node(sk, &l2tp_ip6_table);
+ write_unlock_bh(&l2tp_ip6_lock);
+ }
+ return 0;
+}
+
+static void l2tp_ip6_unhash(struct sock *sk)
+{
+ if (sk_unhashed(sk))
+ return;
+ write_lock_bh(&l2tp_ip6_lock);
+ sk_del_node_init(sk);
+ write_unlock_bh(&l2tp_ip6_lock);
+}
+
static int l2tp_ip6_open(struct sock *sk)
{
/* Prevent autobind. We don't have ports. */
inet_sk(sk)->inet_num = IPPROTO_L2TP;
- write_lock_bh(&l2tp_ip6_lock);
- sk_add_node(sk, &l2tp_ip6_table);
- write_unlock_bh(&l2tp_ip6_lock);
-
+ l2tp_ip6_hash(sk);
return 0;
}
@@ -732,8 +746,8 @@
.sendmsg = l2tp_ip6_sendmsg,
.recvmsg = l2tp_ip6_recvmsg,
.backlog_rcv = l2tp_ip6_backlog_recv,
- .hash = inet6_hash,
- .unhash = inet_unhash,
+ .hash = l2tp_ip6_hash,
+ .unhash = l2tp_ip6_unhash,
.obj_size = sizeof(struct l2tp_ip6_sock),
#ifdef CONFIG_COMPAT
.compat_setsockopt = compat_ipv6_setsockopt,
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 18f3773..d6473b8 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1296,7 +1296,7 @@
/* Wait for children sockets to appear; these are the new sockets
* created upon connection establishment.
*/
- timeout = sock_sndtimeo(listener, flags & O_NONBLOCK);
+ timeout = sock_rcvtimeo(listener, flags & O_NONBLOCK);
prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE);
while ((connected = vsock_dequeue_accept(listener)) == NULL &&