[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <2026013055-vocation-rehab-60f2@gregkh>
Date: Fri, 30 Jan 2026 10:49:55 +0100
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org,
akpm@...ux-foundation.org,
torvalds@...ux-foundation.org,
stable@...r.kernel.org
Cc: lwn@....net,
jslaby@...e.cz,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Subject: Re: Linux 6.6.122
diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
index 9b03c41d3604..bb01bf5663f3 100644
--- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
+++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
@@ -15,42 +15,53 @@ description:
properties:
compatible:
- enum:
- - qcom,mdm9607-rpmpd
- - qcom,msm8226-rpmpd
- - qcom,msm8909-rpmpd
- - qcom,msm8916-rpmpd
- - qcom,msm8939-rpmpd
- - qcom,msm8953-rpmpd
- - qcom,msm8976-rpmpd
- - qcom,msm8994-rpmpd
- - qcom,msm8996-rpmpd
- - qcom,msm8998-rpmpd
- - qcom,qcm2290-rpmpd
- - qcom,qcs404-rpmpd
- - qcom,qdu1000-rpmhpd
- - qcom,sa8155p-rpmhpd
- - qcom,sa8540p-rpmhpd
- - qcom,sa8775p-rpmhpd
- - qcom,sdm660-rpmpd
- - qcom,sc7180-rpmhpd
- - qcom,sc7280-rpmhpd
- - qcom,sc8180x-rpmhpd
- - qcom,sc8280xp-rpmhpd
- - qcom,sdm670-rpmhpd
- - qcom,sdm845-rpmhpd
- - qcom,sdx55-rpmhpd
- - qcom,sdx65-rpmhpd
- - qcom,sdx75-rpmhpd
- - qcom,sm6115-rpmpd
- - qcom,sm6125-rpmpd
- - qcom,sm6350-rpmhpd
- - qcom,sm6375-rpmpd
- - qcom,sm8150-rpmhpd
- - qcom,sm8250-rpmhpd
- - qcom,sm8350-rpmhpd
- - qcom,sm8450-rpmhpd
- - qcom,sm8550-rpmhpd
+ oneOf:
+ - enum:
+ - qcom,mdm9607-rpmpd
+ - qcom,msm8226-rpmpd
+ - qcom,msm8909-rpmpd
+ - qcom,msm8916-rpmpd
+ - qcom,msm8917-rpmpd
+ - qcom,msm8939-rpmpd
+ - qcom,msm8953-rpmpd
+ - qcom,msm8976-rpmpd
+ - qcom,msm8994-rpmpd
+ - qcom,msm8996-rpmpd
+ - qcom,msm8998-rpmpd
+ - qcom,qcm2290-rpmpd
+ - qcom,qcs404-rpmpd
+ - qcom,qdu1000-rpmhpd
+ - qcom,qm215-rpmpd
+ - qcom,sa8155p-rpmhpd
+ - qcom,sa8540p-rpmhpd
+ - qcom,sa8775p-rpmhpd
+ - qcom,sc7180-rpmhpd
+ - qcom,sc7280-rpmhpd
+ - qcom,sc8180x-rpmhpd
+ - qcom,sc8280xp-rpmhpd
+ - qcom,sdm660-rpmpd
+ - qcom,sdm670-rpmhpd
+ - qcom,sdm845-rpmhpd
+ - qcom,sdx55-rpmhpd
+ - qcom,sdx65-rpmhpd
+ - qcom,sdx75-rpmhpd
+ - qcom,sm6115-rpmpd
+ - qcom,sm6125-rpmpd
+ - qcom,sm6350-rpmhpd
+ - qcom,sm6375-rpmpd
+ - qcom,sm7150-rpmhpd
+ - qcom,sm8150-rpmhpd
+ - qcom,sm8250-rpmhpd
+ - qcom,sm8350-rpmhpd
+ - qcom,sm8450-rpmhpd
+ - qcom,sm8550-rpmhpd
+ - qcom,sm8650-rpmhpd
+ - qcom,sm8750-rpmhpd
+ - qcom,x1e80100-rpmhpd
+ - items:
+ - enum:
+ - qcom,msm8937-rpmpd
+ - const: qcom,msm8917-rpmpd
'#power-domain-cells':
const: 1
diff --git a/Documentation/netlink/specs/fou.yaml b/Documentation/netlink/specs/fou.yaml
index 0af5ab842c04..91721ee40641 100644
--- a/Documentation/netlink/specs/fou.yaml
+++ b/Documentation/netlink/specs/fou.yaml
@@ -39,6 +39,8 @@ attribute-sets:
-
name: ipproto
type: u8
+ checks:
+ min: 1
-
name: type
type: u8
diff --git a/Makefile b/Makefile
index 79fa45c965fb..fd613135366c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 6
PATCHLEVEL = 6
-SUBLEVEL = 121
+SUBLEVEL = 122
EXTRAVERSION =
NAME = Pinguïn Aangedreven
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
index 3e70e79ce24b..8472e00bde5a 100644
--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
@@ -4412,8 +4412,12 @@ remoteproc_nsp0: remoteproc@...00000 {
clocks = <&rpmhcc RPMH_CXO_CLK>;
clock-names = "xo";
- power-domains = <&rpmhpd SC8280XP_NSP>;
- power-domain-names = "nsp";
+ power-domains = <&rpmhpd SC8280XP_NSP>,
+ <&rpmhpd SC8280XP_CX>,
+ <&rpmhpd SC8280XP_MXC>;
+ power-domain-names = "nsp",
+ "cx",
+ "mxc";
memory-region = <&pil_nsp0_mem>;
@@ -4543,8 +4547,12 @@ remoteproc_nsp1: remoteproc@...00000 {
clocks = <&rpmhcc RPMH_CXO_CLK>;
clock-names = "xo";
- power-domains = <&rpmhpd SC8280XP_NSP>;
- power-domain-names = "nsp";
+ power-domains = <&rpmhpd SC8280XP_NSP>,
+ <&rpmhpd SC8280XP_CX>,
+ <&rpmhpd SC8280XP_MXC>;
+ power-domain-names = "nsp",
+ "cx",
+ "mxc";
memory-region = <&pil_nsp1_mem>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
index 1eb287a3f8c0..f3d419799708 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
@@ -427,7 +427,6 @@ &pcie_phy {
&pcie0 {
ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
- max-link-speed = <2>;
num-lanes = <2>;
pinctrl-names = "default";
status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
index 6a6b36c36ce2..0a55aa44effe 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts
@@ -73,7 +73,6 @@ &i2c4 {
};
&pcie0 {
- max-link-speed = <1>;
num-lanes = <1>;
vpcie3v3-supply = <&vcc3v3_sys>;
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
index f4829b28c71e..3c6f4982cf1b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
@@ -40,13 +40,13 @@ adc-keys {
button-up {
label = "Volume Up";
linux,code = <KEY_VOLUMEUP>;
- press-threshold-microvolt = <100000>;
+ press-threshold-microvolt = <2000>;
};
button-down {
label = "Volume Down";
linux,code = <KEY_VOLUMEDOWN>;
- press-threshold-microvolt = <600000>;
+ press-threshold-microvolt = <300000>;
};
};
diff --git a/arch/arm64/include/asm/hyperv-tlfs.h b/arch/arm64/include/asm/hyperv-tlfs.h
index bc6c7ac934a1..54846d1d29c3 100644
--- a/arch/arm64/include/asm/hyperv-tlfs.h
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -21,14 +21,6 @@
* byte ordering of Linux running on ARM64, so no special handling is required.
*/
-/*
- * These Hyper-V registers provide information equivalent to the CPUID
- * instruction on x86/x64.
- */
-#define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */
-#define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */
-#define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */
-
/*
* Group C Features. See the asm-generic version of hyperv-tlfs.h
* for a description of Feature Groups.
@@ -41,28 +33,29 @@
#define HV_STIMER_DIRECT_MODE_AVAILABLE BIT(13)
/*
- * Synthetic register definitions equivalent to MSRs on x86/x64
+ * To support arch-generic code calling hv_set/get_register:
+ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
+ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
*/
-#define HV_REGISTER_CRASH_P0 0x00000210
-#define HV_REGISTER_CRASH_P1 0x00000211
-#define HV_REGISTER_CRASH_P2 0x00000212
-#define HV_REGISTER_CRASH_P3 0x00000213
-#define HV_REGISTER_CRASH_P4 0x00000214
-#define HV_REGISTER_CRASH_CTL 0x00000215
+#define HV_MSR_CRASH_P0 (HV_REGISTER_CRASH_P0)
+#define HV_MSR_CRASH_P1 (HV_REGISTER_CRASH_P1)
+#define HV_MSR_CRASH_P2 (HV_REGISTER_CRASH_P2)
+#define HV_MSR_CRASH_P3 (HV_REGISTER_CRASH_P3)
+#define HV_MSR_CRASH_P4 (HV_REGISTER_CRASH_P4)
+#define HV_MSR_CRASH_CTL (HV_REGISTER_CRASH_CTL)
-#define HV_REGISTER_GUEST_OSID 0x00090002
-#define HV_REGISTER_VP_INDEX 0x00090003
-#define HV_REGISTER_TIME_REF_COUNT 0x00090004
-#define HV_REGISTER_REFERENCE_TSC 0x00090017
+#define HV_MSR_VP_INDEX (HV_REGISTER_VP_INDEX)
+#define HV_MSR_TIME_REF_COUNT (HV_REGISTER_TIME_REF_COUNT)
+#define HV_MSR_REFERENCE_TSC (HV_REGISTER_REFERENCE_TSC)
-#define HV_REGISTER_SINT0 0x000A0000
-#define HV_REGISTER_SCONTROL 0x000A0010
-#define HV_REGISTER_SIEFP 0x000A0012
-#define HV_REGISTER_SIMP 0x000A0013
-#define HV_REGISTER_EOM 0x000A0014
+#define HV_MSR_SINT0 (HV_REGISTER_SINT0)
+#define HV_MSR_SCONTROL (HV_REGISTER_SCONTROL)
+#define HV_MSR_SIEFP (HV_REGISTER_SIEFP)
+#define HV_MSR_SIMP (HV_REGISTER_SIMP)
+#define HV_MSR_EOM (HV_REGISTER_EOM)
-#define HV_REGISTER_STIMER0_CONFIG 0x000B0000
-#define HV_REGISTER_STIMER0_COUNT 0x000B0001
+#define HV_MSR_STIMER0_CONFIG (HV_REGISTER_STIMER0_CONFIG)
+#define HV_MSR_STIMER0_COUNT (HV_REGISTER_STIMER0_COUNT)
union hv_msi_entry {
u64 as_uint64[2];
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
index 20070a847304..a975e1a689dd 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -31,12 +31,12 @@ void hv_set_vpreg(u32 reg, u64 value);
u64 hv_get_vpreg(u32 reg);
void hv_get_vpreg_128(u32 reg, struct hv_get_vp_registers_output *result);
-static inline void hv_set_register(unsigned int reg, u64 value)
+static inline void hv_set_msr(unsigned int reg, u64 value)
{
hv_set_vpreg(reg, value);
}
-static inline u64 hv_get_register(unsigned int reg)
+static inline u64 hv_get_msr(unsigned int reg)
{
return hv_get_vpreg(reg);
}
diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 02870beb271e..17c436387f1b 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -396,7 +396,7 @@ int swsusp_arch_suspend(void)
* Memory allocated by get_safe_page() will be dealt with by the hibernate code,
* we don't need to free it here.
*/
-int swsusp_arch_resume(void)
+int __nocfi swsusp_arch_resume(void)
{
int rc;
void *zero_page;
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 425b1bc17a3f..19c494499746 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -475,6 +475,10 @@ static int restore_za_context(struct user_ctxs *user)
fpsimd_flush_task_state(current);
/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
+ sve_alloc(current, false);
+ if (!current->thread.sve_state)
+ return -ENOMEM;
+
sme_alloc(current, true);
if (!current->thread.sme_state) {
current->thread.svcr &= ~SVCR_ZA_MASK;
diff --git a/arch/loongarch/kernel/perf_event.c b/arch/loongarch/kernel/perf_event.c
index cac7cba81b65..c25cb4536bdd 100644
--- a/arch/loongarch/kernel/perf_event.c
+++ b/arch/loongarch/kernel/perf_event.c
@@ -637,6 +637,18 @@ static const struct loongarch_perf_event *loongarch_pmu_map_cache_event(u64 conf
return pev;
}
+static inline bool loongarch_pmu_event_requires_counter(const struct perf_event *event)
+{
+ switch (event->attr.type) {
+ case PERF_TYPE_HARDWARE:
+ case PERF_TYPE_HW_CACHE:
+ case PERF_TYPE_RAW:
+ return true;
+ default:
+ return false;
+ }
+}
+
static int validate_group(struct perf_event *event)
{
struct cpu_hw_events fake_cpuc;
@@ -644,15 +656,18 @@ static int validate_group(struct perf_event *event)
memset(&fake_cpuc, 0, sizeof(fake_cpuc));
- if (loongarch_pmu_alloc_counter(&fake_cpuc, &leader->hw) < 0)
+ if (loongarch_pmu_event_requires_counter(leader) &&
+ loongarch_pmu_alloc_counter(&fake_cpuc, &leader->hw) < 0)
return -EINVAL;
for_each_sibling_event(sibling, leader) {
- if (loongarch_pmu_alloc_counter(&fake_cpuc, &sibling->hw) < 0)
+ if (loongarch_pmu_event_requires_counter(sibling) &&
+ loongarch_pmu_alloc_counter(&fake_cpuc, &sibling->hw) < 0)
return -EINVAL;
}
- if (loongarch_pmu_alloc_counter(&fake_cpuc, &event->hw) < 0)
+ if (loongarch_pmu_event_requires_counter(event) &&
+ loongarch_pmu_alloc_counter(&fake_cpuc, &event->hw) < 0)
return -EINVAL;
return 0;
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 4564521296ac..4ca15be45cb8 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -1423,13 +1423,22 @@ static inline bool intel_pmu_has_bts_period(struct perf_event *event, u64 period
struct hw_perf_event *hwc = &event->hw;
unsigned int hw_event, bts_event;
- if (event->attr.freq)
+ /*
+ * Only use BTS for fixed rate period==1 events.
+ */
+ if (event->attr.freq || period != 1)
+ return false;
+
+ /*
+ * BTS doesn't virtualize.
+ */
+ if (event->attr.exclude_host)
return false;
hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
- return hw_event == bts_event && period == 1;
+ return hw_event == bts_event;
}
static inline bool intel_pmu_has_bts(struct perf_event *event)
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index d1e2d12279e2..95eada2994e1 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -664,14 +664,14 @@ void hyperv_cleanup(void)
hv_hypercall_pg = NULL;
/* Reset the hypercall page */
- hypercall_msr.as_uint64 = hv_get_register(HV_X64_MSR_HYPERCALL);
+ hypercall_msr.as_uint64 = hv_get_msr(HV_X64_MSR_HYPERCALL);
hypercall_msr.enable = 0;
- hv_set_register(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+ hv_set_msr(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
/* Reset the TSC page */
- tsc_msr.as_uint64 = hv_get_register(HV_X64_MSR_REFERENCE_TSC);
+ tsc_msr.as_uint64 = hv_get_msr(HV_X64_MSR_REFERENCE_TSC);
tsc_msr.enable = 0;
- hv_set_register(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
+ hv_set_msr(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
}
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 2ff26f53cd62..3787d26810c1 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -182,7 +182,7 @@ enum hv_isolation_type {
#define HV_X64_MSR_HYPERCALL 0x40000001
/* MSR used to provide vcpu index */
-#define HV_REGISTER_VP_INDEX 0x40000002
+#define HV_X64_MSR_VP_INDEX 0x40000002
/* MSR used to reset the guest OS. */
#define HV_X64_MSR_RESET 0x40000003
@@ -191,10 +191,10 @@ enum hv_isolation_type {
#define HV_X64_MSR_VP_RUNTIME 0x40000010
/* MSR used to read the per-partition time reference counter */
-#define HV_REGISTER_TIME_REF_COUNT 0x40000020
+#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
/* A partition's reference time stamp counter (TSC) page */
-#define HV_REGISTER_REFERENCE_TSC 0x40000021
+#define HV_X64_MSR_REFERENCE_TSC 0x40000021
/* MSR used to retrieve the TSC frequency */
#define HV_X64_MSR_TSC_FREQUENCY 0x40000022
@@ -209,61 +209,61 @@ enum hv_isolation_type {
#define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073
/* Define synthetic interrupt controller model specific registers. */
-#define HV_REGISTER_SCONTROL 0x40000080
-#define HV_REGISTER_SVERSION 0x40000081
-#define HV_REGISTER_SIEFP 0x40000082
-#define HV_REGISTER_SIMP 0x40000083
-#define HV_REGISTER_EOM 0x40000084
-#define HV_REGISTER_SINT0 0x40000090
-#define HV_REGISTER_SINT1 0x40000091
-#define HV_REGISTER_SINT2 0x40000092
-#define HV_REGISTER_SINT3 0x40000093
-#define HV_REGISTER_SINT4 0x40000094
-#define HV_REGISTER_SINT5 0x40000095
-#define HV_REGISTER_SINT6 0x40000096
-#define HV_REGISTER_SINT7 0x40000097
-#define HV_REGISTER_SINT8 0x40000098
-#define HV_REGISTER_SINT9 0x40000099
-#define HV_REGISTER_SINT10 0x4000009A
-#define HV_REGISTER_SINT11 0x4000009B
-#define HV_REGISTER_SINT12 0x4000009C
-#define HV_REGISTER_SINT13 0x4000009D
-#define HV_REGISTER_SINT14 0x4000009E
-#define HV_REGISTER_SINT15 0x4000009F
+#define HV_X64_MSR_SCONTROL 0x40000080
+#define HV_X64_MSR_SVERSION 0x40000081
+#define HV_X64_MSR_SIEFP 0x40000082
+#define HV_X64_MSR_SIMP 0x40000083
+#define HV_X64_MSR_EOM 0x40000084
+#define HV_X64_MSR_SINT0 0x40000090
+#define HV_X64_MSR_SINT1 0x40000091
+#define HV_X64_MSR_SINT2 0x40000092
+#define HV_X64_MSR_SINT3 0x40000093
+#define HV_X64_MSR_SINT4 0x40000094
+#define HV_X64_MSR_SINT5 0x40000095
+#define HV_X64_MSR_SINT6 0x40000096
+#define HV_X64_MSR_SINT7 0x40000097
+#define HV_X64_MSR_SINT8 0x40000098
+#define HV_X64_MSR_SINT9 0x40000099
+#define HV_X64_MSR_SINT10 0x4000009A
+#define HV_X64_MSR_SINT11 0x4000009B
+#define HV_X64_MSR_SINT12 0x4000009C
+#define HV_X64_MSR_SINT13 0x4000009D
+#define HV_X64_MSR_SINT14 0x4000009E
+#define HV_X64_MSR_SINT15 0x4000009F
/*
* Define synthetic interrupt controller model specific registers for
* nested hypervisor.
*/
-#define HV_REGISTER_NESTED_SCONTROL 0x40001080
-#define HV_REGISTER_NESTED_SVERSION 0x40001081
-#define HV_REGISTER_NESTED_SIEFP 0x40001082
-#define HV_REGISTER_NESTED_SIMP 0x40001083
-#define HV_REGISTER_NESTED_EOM 0x40001084
-#define HV_REGISTER_NESTED_SINT0 0x40001090
+#define HV_X64_MSR_NESTED_SCONTROL 0x40001080
+#define HV_X64_MSR_NESTED_SVERSION 0x40001081
+#define HV_X64_MSR_NESTED_SIEFP 0x40001082
+#define HV_X64_MSR_NESTED_SIMP 0x40001083
+#define HV_X64_MSR_NESTED_EOM 0x40001084
+#define HV_X64_MSR_NESTED_SINT0 0x40001090
/*
* Synthetic Timer MSRs. Four timers per vcpu.
*/
-#define HV_REGISTER_STIMER0_CONFIG 0x400000B0
-#define HV_REGISTER_STIMER0_COUNT 0x400000B1
-#define HV_REGISTER_STIMER1_CONFIG 0x400000B2
-#define HV_REGISTER_STIMER1_COUNT 0x400000B3
-#define HV_REGISTER_STIMER2_CONFIG 0x400000B4
-#define HV_REGISTER_STIMER2_COUNT 0x400000B5
-#define HV_REGISTER_STIMER3_CONFIG 0x400000B6
-#define HV_REGISTER_STIMER3_COUNT 0x400000B7
+#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0
+#define HV_X64_MSR_STIMER0_COUNT 0x400000B1
+#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2
+#define HV_X64_MSR_STIMER1_COUNT 0x400000B3
+#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4
+#define HV_X64_MSR_STIMER2_COUNT 0x400000B5
+#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
+#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
/* Hyper-V guest idle MSR */
#define HV_X64_MSR_GUEST_IDLE 0x400000F0
/* Hyper-V guest crash notification MSR's */
-#define HV_REGISTER_CRASH_P0 0x40000100
-#define HV_REGISTER_CRASH_P1 0x40000101
-#define HV_REGISTER_CRASH_P2 0x40000102
-#define HV_REGISTER_CRASH_P3 0x40000103
-#define HV_REGISTER_CRASH_P4 0x40000104
-#define HV_REGISTER_CRASH_CTL 0x40000105
+#define HV_X64_MSR_CRASH_P0 0x40000100
+#define HV_X64_MSR_CRASH_P1 0x40000101
+#define HV_X64_MSR_CRASH_P2 0x40000102
+#define HV_X64_MSR_CRASH_P3 0x40000103
+#define HV_X64_MSR_CRASH_P4 0x40000104
+#define HV_X64_MSR_CRASH_CTL 0x40000105
/* TSC emulation after migration */
#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106
@@ -276,31 +276,38 @@ enum hv_isolation_type {
/* HV_X64_MSR_TSC_INVARIANT_CONTROL bits */
#define HV_EXPOSE_INVARIANT_TSC BIT_ULL(0)
-/* Register name aliases for temporary compatibility */
-#define HV_X64_MSR_STIMER0_COUNT HV_REGISTER_STIMER0_COUNT
-#define HV_X64_MSR_STIMER0_CONFIG HV_REGISTER_STIMER0_CONFIG
-#define HV_X64_MSR_STIMER1_COUNT HV_REGISTER_STIMER1_COUNT
-#define HV_X64_MSR_STIMER1_CONFIG HV_REGISTER_STIMER1_CONFIG
-#define HV_X64_MSR_STIMER2_COUNT HV_REGISTER_STIMER2_COUNT
-#define HV_X64_MSR_STIMER2_CONFIG HV_REGISTER_STIMER2_CONFIG
-#define HV_X64_MSR_STIMER3_COUNT HV_REGISTER_STIMER3_COUNT
-#define HV_X64_MSR_STIMER3_CONFIG HV_REGISTER_STIMER3_CONFIG
-#define HV_X64_MSR_SCONTROL HV_REGISTER_SCONTROL
-#define HV_X64_MSR_SVERSION HV_REGISTER_SVERSION
-#define HV_X64_MSR_SIMP HV_REGISTER_SIMP
-#define HV_X64_MSR_SIEFP HV_REGISTER_SIEFP
-#define HV_X64_MSR_VP_INDEX HV_REGISTER_VP_INDEX
-#define HV_X64_MSR_EOM HV_REGISTER_EOM
-#define HV_X64_MSR_SINT0 HV_REGISTER_SINT0
-#define HV_X64_MSR_SINT15 HV_REGISTER_SINT15
-#define HV_X64_MSR_CRASH_P0 HV_REGISTER_CRASH_P0
-#define HV_X64_MSR_CRASH_P1 HV_REGISTER_CRASH_P1
-#define HV_X64_MSR_CRASH_P2 HV_REGISTER_CRASH_P2
-#define HV_X64_MSR_CRASH_P3 HV_REGISTER_CRASH_P3
-#define HV_X64_MSR_CRASH_P4 HV_REGISTER_CRASH_P4
-#define HV_X64_MSR_CRASH_CTL HV_REGISTER_CRASH_CTL
-#define HV_X64_MSR_TIME_REF_COUNT HV_REGISTER_TIME_REF_COUNT
-#define HV_X64_MSR_REFERENCE_TSC HV_REGISTER_REFERENCE_TSC
+/*
+ * To support arch-generic code calling hv_set/get_register:
+ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
+ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
+ */
+#define HV_MSR_CRASH_P0 (HV_X64_MSR_CRASH_P0)
+#define HV_MSR_CRASH_P1 (HV_X64_MSR_CRASH_P1)
+#define HV_MSR_CRASH_P2 (HV_X64_MSR_CRASH_P2)
+#define HV_MSR_CRASH_P3 (HV_X64_MSR_CRASH_P3)
+#define HV_MSR_CRASH_P4 (HV_X64_MSR_CRASH_P4)
+#define HV_MSR_CRASH_CTL (HV_X64_MSR_CRASH_CTL)
+
+#define HV_MSR_VP_INDEX (HV_X64_MSR_VP_INDEX)
+#define HV_MSR_TIME_REF_COUNT (HV_X64_MSR_TIME_REF_COUNT)
+#define HV_MSR_REFERENCE_TSC (HV_X64_MSR_REFERENCE_TSC)
+
+#define HV_MSR_SINT0 (HV_X64_MSR_SINT0)
+#define HV_MSR_SVERSION (HV_X64_MSR_SVERSION)
+#define HV_MSR_SCONTROL (HV_X64_MSR_SCONTROL)
+#define HV_MSR_SIEFP (HV_X64_MSR_SIEFP)
+#define HV_MSR_SIMP (HV_X64_MSR_SIMP)
+#define HV_MSR_EOM (HV_X64_MSR_EOM)
+
+#define HV_MSR_NESTED_SCONTROL (HV_X64_MSR_NESTED_SCONTROL)
+#define HV_MSR_NESTED_SVERSION (HV_X64_MSR_NESTED_SVERSION)
+#define HV_MSR_NESTED_SIEFP (HV_X64_MSR_NESTED_SIEFP)
+#define HV_MSR_NESTED_SIMP (HV_X64_MSR_NESTED_SIMP)
+#define HV_MSR_NESTED_EOM (HV_X64_MSR_NESTED_EOM)
+#define HV_MSR_NESTED_SINT0 (HV_X64_MSR_NESTED_SINT0)
+
+#define HV_MSR_STIMER0_CONFIG (HV_X64_MSR_STIMER0_CONFIG)
+#define HV_MSR_STIMER0_COUNT (HV_X64_MSR_STIMER0_COUNT)
/*
* Registers are only accessible via HVCALL_GET_VP_REGISTERS hvcall and
diff --git a/arch/x86/include/asm/kfence.h b/arch/x86/include/asm/kfence.h
index ff5c7134a37a..acf9ffa1a171 100644
--- a/arch/x86/include/asm/kfence.h
+++ b/arch/x86/include/asm/kfence.h
@@ -42,10 +42,34 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
unsigned int level;
pte_t *pte = lookup_address(addr, &level);
+ pteval_t val;
if (WARN_ON(!pte || level != PG_LEVEL_4K))
return false;
+ val = pte_val(*pte);
+
+ /*
+ * protect requires making the page not-present. If the PTE is
+ * already in the right state, there's nothing to do.
+ */
+ if (protect != !!(val & _PAGE_PRESENT))
+ return true;
+
+ /*
+ * Otherwise, invert the entire PTE. This avoids writing out an
+ * L1TF-vulnerable PTE (not present, without the high address bits
+ * set).
+ */
+ set_pte(pte, __pte(~val));
+
+ /*
+ * If the page was protected (non-present) and we're making it
+ * present, there is no need to flush the TLB at all.
+ */
+ if (!protect)
+ return true;
+
/*
* We need to avoid IPIs, as we may get KFENCE allocations or faults
* with interrupts disabled. Therefore, the below is best-effort, and
@@ -53,11 +77,6 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect)
* lazy fault handling takes care of faults after the page is PRESENT.
*/
- if (protect)
- set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT));
- else
- set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT));
-
/*
* Flush this CPU's TLB, assuming whoever did the allocation/free is
* likely to continue running on this CPU.
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index ec95d6e9f168..aa76687ce520 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -292,24 +292,24 @@ static inline void hv_ivm_msr_write(u64 msr, u64 value) {}
static inline void hv_ivm_msr_read(u64 msr, u64 *value) {}
#endif
-static inline bool hv_is_synic_reg(unsigned int reg)
+static inline bool hv_is_synic_msr(unsigned int reg)
{
- return (reg >= HV_REGISTER_SCONTROL) &&
- (reg <= HV_REGISTER_SINT15);
+ return (reg >= HV_X64_MSR_SCONTROL) &&
+ (reg <= HV_X64_MSR_SINT15);
}
-static inline bool hv_is_sint_reg(unsigned int reg)
+static inline bool hv_is_sint_msr(unsigned int reg)
{
- return (reg >= HV_REGISTER_SINT0) &&
- (reg <= HV_REGISTER_SINT15);
+ return (reg >= HV_X64_MSR_SINT0) &&
+ (reg <= HV_X64_MSR_SINT15);
}
-u64 hv_get_register(unsigned int reg);
-void hv_set_register(unsigned int reg, u64 value);
-u64 hv_get_non_nested_register(unsigned int reg);
-void hv_set_non_nested_register(unsigned int reg, u64 value);
+u64 hv_get_msr(unsigned int reg);
+void hv_set_msr(unsigned int reg, u64 value);
+u64 hv_get_non_nested_msr(unsigned int reg);
+void hv_set_non_nested_msr(unsigned int reg, u64 value);
-static __always_inline u64 hv_raw_get_register(unsigned int reg)
+static __always_inline u64 hv_raw_get_msr(unsigned int reg)
{
return __rdmsr(reg);
}
@@ -330,10 +330,10 @@ static inline int hyperv_flush_guest_mapping_range(u64 as,
{
return -1;
}
-static inline void hv_set_register(unsigned int reg, u64 value) { }
-static inline u64 hv_get_register(unsigned int reg) { return 0; }
-static inline void hv_set_non_nested_register(unsigned int reg, u64 value) { }
-static inline u64 hv_get_non_nested_register(unsigned int reg) { return 0; }
+static inline void hv_set_msr(unsigned int reg, u64 value) { }
+static inline u64 hv_get_msr(unsigned int reg) { return 0; }
+static inline void hv_set_non_nested_msr(unsigned int reg, u64 value) { }
+static inline u64 hv_get_non_nested_msr(unsigned int reg) { return 0; }
#endif /* CONFIG_HYPERV */
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index e709070eed70..fc692125d82f 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -44,70 +44,70 @@ bool hyperv_paravisor_present __ro_after_init;
EXPORT_SYMBOL_GPL(hyperv_paravisor_present);
#if IS_ENABLED(CONFIG_HYPERV)
-static inline unsigned int hv_get_nested_reg(unsigned int reg)
+static inline unsigned int hv_get_nested_msr(unsigned int reg)
{
- if (hv_is_sint_reg(reg))
- return reg - HV_REGISTER_SINT0 + HV_REGISTER_NESTED_SINT0;
+ if (hv_is_sint_msr(reg))
+ return reg - HV_X64_MSR_SINT0 + HV_X64_MSR_NESTED_SINT0;
switch (reg) {
- case HV_REGISTER_SIMP:
- return HV_REGISTER_NESTED_SIMP;
- case HV_REGISTER_SIEFP:
- return HV_REGISTER_NESTED_SIEFP;
- case HV_REGISTER_SVERSION:
- return HV_REGISTER_NESTED_SVERSION;
- case HV_REGISTER_SCONTROL:
- return HV_REGISTER_NESTED_SCONTROL;
- case HV_REGISTER_EOM:
- return HV_REGISTER_NESTED_EOM;
+ case HV_X64_MSR_SIMP:
+ return HV_X64_MSR_NESTED_SIMP;
+ case HV_X64_MSR_SIEFP:
+ return HV_X64_MSR_NESTED_SIEFP;
+ case HV_X64_MSR_SVERSION:
+ return HV_X64_MSR_NESTED_SVERSION;
+ case HV_X64_MSR_SCONTROL:
+ return HV_X64_MSR_NESTED_SCONTROL;
+ case HV_X64_MSR_EOM:
+ return HV_X64_MSR_NESTED_EOM;
default:
return reg;
}
}
-u64 hv_get_non_nested_register(unsigned int reg)
+u64 hv_get_non_nested_msr(unsigned int reg)
{
u64 value;
- if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present)
+ if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present)
hv_ivm_msr_read(reg, &value);
else
rdmsrl(reg, value);
return value;
}
-EXPORT_SYMBOL_GPL(hv_get_non_nested_register);
+EXPORT_SYMBOL_GPL(hv_get_non_nested_msr);
-void hv_set_non_nested_register(unsigned int reg, u64 value)
+void hv_set_non_nested_msr(unsigned int reg, u64 value)
{
- if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present) {
+ if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) {
hv_ivm_msr_write(reg, value);
/* Write proxy bit via wrmsl instruction */
- if (hv_is_sint_reg(reg))
+ if (hv_is_sint_msr(reg))
wrmsrl(reg, value | 1 << 20);
} else {
wrmsrl(reg, value);
}
}
-EXPORT_SYMBOL_GPL(hv_set_non_nested_register);
+EXPORT_SYMBOL_GPL(hv_set_non_nested_msr);
-u64 hv_get_register(unsigned int reg)
+u64 hv_get_msr(unsigned int reg)
{
if (hv_nested)
- reg = hv_get_nested_reg(reg);
+ reg = hv_get_nested_msr(reg);
- return hv_get_non_nested_register(reg);
+ return hv_get_non_nested_msr(reg);
}
-EXPORT_SYMBOL_GPL(hv_get_register);
+EXPORT_SYMBOL_GPL(hv_get_msr);
-void hv_set_register(unsigned int reg, u64 value)
+void hv_set_msr(unsigned int reg, u64 value)
{
if (hv_nested)
- reg = hv_get_nested_reg(reg);
+ reg = hv_get_nested_msr(reg);
- hv_set_non_nested_register(reg, value);
+ hv_set_non_nested_msr(reg, value);
}
-EXPORT_SYMBOL_GPL(hv_set_register);
+EXPORT_SYMBOL_GPL(hv_set_msr);
static void (*vmbus_handler)(void);
static void (*hv_stimer0_handler)(void);
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 10830995eada..fd9959df7548 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -755,7 +755,8 @@ static __init bool get_mem_config(void)
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
return __get_mem_config_intel(&hw_res->r_resctrl);
- else if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ else if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
return __rdt_get_mem_config_amd(&hw_res->r_resctrl);
return false;
@@ -907,7 +908,8 @@ static __init void rdt_init_res_defs(void)
{
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
rdt_init_res_defs_intel();
- else if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ else if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
rdt_init_res_defs_amd();
}
@@ -938,8 +940,19 @@ void resctrl_cpu_detect(struct cpuinfo_x86 *c)
c->x86_cache_occ_scale = ebx;
c->x86_cache_mbm_width_offset = eax & 0xff;
- if (c->x86_vendor == X86_VENDOR_AMD && !c->x86_cache_mbm_width_offset)
- c->x86_cache_mbm_width_offset = MBM_CNTR_WIDTH_OFFSET_AMD;
+ if (!c->x86_cache_mbm_width_offset) {
+ switch (c->x86_vendor) {
+ case X86_VENDOR_AMD:
+ c->x86_cache_mbm_width_offset = MBM_CNTR_WIDTH_OFFSET_AMD;
+ break;
+ case X86_VENDOR_HYGON:
+ c->x86_cache_mbm_width_offset = MBM_CNTR_WIDTH_OFFSET_HYGON;
+ break;
+ default:
+ /* Leave c->x86_cache_mbm_width_offset as 0 */
+ break;
+ }
+ }
}
}
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 566386abb877..aafefaea0f26 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -20,6 +20,9 @@
#define MBA_IS_LINEAR 0x4
#define MBM_CNTR_WIDTH_OFFSET_AMD 20
+/* Hygon MBM counter width as an offset from MBM_CNTR_WIDTH_BASE */
+#define MBM_CNTR_WIDTH_OFFSET_HYGON 8
+
#define RMID_VAL_ERROR BIT_ULL(63)
#define RMID_VAL_UNAVAIL BIT_ULL(62)
/*
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index 175c14567cf1..75dad6e3c984 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -294,10 +294,29 @@ EXPORT_SYMBOL_GPL(fpu_enable_guest_xfd_features);
#ifdef CONFIG_X86_64
void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd)
{
+ struct fpstate *fpstate = guest_fpu->fpstate;
+
fpregs_lock();
- guest_fpu->fpstate->xfd = xfd;
- if (guest_fpu->fpstate->in_use)
- xfd_update_state(guest_fpu->fpstate);
+
+ /*
+ * KVM's guest ABI is that setting XFD[i]=1 *can* immediately revert the
+ * save state to its initial configuration. Likewise, KVM_GET_XSAVE does
+ * the same as XSAVE and returns XSTATE_BV[i]=0 whenever XFD[i]=1.
+ *
+ * If the guest's FPU state is in hardware, just update XFD: the XSAVE
+ * in fpu_swap_kvm_fpstate will clear XSTATE_BV[i] whenever XFD[i]=1.
+ *
+ * If however the guest's FPU state is NOT resident in hardware, clear
+ * disabled components in XSTATE_BV now, or a subsequent XRSTOR will
+ * attempt to load disabled components and generate #NM _in the host_.
+ */
+ if (xfd && test_thread_flag(TIF_NEED_FPU_LOAD))
+ fpstate->regs.xsave.header.xfeatures &= ~xfd;
+
+ fpstate->xfd = xfd;
+ if (fpstate->in_use)
+ xfd_update_state(fpstate);
+
fpregs_unlock();
}
EXPORT_SYMBOL_GPL(fpu_update_guest_xfd);
@@ -405,6 +424,13 @@ int fpu_copy_uabi_to_guest_fpstate(struct fpu_guest *gfpu, const void *buf,
if (ustate->xsave.header.xfeatures & ~xcr0)
return -EINVAL;
+ /*
+ * Disabled features must be in their initial state, otherwise XRSTOR
+ * causes an exception.
+ */
+ if (WARN_ON_ONCE(ustate->xsave.header.xfeatures & kstate->xfd))
+ return -EINVAL;
+
/*
* Nullify @vpkru to preserve its current value if PKRU's bit isn't set
* in the header. KVM's odd ABI is to leave PKRU untouched in this
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 8acaaa8f17b9..89df215ebf28 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -5432,9 +5432,18 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
struct kvm_xsave *guest_xsave)
{
+ union fpregs_state *xstate = (union fpregs_state *)guest_xsave->region;
+
if (fpstate_is_confidential(&vcpu->arch.guest_fpu))
return 0;
+ /*
+ * For backwards compatibility, do not expect disabled features to be in
+ * their initial state. XSTATE_BV[i] must still be cleared whenever
+ * XFD[i]=1, or XRSTOR would cause a #NM.
+ */
+ xstate->xsave.header.xfeatures &= ~vcpu->arch.guest_fpu.fpstate->xfd;
+
return fpu_copy_uabi_to_guest_fpstate(&vcpu->arch.guest_fpu,
guest_xsave->region,
kvm_caps.supported_xcr0,
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 6529b3e2cff3..4890cafea7b6 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -815,8 +815,6 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
force_sig_pkuerr((void __user *)address, pkey);
else
force_sig_fault(SIGSEGV, si_code, (void __user *)address);
-
- local_irq_disable();
}
static noinline void
@@ -1463,15 +1461,12 @@ handle_page_fault(struct pt_regs *regs, unsigned long error_code,
do_kern_addr_fault(regs, error_code, address);
} else {
do_user_addr_fault(regs, error_code, address);
- /*
- * User address page fault handling might have reenabled
- * interrupts. Fixing up all potential exit points of
- * do_user_addr_fault() and its leaf functions is just not
- * doable w/o creating an unholy mess or turning the code
- * upside down.
- */
- local_irq_disable();
}
+ /*
+ * page fault handling might have reenabled interrupts,
+ * make sure to disable them again.
+ */
+ local_irq_disable();
}
DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)
diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c
index e0b0ec0f8245..7e3dc0cead96 100644
--- a/arch/x86/mm/kaslr.c
+++ b/arch/x86/mm/kaslr.c
@@ -111,12 +111,12 @@ void __init kernel_randomize_memory(void)
/*
* Adapt physical memory region size based on available memory,
- * except when CONFIG_PCI_P2PDMA is enabled. P2PDMA exposes the
- * device BAR space assuming the direct map space is large enough
- * for creating a ZONE_DEVICE mapping in the direct map corresponding
- * to the physical BAR address.
+ * except when CONFIG_ZONE_DEVICE is enabled. ZONE_DEVICE wants to map
+ * any physical address into the direct-map. KASLR wants to reliably
+ * steal some physical address bits. Those design choices are in direct
+ * conflict.
*/
- if (!IS_ENABLED(CONFIG_PCI_P2PDMA) && (memory_tb < kaslr_regions[0].size_tb))
+ if (!IS_ENABLED(CONFIG_ZONE_DEVICE) && (memory_tb < kaslr_regions[0].size_tb))
kaslr_regions[0].size_tb = memory_tb;
/*
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index 91424e791d5c..29ff3a0e86c0 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -189,6 +189,9 @@ static int crypto_authenc_esn_encrypt(struct aead_request *req)
struct scatterlist *src, *dst;
int err;
+ if (assoclen < 8)
+ return -EINVAL;
+
sg_init_table(areq_ctx->src, 2);
src = scatterwalk_ffwd(areq_ctx->src, req->src, assoclen);
dst = src;
@@ -281,6 +284,9 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req)
u32 tmp[2];
int err;
+ if (assoclen < 8)
+ return -EINVAL;
+
cryptlen -= authsize;
if (req->src != dst) {
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index f627753519b9..d5e713f284b7 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2780,9 +2780,33 @@ static void ata_dev_config_cpr(struct ata_device *dev)
kfree(buf);
}
+/*
+ * Configure features related to link power management.
+ */
+static void ata_dev_config_lpm(struct ata_device *dev)
+{
+ struct ata_port *ap = dev->link->ap;
+ unsigned int err_mask;
+
+ /*
+ * Device Initiated Power Management (DIPM) is normally disabled by
+ * default on a device. However, DIPM may have been enabled and that
+ * setting kept even after COMRESET because of the Software Settings
+ * Preservation feature. So if the port does not support DIPM and the
+ * device does, disable DIPM on the device.
+ */
+ if (ap->flags & ATA_FLAG_NO_DIPM && ata_id_has_dipm(dev->id)) {
+ err_mask = ata_dev_set_feature(dev,
+ SETFEATURES_SATA_DISABLE, SATA_DIPM);
+ if (err_mask && err_mask != AC_ERR_DEV)
+ ata_dev_err(dev, "Disable DIPM failed, Emask 0x%x\n",
+ err_mask);
+ }
+}
+
static void ata_dev_print_features(struct ata_device *dev)
{
- if (!(dev->flags & ATA_DFLAG_FEATURES_MASK))
+ if (!(dev->flags & ATA_DFLAG_FEATURES_MASK) && !dev->cpr_log)
return;
ata_dev_info(dev,
@@ -2949,6 +2973,7 @@ int ata_dev_configure(struct ata_device *dev)
ata_dev_config_chs(dev);
}
+ ata_dev_config_lpm(dev);
ata_dev_config_fua(dev);
ata_dev_config_devslp(dev);
ata_dev_config_sense_reporting(dev);
@@ -3022,6 +3047,11 @@ int ata_dev_configure(struct ata_device *dev)
ata_mode_string(xfer_mask),
cdb_intr_string, atapi_an_string,
dma_dir_string);
+
+ ata_dev_config_lpm(dev);
+
+ if (print_info)
+ ata_dev_print_features(dev);
}
/* determine max_sectors */
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 9603c28a3ed8..48860beff95c 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -408,9 +408,11 @@ static void regmap_lock_hwlock_irq(void *__map)
static void regmap_lock_hwlock_irqsave(void *__map)
{
struct regmap *map = __map;
+ unsigned long flags = 0;
hwspin_lock_timeout_irqsave(map->hwlock, UINT_MAX,
- &map->spinlock_flags);
+ &flags);
+ map->spinlock_flags = flags;
}
static void regmap_unlock_hwlock(void *__map)
diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
index 2dd254c720f5..355b23f3fc5d 100644
--- a/drivers/block/null_blk/main.c
+++ b/drivers/block/null_blk/main.c
@@ -622,12 +622,22 @@ static void nullb_add_fault_config(struct nullb_device *dev)
configfs_add_default_group(&dev->init_hctx_fault_config.group, &dev->group);
}
+static void nullb_del_fault_config(struct nullb_device *dev)
+{
+ config_item_put(&dev->init_hctx_fault_config.group.cg_item);
+ config_item_put(&dev->requeue_config.group.cg_item);
+ config_item_put(&dev->timeout_config.group.cg_item);
+}
+
#else
static void nullb_add_fault_config(struct nullb_device *dev)
{
}
+static void nullb_del_fault_config(struct nullb_device *dev)
+{
+}
#endif
static struct
@@ -659,7 +669,7 @@ nullb_group_drop_item(struct config_group *group, struct config_item *item)
null_del_dev(dev->nullb);
mutex_unlock(&lock);
}
-
+ nullb_del_fault_config(dev);
config_item_put(item);
}
diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
index 5eec1457e139..51ee0a756681 100644
--- a/drivers/clocksource/hyperv_timer.c
+++ b/drivers/clocksource/hyperv_timer.c
@@ -82,14 +82,14 @@ static int hv_ce_set_next_event(unsigned long delta,
current_tick = hv_read_reference_counter();
current_tick += delta;
- hv_set_register(HV_REGISTER_STIMER0_COUNT, current_tick);
+ hv_set_msr(HV_MSR_STIMER0_COUNT, current_tick);
return 0;
}
static int hv_ce_shutdown(struct clock_event_device *evt)
{
- hv_set_register(HV_REGISTER_STIMER0_COUNT, 0);
- hv_set_register(HV_REGISTER_STIMER0_CONFIG, 0);
+ hv_set_msr(HV_MSR_STIMER0_COUNT, 0);
+ hv_set_msr(HV_MSR_STIMER0_CONFIG, 0);
if (direct_mode_enabled && stimer0_irq >= 0)
disable_percpu_irq(stimer0_irq);
@@ -120,7 +120,7 @@ static int hv_ce_set_oneshot(struct clock_event_device *evt)
timer_cfg.direct_mode = 0;
timer_cfg.sintx = stimer0_message_sint;
}
- hv_set_register(HV_REGISTER_STIMER0_CONFIG, timer_cfg.as_uint64);
+ hv_set_msr(HV_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);
return 0;
}
@@ -373,11 +373,11 @@ static __always_inline u64 read_hv_clock_msr(void)
* is set to 0 when the partition is created and is incremented in 100
* nanosecond units.
*
- * Use hv_raw_get_register() because this function is used from
- * noinstr. Notable; while HV_REGISTER_TIME_REF_COUNT is a synthetic
+ * Use hv_raw_get_msr() because this function is used from
+ * noinstr. Notable; while HV_MSR_TIME_REF_COUNT is a synthetic
* register it doesn't need the GHCB path.
*/
- return hv_raw_get_register(HV_REGISTER_TIME_REF_COUNT);
+ return hv_raw_get_msr(HV_MSR_TIME_REF_COUNT);
}
/*
@@ -440,9 +440,9 @@ static void suspend_hv_clock_tsc(struct clocksource *arg)
union hv_reference_tsc_msr tsc_msr;
/* Disable the TSC page */
- tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
+ tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC);
tsc_msr.enable = 0;
- hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
+ hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
}
@@ -451,10 +451,10 @@ static void resume_hv_clock_tsc(struct clocksource *arg)
union hv_reference_tsc_msr tsc_msr;
/* Re-enable the TSC page */
- tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
+ tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC);
tsc_msr.enable = 1;
tsc_msr.pfn = tsc_pfn;
- hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
+ hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
}
/*
@@ -567,14 +567,14 @@ static void __init hv_init_tsc_clocksource(void)
* thus TSC clocksource will work even without the real TSC page
* mapped.
*/
- tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
+ tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC);
if (hv_root_partition)
tsc_pfn = tsc_msr.pfn;
else
tsc_pfn = HVPFN_DOWN(virt_to_phys(tsc_page));
tsc_msr.enable = 1;
tsc_msr.pfn = tsc_pfn;
- hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
+ hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index da3071b387eb..3d542d0f7603 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -39,8 +39,9 @@ static int riscv_clock_next_event(unsigned long delta,
csr_set(CSR_IE, IE_TIE);
if (static_branch_likely(&riscv_sstc_available)) {
#if defined(CONFIG_32BIT)
- csr_write(CSR_STIMECMP, next_tval & 0xFFFFFFFF);
+ csr_write(CSR_STIMECMP, ULONG_MAX);
csr_write(CSR_STIMECMPH, next_tval >> 32);
+ csr_write(CSR_STIMECMP, next_tval & 0xFFFFFFFF);
#else
csr_write(CSR_STIMECMP, next_tval);
#endif
diff --git a/drivers/comedi/comedi_fops.c b/drivers/comedi/comedi_fops.c
index bb4fbfa80c82..12201ebf22eb 100644
--- a/drivers/comedi/comedi_fops.c
+++ b/drivers/comedi/comedi_fops.c
@@ -1099,7 +1099,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
for (i = 0; i < s->n_chan; i++) {
int x;
- x = (dev->minor << 28) | (it->subdev << 24) | (i << 16) |
+ x = (it->subdev << 24) | (i << 16) |
(s->range_table_list[i]->length);
if (put_user(x, it->rangelist + i))
return -EFAULT;
diff --git a/drivers/comedi/drivers/dmm32at.c b/drivers/comedi/drivers/dmm32at.c
index fe023c722aa3..d17cba93578c 100644
--- a/drivers/comedi/drivers/dmm32at.c
+++ b/drivers/comedi/drivers/dmm32at.c
@@ -330,6 +330,7 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev,
static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
{
+ unsigned long irq_flags;
unsigned char lo1, lo2, hi2;
unsigned short both2;
@@ -342,6 +343,9 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
/* set counter clocks to 10MHz, disable all aux dio */
outb(0, dev->iobase + DMM32AT_CTRDIO_CFG_REG);
+ /* serialize access to control register and paged registers */
+ spin_lock_irqsave(&dev->spinlock, irq_flags);
+
/* get access to the clock regs */
outb(DMM32AT_CTRL_PAGE_8254, dev->iobase + DMM32AT_CTRL_REG);
@@ -354,6 +358,8 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
outb(lo2, dev->iobase + DMM32AT_CLK2);
outb(hi2, dev->iobase + DMM32AT_CLK2);
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
/* enable the ai conversion interrupt and the clock to start scans */
outb(DMM32AT_INTCLK_ADINT |
DMM32AT_INTCLK_CLKEN | DMM32AT_INTCLK_CLKSEL,
@@ -363,13 +369,19 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned long irq_flags;
int ret;
dmm32at_ai_set_chanspec(dev, s, cmd->chanlist[0], cmd->chanlist_len);
+ /* serialize access to control register and paged registers */
+ spin_lock_irqsave(&dev->spinlock, irq_flags);
+
/* reset the interrupt just in case */
outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG);
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
/*
* wait for circuit to settle
* we don't have the 'insn' here but it's not needed
@@ -429,8 +441,13 @@ static irqreturn_t dmm32at_isr(int irq, void *d)
comedi_handle_events(dev, s);
}
+ /* serialize access to control register and paged registers */
+ spin_lock(&dev->spinlock);
+
/* reset the interrupt */
outb(DMM32AT_CTRL_INTRST, dev->iobase + DMM32AT_CTRL_REG);
+
+ spin_unlock(&dev->spinlock);
return IRQ_HANDLED;
}
@@ -481,14 +498,25 @@ static int dmm32at_ao_insn_write(struct comedi_device *dev,
static int dmm32at_8255_io(struct comedi_device *dev,
int dir, int port, int data, unsigned long regbase)
{
+ unsigned long irq_flags;
+ int ret;
+
+ /* serialize access to control register and paged registers */
+ spin_lock_irqsave(&dev->spinlock, irq_flags);
+
/* get access to the DIO regs */
outb(DMM32AT_CTRL_PAGE_8255, dev->iobase + DMM32AT_CTRL_REG);
if (dir) {
outb(data, dev->iobase + regbase + port);
- return 0;
+ ret = 0;
+ } else {
+ ret = inb(dev->iobase + regbase + port);
}
- return inb(dev->iobase + regbase + port);
+
+ spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return ret;
}
/* Make sure the board is there and put it to a known state */
diff --git a/drivers/comedi/range.c b/drivers/comedi/range.c
index 8f43cf88d784..5b8f662365e3 100644
--- a/drivers/comedi/range.c
+++ b/drivers/comedi/range.c
@@ -52,7 +52,7 @@ int do_rangeinfo_ioctl(struct comedi_device *dev,
const struct comedi_lrange *lr;
struct comedi_subdevice *s;
- subd = (it->range_type >> 24) & 0xf;
+ subd = (it->range_type >> 24) & 0xff;
chan = (it->range_type >> 16) & 0xff;
if (!dev->attached)
diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c
index 5b1457f6e3bf..4034ace367ab 100644
--- a/drivers/dma/apple-admac.c
+++ b/drivers/dma/apple-admac.c
@@ -938,6 +938,7 @@ static int admac_remove(struct platform_device *pdev)
}
static const struct of_device_id admac_of_match[] = {
+ { .compatible = "apple,t8103-admac", },
{ .compatible = "apple,admac", },
{ }
};
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index b2876f67471f..ce9b707e8ac1 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1755,6 +1755,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
static void atc_free_chan_resources(struct dma_chan *chan)
{
struct at_dma_chan *atchan = to_at_dma_chan(chan);
+ struct at_dma_slave *atslave;
BUG_ON(atc_chan_is_enabled(atchan));
@@ -1764,8 +1765,12 @@ static void atc_free_chan_resources(struct dma_chan *chan)
/*
* Free atslave allocated in at_dma_xlate()
*/
- kfree(chan->private);
- chan->private = NULL;
+ atslave = chan->private;
+ if (atslave) {
+ put_device(atslave->dma_dev);
+ kfree(atslave);
+ chan->private = NULL;
+ }
dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
}
diff --git a/drivers/dma/bcm-sba-raid.c b/drivers/dma/bcm-sba-raid.c
index 94ea35330eb5..7573860be162 100644
--- a/drivers/dma/bcm-sba-raid.c
+++ b/drivers/dma/bcm-sba-raid.c
@@ -1699,7 +1699,7 @@ static int sba_probe(struct platform_device *pdev)
/* Prealloc channel resource */
ret = sba_prealloc_channel_resources(sba);
if (ret)
- goto fail_free_mchan;
+ goto fail_put_mbox;
/* Check availability of debugfs */
if (!debugfs_initialized())
@@ -1729,6 +1729,8 @@ static int sba_probe(struct platform_device *pdev)
fail_free_resources:
debugfs_remove_recursive(sba->root);
sba_freeup_channel_resources(sba);
+fail_put_mbox:
+ put_device(sba->mbox_dev);
fail_free_mchan:
mbox_free_channel(sba->mchan);
return ret;
@@ -1744,6 +1746,8 @@ static int sba_remove(struct platform_device *pdev)
sba_freeup_channel_resources(sba);
+ put_device(sba->mbox_dev);
+
mbox_free_channel(sba->mchan);
return 0;
diff --git a/drivers/dma/dw/rzn1-dmamux.c b/drivers/dma/dw/rzn1-dmamux.c
index deadf135681b..cbec277af4dd 100644
--- a/drivers/dma/dw/rzn1-dmamux.c
+++ b/drivers/dma/dw/rzn1-dmamux.c
@@ -90,7 +90,7 @@ static void *rzn1_dmamux_route_allocate(struct of_phandle_args *dma_spec,
if (test_and_set_bit(map->req_idx, dmamux->used_chans)) {
ret = -EBUSY;
- goto free_map;
+ goto put_dma_spec_np;
}
mask = BIT(map->req_idx);
@@ -103,6 +103,8 @@ static void *rzn1_dmamux_route_allocate(struct of_phandle_args *dma_spec,
clear_bitmap:
clear_bit(map->req_idx, dmamux->used_chans);
+put_dma_spec_np:
+ of_node_put(dma_spec->np);
free_map:
kfree(map);
put_device:
diff --git a/drivers/dma/idxd/compat.c b/drivers/dma/idxd/compat.c
index 5fd38d1b9d28..ff73e0b11924 100644
--- a/drivers/dma/idxd/compat.c
+++ b/drivers/dma/idxd/compat.c
@@ -21,11 +21,16 @@ static ssize_t unbind_store(struct device_driver *drv, const char *buf, size_t c
int rc = -ENODEV;
dev = bus_find_device_by_name(bus, NULL, buf);
- if (dev && dev->driver) {
+ if (!dev)
+ return -ENODEV;
+
+ if (dev->driver) {
device_driver_detach(dev);
rc = count;
}
+ put_device(dev);
+
return rc;
}
static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, 0200, NULL, unbind_store);
@@ -39,9 +44,12 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t cou
struct idxd_dev *idxd_dev;
dev = bus_find_device_by_name(bus, NULL, buf);
- if (!dev || dev->driver || drv != &dsa_drv.drv)
+ if (!dev)
return -ENODEV;
+ if (dev->driver || drv != &dsa_drv.drv)
+ goto err_put_dev;
+
idxd_dev = confdev_to_idxd_dev(dev);
if (is_idxd_dev(idxd_dev)) {
alt_drv = driver_find("idxd", bus);
@@ -54,13 +62,20 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t cou
alt_drv = driver_find("user", bus);
}
if (!alt_drv)
- return -ENODEV;
+ goto err_put_dev;
rc = device_driver_attach(alt_drv, dev);
if (rc < 0)
- return rc;
+ goto err_put_dev;
+
+ put_device(dev);
return count;
+
+err_put_dev:
+ put_device(dev);
+
+ return rc;
}
static DRIVER_ATTR_IGNORE_LOCKDEP(bind, 0200, NULL, bind_store);
diff --git a/drivers/dma/lpc18xx-dmamux.c b/drivers/dma/lpc18xx-dmamux.c
index 2b6436f4b193..d3ff521951b8 100644
--- a/drivers/dma/lpc18xx-dmamux.c
+++ b/drivers/dma/lpc18xx-dmamux.c
@@ -57,30 +57,31 @@ static void *lpc18xx_dmamux_reserve(struct of_phandle_args *dma_spec,
struct lpc18xx_dmamux_data *dmamux = platform_get_drvdata(pdev);
unsigned long flags;
unsigned mux;
+ int ret = -EINVAL;
if (dma_spec->args_count != 3) {
dev_err(&pdev->dev, "invalid number of dma mux args\n");
- return ERR_PTR(-EINVAL);
+ goto err_put_pdev;
}
mux = dma_spec->args[0];
if (mux >= dmamux->dma_master_requests) {
dev_err(&pdev->dev, "invalid mux number: %d\n",
dma_spec->args[0]);
- return ERR_PTR(-EINVAL);
+ goto err_put_pdev;
}
if (dma_spec->args[1] > LPC18XX_DMAMUX_MAX_VAL) {
dev_err(&pdev->dev, "invalid dma mux value: %d\n",
dma_spec->args[1]);
- return ERR_PTR(-EINVAL);
+ goto err_put_pdev;
}
/* The of_node_put() will be done in the core for the node */
dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
if (!dma_spec->np) {
dev_err(&pdev->dev, "can't get dma master\n");
- return ERR_PTR(-EINVAL);
+ goto err_put_pdev;
}
spin_lock_irqsave(&dmamux->lock, flags);
@@ -89,7 +90,8 @@ static void *lpc18xx_dmamux_reserve(struct of_phandle_args *dma_spec,
dev_err(&pdev->dev, "dma request %u busy with %u.%u\n",
mux, mux, dmamux->muxes[mux].value);
of_node_put(dma_spec->np);
- return ERR_PTR(-EBUSY);
+ ret = -EBUSY;
+ goto err_put_pdev;
}
dmamux->muxes[mux].busy = true;
@@ -106,7 +108,14 @@ static void *lpc18xx_dmamux_reserve(struct of_phandle_args *dma_spec,
dev_dbg(&pdev->dev, "mapping dmamux %u.%u to dma request %u\n", mux,
dmamux->muxes[mux].value, mux);
+ put_device(&pdev->dev);
+
return &dmamux->muxes[mux];
+
+err_put_pdev:
+ put_device(&pdev->dev);
+
+ return ERR_PTR(ret);
}
static int lpc18xx_dmamux_probe(struct platform_device *pdev)
diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c
index 1c93864e0e4d..36830efd13f7 100644
--- a/drivers/dma/qcom/gpi.c
+++ b/drivers/dma/qcom/gpi.c
@@ -1621,14 +1621,16 @@ static int
gpi_peripheral_config(struct dma_chan *chan, struct dma_slave_config *config)
{
struct gchan *gchan = to_gchan(chan);
+ void *new_config;
if (!config->peripheral_config)
return -EINVAL;
- gchan->config = krealloc(gchan->config, config->peripheral_size, GFP_NOWAIT);
- if (!gchan->config)
+ new_config = krealloc(gchan->config, config->peripheral_size, GFP_NOWAIT);
+ if (!new_config)
return -ENOMEM;
+ gchan->config = new_config;
memcpy(gchan->config, config->peripheral_config, config->peripheral_size);
return 0;
diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c
index f777addda8ba..d11be1884774 100644
--- a/drivers/dma/sh/rz-dmac.c
+++ b/drivers/dma/sh/rz-dmac.c
@@ -533,11 +533,16 @@ rz_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
static int rz_dmac_terminate_all(struct dma_chan *chan)
{
struct rz_dmac_chan *channel = to_rz_dmac_chan(chan);
+ struct rz_lmdesc *lmdesc = channel->lmdesc.base;
unsigned long flags;
+ unsigned int i;
LIST_HEAD(head);
rz_dmac_disable_hw(channel);
spin_lock_irqsave(&channel->vc.lock, flags);
+ for (i = 0; i < DMAC_NR_LMDESC; i++)
+ lmdesc[i].header = 0;
+
list_splice_tail_init(&channel->ld_active, &channel->ld_free);
list_splice_tail_init(&channel->ld_queue, &channel->ld_free);
spin_unlock_irqrestore(&channel->vc.lock, flags);
diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
index 8d77e2a7939a..2bd218dbabbb 100644
--- a/drivers/dma/stm32-dmamux.c
+++ b/drivers/dma/stm32-dmamux.c
@@ -90,23 +90,25 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
struct stm32_dmamux_data *dmamux = platform_get_drvdata(pdev);
struct stm32_dmamux *mux;
u32 i, min, max;
- int ret;
+ int ret = -EINVAL;
unsigned long flags;
if (dma_spec->args_count != 3) {
dev_err(&pdev->dev, "invalid number of dma mux args\n");
- return ERR_PTR(-EINVAL);
+ goto err_put_pdev;
}
if (dma_spec->args[0] > dmamux->dmamux_requests) {
dev_err(&pdev->dev, "invalid mux request number: %d\n",
dma_spec->args[0]);
- return ERR_PTR(-EINVAL);
+ goto err_put_pdev;
}
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
- if (!mux)
- return ERR_PTR(-ENOMEM);
+ if (!mux) {
+ ret = -ENOMEM;
+ goto err_put_pdev;
+ }
spin_lock_irqsave(&dmamux->lock, flags);
mux->chan_id = find_first_zero_bit(dmamux->dma_inuse,
@@ -133,7 +135,6 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", i - 1);
if (!dma_spec->np) {
dev_err(&pdev->dev, "can't get dma master\n");
- ret = -EINVAL;
goto error;
}
@@ -142,7 +143,7 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret < 0) {
spin_unlock_irqrestore(&dmamux->lock, flags);
- goto error;
+ goto err_put_dma_spec_np;
}
spin_unlock_irqrestore(&dmamux->lock, flags);
@@ -160,13 +161,20 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec,
dev_dbg(&pdev->dev, "Mapping DMAMUX(%u) to DMA%u(%u)\n",
mux->request, mux->master, mux->chan_id);
+ put_device(&pdev->dev);
+
return mux;
+err_put_dma_spec_np:
+ of_node_put(dma_spec->np);
error:
clear_bit(mux->chan_id, dmamux->dma_inuse);
error_chan_id:
kfree(mux);
+err_put_pdev:
+ put_device(&pdev->dev);
+
return ERR_PTR(ret);
}
diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c
index e557bada1510..37848d558ae4 100644
--- a/drivers/dma/tegra210-adma.c
+++ b/drivers/dma/tegra210-adma.c
@@ -342,10 +342,17 @@ static void tegra_adma_stop(struct tegra_adma_chan *tdc)
return;
}
- kfree(tdc->desc);
+ vchan_terminate_vdesc(&tdc->desc->vd);
tdc->desc = NULL;
}
+static void tegra_adma_synchronize(struct dma_chan *dc)
+{
+ struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
+
+ vchan_synchronize(&tdc->vc);
+}
+
static void tegra_adma_start(struct tegra_adma_chan *tdc)
{
struct virt_dma_desc *vd = vchan_next_desc(&tdc->vc);
@@ -909,6 +916,7 @@ static int tegra_adma_probe(struct platform_device *pdev)
tdma->dma_dev.device_config = tegra_adma_slave_config;
tdma->dma_dev.device_tx_status = tegra_adma_tx_status;
tdma->dma_dev.device_terminate_all = tegra_adma_terminate_all;
+ tdma->dma_dev.device_synchronize = tegra_adma_synchronize;
tdma->dma_dev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
tdma->dma_dev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
tdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
diff --git a/drivers/dma/ti/dma-crossbar.c b/drivers/dma/ti/dma-crossbar.c
index 7f17ee87a6dc..ff05b150ad37 100644
--- a/drivers/dma/ti/dma-crossbar.c
+++ b/drivers/dma/ti/dma-crossbar.c
@@ -79,34 +79,35 @@ static void *ti_am335x_xbar_route_allocate(struct of_phandle_args *dma_spec,
{
struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
struct ti_am335x_xbar_data *xbar = platform_get_drvdata(pdev);
- struct ti_am335x_xbar_map *map;
+ struct ti_am335x_xbar_map *map = ERR_PTR(-EINVAL);
if (dma_spec->args_count != 3)
- return ERR_PTR(-EINVAL);
+ goto out_put_pdev;
if (dma_spec->args[2] >= xbar->xbar_events) {
dev_err(&pdev->dev, "Invalid XBAR event number: %d\n",
dma_spec->args[2]);
- return ERR_PTR(-EINVAL);
+ goto out_put_pdev;
}
if (dma_spec->args[0] >= xbar->dma_requests) {
dev_err(&pdev->dev, "Invalid DMA request line number: %d\n",
dma_spec->args[0]);
- return ERR_PTR(-EINVAL);
+ goto out_put_pdev;
}
/* The of_node_put() will be done in the core for the node */
dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
if (!dma_spec->np) {
dev_err(&pdev->dev, "Can't get DMA master\n");
- return ERR_PTR(-EINVAL);
+ goto out_put_pdev;
}
map = kzalloc(sizeof(*map), GFP_KERNEL);
if (!map) {
of_node_put(dma_spec->np);
- return ERR_PTR(-ENOMEM);
+ map = ERR_PTR(-ENOMEM);
+ goto out_put_pdev;
}
map->dma_line = (u16)dma_spec->args[0];
@@ -120,6 +121,9 @@ static void *ti_am335x_xbar_route_allocate(struct of_phandle_args *dma_spec,
ti_am335x_xbar_write(xbar->iomem, map->dma_line, map->mux_val);
+out_put_pdev:
+ put_device(&pdev->dev);
+
return map;
}
@@ -288,6 +292,8 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec,
ti_dra7_xbar_write(xbar->iomem, map->xbar_out, map->xbar_in);
+ put_device(&pdev->dev);
+
return map;
}
diff --git a/drivers/dma/ti/k3-udma-private.c b/drivers/dma/ti/k3-udma-private.c
index 05228bf00033..624360423ef1 100644
--- a/drivers/dma/ti/k3-udma-private.c
+++ b/drivers/dma/ti/k3-udma-private.c
@@ -42,9 +42,9 @@ struct udma_dev *of_xudma_dev_get(struct device_node *np, const char *property)
}
ud = platform_get_drvdata(pdev);
+ put_device(&pdev->dev);
if (!ud) {
pr_debug("UDMA has not been probed\n");
- put_device(&pdev->dev);
return ERR_PTR(-EPROBE_DEFER);
}
diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c
index cf96cf915c0c..efc9093707e5 100644
--- a/drivers/dma/ti/omap-dma.c
+++ b/drivers/dma/ti/omap-dma.c
@@ -1809,6 +1809,8 @@ static int omap_dma_probe(struct platform_device *pdev)
if (rc) {
pr_warn("OMAP-DMA: failed to register slave DMA engine device: %d\n",
rc);
+ if (od->ll123_supported)
+ dma_pool_destroy(od->desc_pool);
omap_dma_free(od);
return rc;
}
@@ -1824,6 +1826,8 @@ static int omap_dma_probe(struct platform_device *pdev)
if (rc) {
pr_warn("OMAP-DMA: failed to register DMA controller\n");
dma_async_device_unregister(&od->ddev);
+ if (od->ll123_supported)
+ dma_pool_destroy(od->desc_pool);
omap_dma_free(od);
}
}
diff --git a/drivers/dma/xilinx/xdma-regs.h b/drivers/dma/xilinx/xdma-regs.h
index dd98b4526b90..b19c173d8bfc 100644
--- a/drivers/dma/xilinx/xdma-regs.h
+++ b/drivers/dma/xilinx/xdma-regs.h
@@ -9,6 +9,7 @@
/* The length of register space exposed to host */
#define XDMA_REG_SPACE_LEN 65536
+#define XDMA_MAX_REG_OFFSET (XDMA_REG_SPACE_LEN - 4)
/*
* maximum number of DMA channels for each direction:
diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c
index e0bfd129d563..dbab4c449914 100644
--- a/drivers/dma/xilinx/xdma.c
+++ b/drivers/dma/xilinx/xdma.c
@@ -38,7 +38,7 @@ static const struct regmap_config xdma_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
- .max_register = XDMA_REG_SPACE_LEN,
+ .max_register = XDMA_MAX_REG_OFFSET,
};
/**
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 14c4c5031b55..176cac3f37a7 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -128,6 +128,7 @@
#define XILINX_MCDMA_MAX_CHANS_PER_DEVICE 0x20
#define XILINX_DMA_MAX_CHANS_PER_DEVICE 0x2
#define XILINX_CDMA_MAX_CHANS_PER_DEVICE 0x1
+#define XILINX_DMA_DFAULT_ADDRWIDTH 0x20
#define XILINX_DMA_DMAXR_ALL_IRQ_MASK \
(XILINX_DMA_DMASR_FRM_CNT_IRQ | \
@@ -3057,7 +3058,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
struct xilinx_dma_device *xdev;
struct device_node *child, *np = pdev->dev.of_node;
- u32 num_frames, addr_width, len_width;
+ u32 num_frames, addr_width = XILINX_DMA_DFAULT_ADDRWIDTH, len_width;
int i, err;
/* Allocate and initialize the DMA engine structure */
@@ -3131,7 +3132,9 @@ static int xilinx_dma_probe(struct platform_device *pdev)
err = of_property_read_u32(node, "xlnx,addrwidth", &addr_width);
if (err < 0)
- dev_warn(xdev->dev, "missing xlnx,addrwidth property\n");
+ dev_warn(xdev->dev,
+ "missing xlnx,addrwidth property, using default value %d\n",
+ XILINX_DMA_DFAULT_ADDRWIDTH);
if (addr_width > 32)
xdev->ext_addr = true;
diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c
index afccdebf5ac1..6cade6d7ceff 100644
--- a/drivers/edac/i3200_edac.c
+++ b/drivers/edac/i3200_edac.c
@@ -358,10 +358,11 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
layers[1].type = EDAC_MC_LAYER_CHANNEL;
layers[1].size = nr_channels;
layers[1].is_virt_csrow = false;
- mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
- sizeof(struct i3200_priv));
+
+ rc = -ENOMEM;
+ mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(struct i3200_priv));
if (!mci)
- return -ENOMEM;
+ goto unmap;
edac_dbg(3, "MC: init mci\n");
@@ -421,9 +422,9 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
return 0;
fail:
+ edac_mc_free(mci);
+unmap:
iounmap(window);
- if (mci)
- edac_mc_free(mci);
return rc;
}
diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c
index 49ab5721aab2..292dda754c23 100644
--- a/drivers/edac/x38_edac.c
+++ b/drivers/edac/x38_edac.c
@@ -341,9 +341,12 @@ static int x38_probe1(struct pci_dev *pdev, int dev_idx)
layers[1].type = EDAC_MC_LAYER_CHANNEL;
layers[1].size = x38_channel_num;
layers[1].is_virt_csrow = false;
+
+
+ rc = -ENOMEM;
mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0);
if (!mci)
- return -ENOMEM;
+ goto unmap;
edac_dbg(3, "MC: init mci\n");
@@ -403,9 +406,9 @@ static int x38_probe1(struct pci_dev *pdev, int dev_idx)
return 0;
fail:
+ edac_mc_free(mci);
+unmap:
iounmap(window);
- if (mci)
- edac_mc_free(mci);
return rc;
}
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index cd34ef9384f1..74ffaf44d74c 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -162,7 +162,7 @@ int cper_bits_to_str(char *buf, int buf_size, unsigned long bits,
len -= size;
str += size;
}
- return len - buf_size;
+ return buf_size - len;
}
EXPORT_SYMBOL_GPL(cper_bits_to_str);
diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c
index b9f6128d56f7..f587abcd7ca3 100644
--- a/drivers/firmware/imx/imx-scu-irq.c
+++ b/drivers/firmware/imx/imx-scu-irq.c
@@ -203,6 +203,18 @@ int imx_scu_enable_general_irq_channel(struct device *dev)
struct mbox_chan *ch;
int ret = 0, i = 0;
+ if (!of_parse_phandle_with_args(dev->of_node, "mboxes",
+ "#mbox-cells", 0, &spec)) {
+ i = of_alias_get_id(spec.np, "mu");
+ of_node_put(spec.np);
+ }
+
+ /* use mu1 as general mu irq channel if failed */
+ if (i < 0)
+ i = 1;
+
+ mu_resource_id = IMX_SC_R_MU_0A + i;
+
ret = imx_scu_get_handle(&imx_sc_irq_ipc_handle);
if (ret)
return ret;
@@ -225,18 +237,6 @@ int imx_scu_enable_general_irq_channel(struct device *dev)
return ret;
}
- if (!of_parse_phandle_with_args(dev->of_node, "mboxes",
- "#mbox-cells", 0, &spec)) {
- i = of_alias_get_id(spec.np, "mu");
- of_node_put(spec.np);
- }
-
- /* use mu1 as general mu irq channel if failed */
- if (i < 0)
- i = 1;
-
- mu_resource_id = IMX_SC_R_MU_0A + i;
-
/* Create directory under /sysfs/firmware */
wakeup_obj = kobject_create_and_add("scu_wakeup_source", firmware_kobj);
if (!wakeup_obj) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
index 720011019741..bff44fc21e8b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
@@ -110,7 +110,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
struct drm_exec exec;
int r;
- drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
+ drm_exec_init(&exec, 0);
drm_exec_until_all_locked(&exec) {
r = amdgpu_vm_lock_pd(vm, &exec, 0);
if (likely(!r))
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index c1b9333d7b78..017552e79178 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -4029,6 +4029,14 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
/* disable ras feature must before hw fini */
amdgpu_ras_pre_fini(adev);
+ /*
+ * device went through surprise hotplug; we need to destroy topology
+ * before ip_fini_early to prevent kfd locking refcount issues by calling
+ * amdgpu_amdkfd_suspend()
+ */
+ if (drm_dev_is_unplugged(adev_to_drm(adev)))
+ amdgpu_amdkfd_device_fini_sw(adev);
+
amdgpu_device_ip_fini_early(adev);
amdgpu_irq_fini_hw(adev);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index fd4a75073364..48eb5545adcd 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -2446,6 +2446,14 @@ static int allocate_hiq_sdma_mqd(struct device_queue_manager *dqm)
return retval;
}
+static void deallocate_hiq_sdma_mqd(struct kfd_node *dev,
+ struct kfd_mem_obj *mqd)
+{
+ WARN(!mqd, "No hiq sdma mqd trunk to free");
+
+ amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem);
+}
+
struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev)
{
struct device_queue_manager *dqm;
@@ -2567,19 +2575,14 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev)
return dqm;
}
+ if (!dev->kfd->shared_resources.enable_mes)
+ deallocate_hiq_sdma_mqd(dev, &dqm->hiq_sdma_mqd);
+
out_free:
kfree(dqm);
return NULL;
}
-static void deallocate_hiq_sdma_mqd(struct kfd_node *dev,
- struct kfd_mem_obj *mqd)
-{
- WARN(!mqd, "No hiq sdma mqd trunk to free");
-
- amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem);
-}
-
void device_queue_manager_uninit(struct device_queue_manager *dqm)
{
dqm->ops.stop(dqm);
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
index b015e80672ec..fcd3ab4b0045 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
@@ -41,7 +41,7 @@
/* kHZ*/
#define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000
/* kHZ*/
-#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000
+#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 340000
struct dp_hdmi_dongle_signature_data {
int8_t id[15];/* "DP-HDMI ADAPTOR"*/
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
index 0172fede51b5..14f5b4f00f72 100644
--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c
@@ -1228,7 +1228,7 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
struct dce_hwseq *hws = link->dc->hwseq;
if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
- if (!link->skip_implict_edp_power_control)
+ if (!link->skip_implict_edp_power_control && hws)
hws->funcs.edp_backlight_control(link, false);
link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
}
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
index 2d98f539a100..0717f69f7c45 100644
--- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c
+++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c
@@ -325,7 +325,7 @@ static void query_dp_dual_mode_adaptor(
/* Assume we have no valid DP passive dongle connected */
*dongle = DISPLAY_DONGLE_NONE;
- sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
+ sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
/* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
if (!i2c_read(
@@ -381,6 +381,8 @@ static void query_dp_dual_mode_adaptor(
}
}
+ if (is_valid_hdmi_signature)
+ sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
if (is_type2_dongle) {
uint32_t max_tmds_clk =
diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
index e5f68b2b8def..caf590caaf2c 100644
--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
+++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
@@ -2257,8 +2257,6 @@ static int si_populate_smc_tdp_limits(struct amdgpu_device *adev,
if (scaling_factor == 0)
return -EINVAL;
- memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));
-
ret = si_calculate_adjusted_tdp_limits(adev,
false, /* ??? */
adev->pm.dpm.tdp_adjustment,
@@ -2267,6 +2265,12 @@ static int si_populate_smc_tdp_limits(struct amdgpu_device *adev,
if (ret)
return ret;
+ if (adev->pdev->device == 0x6611 && adev->pdev->revision == 0x87) {
+ /* Workaround buggy powertune on Radeon 430 and 520. */
+ tdp_limit = 32;
+ near_tdp_limit = 28;
+ }
+
smc_table->dpm2Params.TDPLimit =
cpu_to_be32(si_scale_power_for_smc(tdp_limit, scaling_factor) * 1000);
smc_table->dpm2Params.NearTDPLimit =
@@ -2312,16 +2316,8 @@ static int si_populate_smc_tdp_limits_2(struct amdgpu_device *adev,
if (ni_pi->enable_power_containment) {
SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable;
- u32 scaling_factor = si_get_smc_power_scaling_factor(adev);
int ret;
- memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));
-
- smc_table->dpm2Params.NearTDPLimit =
- cpu_to_be32(si_scale_power_for_smc(adev->pm.dpm.near_tdp_limit_adjusted, scaling_factor) * 1000);
- smc_table->dpm2Params.SafePowerLimit =
- cpu_to_be32(si_scale_power_for_smc((adev->pm.dpm.near_tdp_limit_adjusted * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000);
-
ret = amdgpu_si_copy_bytes_to_smc(adev,
(si_pi->state_table_start +
offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +
@@ -3458,10 +3454,15 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
(adev->pdev->revision == 0x80) ||
(adev->pdev->revision == 0x81) ||
(adev->pdev->revision == 0x83) ||
- (adev->pdev->revision == 0x87) ||
+ (adev->pdev->revision == 0x87 &&
+ adev->pdev->device != 0x6611) ||
(adev->pdev->device == 0x6604) ||
(adev->pdev->device == 0x6605)) {
max_sclk = 75000;
+ } else if (adev->pdev->revision == 0x87 &&
+ adev->pdev->device == 0x6611) {
+ /* Radeon 430 and 520 */
+ max_sclk = 78000;
}
}
diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c
index a95ee5dcc2e3..1a889139cb05 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c
@@ -84,6 +84,7 @@ curs507a_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh,
asyh->curs.handle = handle;
asyh->curs.offset = offset;
asyh->set.curs = asyh->curs.visible;
+ nv50_atom(asyh->state.state)->lock_core = true;
}
}
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 0d69098eddd9..8a94eee57d94 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1607,6 +1607,7 @@ static const struct panel_desc dataimage_scf0700c48ggu18 = {
},
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
+ .connector_type = DRM_MODE_CONNECTOR_DPI,
};
static const struct display_timing dlc_dlc0700yzg_1_timing = {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
index 69dfe69ce0f8..a8c8c9375d29 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
@@ -923,8 +923,10 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv,
ttm_bo_unreserve(&buf->tbo);
res = vmw_shader_alloc(dev_priv, buf, size, 0, shader_type);
- if (unlikely(ret != 0))
+ if (IS_ERR(res)) {
+ ret = PTR_ERR(res);
goto no_reserve;
+ }
ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_shader,
vmw_shader_key(user_key, shader_type),
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index a8e8da002b9b..5e3bd615066c 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -983,6 +983,7 @@ static int usbhid_parse(struct hid_device *hid)
struct usb_device *dev = interface_to_usbdev (intf);
struct hid_descriptor *hdesc;
struct hid_class_descriptor *hcdesc;
+ __u8 fixed_opt_descriptors_size;
u32 quirks = 0;
unsigned int rsize = 0;
char *rdesc;
@@ -1013,7 +1014,21 @@ static int usbhid_parse(struct hid_device *hid)
(hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) {
dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n",
hdesc->bLength, hdesc->bNumDescriptors);
- return -EINVAL;
+
+ /*
+ * Some devices may expose a wrong number of descriptors compared
+ * to the provided length.
+ * However, we ignore the optional hid class descriptors entirely
+ * so we can safely recompute the proper field.
+ */
+ if (hdesc->bLength >= sizeof(*hdesc)) {
+ fixed_opt_descriptors_size = hdesc->bLength - sizeof(*hdesc);
+
+ hid_warn(intf, "fixing wrong optional hid class descriptors count\n");
+ hdesc->bNumDescriptors = fixed_opt_descriptors_size / sizeof(*hcdesc) + 1;
+ } else {
+ return -EINVAL;
+ }
}
hid->version = le16_to_cpu(hdesc->bcdHID);
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 51e5018ac9b2..a8ad728354cb 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -270,7 +270,7 @@ void hv_synic_enable_regs(unsigned int cpu)
union hv_synic_scontrol sctrl;
/* Setup the Synic's message page */
- simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP);
+ simp.as_uint64 = hv_get_msr(HV_MSR_SIMP);
simp.simp_enabled = 1;
if (ms_hyperv.paravisor_present || hv_root_partition) {
@@ -286,10 +286,10 @@ void hv_synic_enable_regs(unsigned int cpu)
>> HV_HYP_PAGE_SHIFT;
}
- hv_set_register(HV_REGISTER_SIMP, simp.as_uint64);
+ hv_set_msr(HV_MSR_SIMP, simp.as_uint64);
/* Setup the Synic's event page */
- siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP);
+ siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP);
siefp.siefp_enabled = 1;
if (ms_hyperv.paravisor_present || hv_root_partition) {
@@ -305,13 +305,12 @@ void hv_synic_enable_regs(unsigned int cpu)
>> HV_HYP_PAGE_SHIFT;
}
- hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64);
+ hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64);
/* Setup the shared SINT. */
if (vmbus_irq != -1)
enable_percpu_irq(vmbus_irq, 0);
- shared_sint.as_uint64 = hv_get_register(HV_REGISTER_SINT0 +
- VMBUS_MESSAGE_SINT);
+ shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT);
shared_sint.vector = vmbus_interrupt;
shared_sint.masked = false;
@@ -326,14 +325,13 @@ void hv_synic_enable_regs(unsigned int cpu)
#else
shared_sint.auto_eoi = 0;
#endif
- hv_set_register(HV_REGISTER_SINT0 + VMBUS_MESSAGE_SINT,
- shared_sint.as_uint64);
+ hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
/* Enable the global synic bit */
- sctrl.as_uint64 = hv_get_register(HV_REGISTER_SCONTROL);
+ sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL);
sctrl.enable = 1;
- hv_set_register(HV_REGISTER_SCONTROL, sctrl.as_uint64);
+ hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64);
}
int hv_synic_init(unsigned int cpu)
@@ -357,17 +355,15 @@ void hv_synic_disable_regs(unsigned int cpu)
union hv_synic_siefp siefp;
union hv_synic_scontrol sctrl;
- shared_sint.as_uint64 = hv_get_register(HV_REGISTER_SINT0 +
- VMBUS_MESSAGE_SINT);
+ shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT);
shared_sint.masked = 1;
/* Need to correctly cleanup in the case of SMP!!! */
/* Disable the interrupt */
- hv_set_register(HV_REGISTER_SINT0 + VMBUS_MESSAGE_SINT,
- shared_sint.as_uint64);
+ hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
- simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP);
+ simp.as_uint64 = hv_get_msr(HV_MSR_SIMP);
/*
* In Isolation VM, sim and sief pages are allocated by
* paravisor. These pages also will be used by kdump
@@ -382,9 +378,9 @@ void hv_synic_disable_regs(unsigned int cpu)
simp.base_simp_gpa = 0;
}
- hv_set_register(HV_REGISTER_SIMP, simp.as_uint64);
+ hv_set_msr(HV_MSR_SIMP, simp.as_uint64);
- siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP);
+ siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP);
siefp.siefp_enabled = 0;
if (ms_hyperv.paravisor_present || hv_root_partition) {
@@ -394,12 +390,12 @@ void hv_synic_disable_regs(unsigned int cpu)
siefp.base_siefp_gpa = 0;
}
- hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64);
+ hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64);
/* Disable the global synic bit */
- sctrl.as_uint64 = hv_get_register(HV_REGISTER_SCONTROL);
+ sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL);
sctrl.enable = 0;
- hv_set_register(HV_REGISTER_SCONTROL, sctrl.as_uint64);
+ hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64);
if (vmbus_irq != -1)
disable_percpu_irq(vmbus_irq);
diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
index ccad7bca3fd3..5512861dd8d2 100644
--- a/drivers/hv/hv_common.c
+++ b/drivers/hv/hv_common.c
@@ -216,31 +216,33 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
/*
* Write dump contents to the page. No need to synchronize; panic should
- * be single-threaded.
+ * be single-threaded. Ignore failures from kmsg_dump_get_buffer() since
+ * panic notification should be done even if there is no message data.
+ * Don't assume bytes_written is set in case of failure, so initialize it.
*/
kmsg_dump_rewind(&iter);
- kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
+ bytes_written = 0;
+ (void)kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
&bytes_written);
- if (!bytes_written)
- return;
+
/*
* P3 to contain the physical address of the panic page & P4 to
* contain the size of the panic data in that page. Rest of the
* registers are no-op when the NOTIFY_MSG flag is set.
*/
- hv_set_register(HV_REGISTER_CRASH_P0, 0);
- hv_set_register(HV_REGISTER_CRASH_P1, 0);
- hv_set_register(HV_REGISTER_CRASH_P2, 0);
- hv_set_register(HV_REGISTER_CRASH_P3, virt_to_phys(hv_panic_page));
- hv_set_register(HV_REGISTER_CRASH_P4, bytes_written);
+ hv_set_msr(HV_MSR_CRASH_P0, 0);
+ hv_set_msr(HV_MSR_CRASH_P1, 0);
+ hv_set_msr(HV_MSR_CRASH_P2, 0);
+ hv_set_msr(HV_MSR_CRASH_P3, bytes_written ? virt_to_phys(hv_panic_page) : 0);
+ hv_set_msr(HV_MSR_CRASH_P4, bytes_written);
/*
* Let Hyper-V know there is crash data available along with
* the panic message.
*/
- hv_set_register(HV_REGISTER_CRASH_CTL,
- (HV_CRASH_CTL_CRASH_NOTIFY |
- HV_CRASH_CTL_CRASH_NOTIFY_MSG));
+ hv_set_msr(HV_MSR_CRASH_CTL,
+ (HV_CRASH_CTL_CRASH_NOTIFY |
+ HV_CRASH_CTL_CRASH_NOTIFY_MSG));
}
static struct kmsg_dumper hv_kmsg_dumper = {
@@ -311,7 +313,7 @@ int __init hv_common_init(void)
* Register for panic kmsg callback only if the right
* capability is supported by the hypervisor.
*/
- hyperv_crash_ctl = hv_get_register(HV_REGISTER_CRASH_CTL);
+ hyperv_crash_ctl = hv_get_msr(HV_MSR_CRASH_CTL);
if (hyperv_crash_ctl & HV_CRASH_CTL_CRASH_NOTIFY_MSG)
hv_kmsg_dump_register();
@@ -410,7 +412,7 @@ int hv_common_cpu_init(unsigned int cpu)
*inputarg = mem;
}
- msr_vp_index = hv_get_register(HV_REGISTER_VP_INDEX);
+ msr_vp_index = hv_get_msr(HV_MSR_VP_INDEX);
hv_vp_index[cpu] = msr_vp_index;
@@ -507,7 +509,7 @@ EXPORT_SYMBOL_GPL(hv_is_hibernation_supported);
*/
static u64 __hv_read_ref_counter(void)
{
- return hv_get_register(HV_REGISTER_TIME_REF_COUNT);
+ return hv_get_msr(HV_MSR_TIME_REF_COUNT);
}
u64 (*hv_read_reference_counter)(void) = __hv_read_ref_counter;
diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index a7c8324f6e1a..e14163459c3d 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -810,9 +810,12 @@ static int intel_th_output_open(struct inode *inode, struct file *file)
int err;
dev = bus_find_device_by_devt(&intel_th_bus, inode->i_rdev);
- if (!dev || !dev->driver) {
+ if (!dev)
+ return -ENODEV;
+
+ if (!dev->driver) {
err = -ENODEV;
- goto out_no_device;
+ goto out_put_device;
}
thdrv = to_intel_th_driver(dev->driver);
@@ -836,12 +839,22 @@ static int intel_th_output_open(struct inode *inode, struct file *file)
out_put_device:
put_device(dev);
-out_no_device:
+
return err;
}
+static int intel_th_output_release(struct inode *inode, struct file *file)
+{
+ struct intel_th_device *thdev = file->private_data;
+
+ put_device(&thdev->dev);
+
+ return 0;
+}
+
static const struct file_operations intel_th_output_fops = {
.open = intel_th_output_open,
+ .release = intel_th_output_release,
.llseek = noop_llseek,
};
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 350f7827fbac..f6e46168571f 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -97,6 +97,7 @@ struct geni_i2c_dev {
dma_addr_t dma_addr;
struct dma_chan *tx_c;
struct dma_chan *rx_c;
+ bool no_dma;
bool gpi_mode;
bool abort_done;
};
@@ -411,7 +412,7 @@ static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
size_t len = msg->len;
struct i2c_msg *cur;
- dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
+ dma_buf = gi2c->no_dma ? NULL : i2c_get_dma_safe_msg_buf(msg, 32);
if (dma_buf)
geni_se_select_mode(se, GENI_SE_DMA);
else
@@ -450,7 +451,7 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg,
size_t len = msg->len;
struct i2c_msg *cur;
- dma_buf = i2c_get_dma_safe_msg_buf(msg, 32);
+ dma_buf = gi2c->no_dma ? NULL : i2c_get_dma_safe_msg_buf(msg, 32);
if (dma_buf)
geni_se_select_mode(se, GENI_SE_DMA);
else
@@ -866,10 +867,12 @@ static int geni_i2c_probe(struct platform_device *pdev)
return -ENXIO;
}
- if (desc && desc->no_dma_support)
+ if (desc && desc->no_dma_support) {
fifo_disable = false;
- else
+ gi2c->no_dma = true;
+ } else {
fifo_disable = readl_relaxed(gi2c->se.base + GENI_IF_DISABLE_RO) & FIFO_IF_DISABLE;
+ }
if (fifo_disable) {
/* FIFO is disabled, so we can only use GPI DMA */
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index d2104e14e255..51d8de18e6d6 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -517,7 +517,6 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = {
[0] = H3LIS331DL_ACCEL_DEV_NAME,
- [1] = IIS328DQ_ACCEL_DEV_NAME,
},
.ch = (struct iio_chan_spec *)st_accel_12bit_channels,
.odr = {
@@ -584,6 +583,77 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.multi_read_bit = true,
.bootime = 2,
},
+ {
+ .wai = 0x32,
+ .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
+ .sensors_supported = {
+ [0] = IIS328DQ_ACCEL_DEV_NAME,
+ },
+ .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
+ .odr = {
+ .addr = 0x20,
+ .mask = 0x18,
+ .odr_avl = {
+ { .hz = 50, .value = 0x00, },
+ { .hz = 100, .value = 0x01, },
+ { .hz = 400, .value = 0x02, },
+ { .hz = 1000, .value = 0x03, },
+ },
+ },
+ .pw = {
+ .addr = 0x20,
+ .mask = 0x20,
+ .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
+ .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+ },
+ .enable_axis = {
+ .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
+ .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
+ },
+ .fs = {
+ .addr = 0x23,
+ .mask = 0x30,
+ .fs_avl = {
+ [0] = {
+ .num = ST_ACCEL_FS_AVL_100G,
+ .value = 0x00,
+ .gain = IIO_G_TO_M_S_2(980),
+ },
+ [1] = {
+ .num = ST_ACCEL_FS_AVL_200G,
+ .value = 0x01,
+ .gain = IIO_G_TO_M_S_2(1950),
+ },
+ [2] = {
+ .num = ST_ACCEL_FS_AVL_400G,
+ .value = 0x03,
+ .gain = IIO_G_TO_M_S_2(3910),
+ },
+ },
+ },
+ .bdu = {
+ .addr = 0x23,
+ .mask = 0x80,
+ },
+ .drdy_irq = {
+ .int1 = {
+ .addr = 0x22,
+ .mask = 0x02,
+ },
+ .int2 = {
+ .addr = 0x22,
+ .mask = 0x10,
+ },
+ .addr_ihl = 0x22,
+ .mask_ihl = 0x80,
+ },
+ .sim = {
+ .addr = 0x23,
+ .value = BIT(0),
+ },
+ .multi_read_bit = true,
+ .bootime = 2,
+ },
{
/* No WAI register present */
.sensors_supported = {
diff --git a/drivers/iio/adc/ad7280a.c b/drivers/iio/adc/ad7280a.c
index 9080c795dcb7..10cc623bf62a 100644
--- a/drivers/iio/adc/ad7280a.c
+++ b/drivers/iio/adc/ad7280a.c
@@ -1028,7 +1028,9 @@ static int ad7280_probe(struct spi_device *spi)
st->spi->max_speed_hz = AD7280A_MAX_SPI_CLK_HZ;
st->spi->mode = SPI_MODE_1;
- spi_setup(st->spi);
+ ret = spi_setup(st->spi);
+ if (ret < 0)
+ return ret;
st->ctrl_lb = FIELD_PREP(AD7280A_CTRL_LB_ACQ_TIME_MSK, st->acquisition_time) |
FIELD_PREP(AD7280A_CTRL_LB_THERMISTOR_MSK, st->thermistor_term_en);
diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
index 4c08f8a04f96..26829ff29d35 100644
--- a/drivers/iio/adc/ad9467.c
+++ b/drivers/iio/adc/ad9467.c
@@ -90,7 +90,7 @@
#define CHIPID_AD9434 0x6A
#define AD9434_DEF_OUTPUT_MODE 0x00
-#define AD9434_REG_VREF_MASK 0xC0
+#define AD9434_REG_VREF_MASK GENMASK(4, 0)
/*
* Analog Devices AD9467 16-Bit, 200/250 MSPS ADC
diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index b54e4481fafb..4ca39a2527c2 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -2504,6 +2504,7 @@ static int at91_adc_remove(struct platform_device *pdev)
struct at91_adc_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
+ cancel_work_sync(&st->touch_st.workq);
at91_adc_dma_disable(st);
diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index 43c8af41b4a9..a935ef1840a6 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -721,14 +721,7 @@ static const struct iio_chan_spec exynos_adc_iio_channels[] = {
ADC_CHANNEL(9, "adc9"),
};
-static int exynos_adc_remove_devices(struct device *dev, void *c)
-{
- struct platform_device *pdev = to_platform_device(dev);
-
- platform_device_unregister(pdev);
- return 0;
-}
static int exynos_adc_ts_open(struct input_dev *dev)
{
@@ -929,8 +922,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
return 0;
err_of_populate:
- device_for_each_child(&indio_dev->dev, NULL,
- exynos_adc_remove_devices);
+ of_platform_depopulate(&indio_dev->dev);
if (has_ts) {
input_unregister_device(info->input);
free_irq(info->tsirq, info);
@@ -959,8 +951,7 @@ static int exynos_adc_remove(struct platform_device *pdev)
free_irq(info->tsirq, info);
input_unregister_device(info->input);
}
- device_for_each_child(&indio_dev->dev, NULL,
- exynos_adc_remove_devices);
+ of_platform_depopulate(&indio_dev->dev);
iio_device_unregister(indio_dev);
free_irq(info->irq, info);
if (info->data->exit_hw)
diff --git a/drivers/iio/chemical/scd4x.c b/drivers/iio/chemical/scd4x.c
index ca6b20270711..6fd0fa3d3fbe 100644
--- a/drivers/iio/chemical/scd4x.c
+++ b/drivers/iio/chemical/scd4x.c
@@ -585,7 +585,7 @@ static const struct iio_chan_spec scd4x_channels[] = {
.sign = 'u',
.realbits = 16,
.storagebits = 16,
- .endianness = IIO_BE,
+ .endianness = IIO_CPU,
},
},
{
@@ -600,7 +600,7 @@ static const struct iio_chan_spec scd4x_channels[] = {
.sign = 'u',
.realbits = 16,
.storagebits = 16,
- .endianness = IIO_BE,
+ .endianness = IIO_CPU,
},
},
{
@@ -613,7 +613,7 @@ static const struct iio_chan_spec scd4x_channels[] = {
.sign = 'u',
.realbits = 16,
.storagebits = 16,
- .endianness = IIO_BE,
+ .endianness = IIO_CPU,
},
},
};
diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c
index 57cc0f0eedc6..4c9f7ade52b3 100644
--- a/drivers/iio/dac/ad5686.c
+++ b/drivers/iio/dac/ad5686.c
@@ -434,6 +434,12 @@ static const struct ad5686_chip_info ad5686_chip_info_tbl[] = {
.num_channels = 4,
.regmap_type = AD5686_REGMAP,
},
+ [ID_AD5695R] = {
+ .channels = ad5685r_channels,
+ .int_vref_mv = 2500,
+ .num_channels = 4,
+ .regmap_type = AD5686_REGMAP,
+ },
[ID_AD5696] = {
.channels = ad5686_channels,
.num_channels = 4,
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index 6e42e0c659e0..ef664c7c661b 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -84,6 +84,13 @@ static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(3),
};
+static const struct iio_chan_spec st_lsm6ds0_acc_channels[] = {
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
@@ -125,8 +132,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
.channels = {
[ST_LSM6DSX_ID_ACC] = {
- .chan = st_lsm6dsx_acc_channels,
- .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ .chan = st_lsm6ds0_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6ds0_acc_channels),
},
[ST_LSM6DSX_ID_GYRO] = {
.chan = st_lsm6ds0_gyro_channels,
@@ -1428,8 +1435,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
.channels = {
[ST_LSM6DSX_ID_ACC] = {
- .chan = st_lsm6dsx_acc_channels,
- .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
+ .chan = st_lsm6ds0_acc_channels,
+ .len = ARRAY_SIZE(st_lsm6ds0_acc_channels),
},
[ST_LSM6DSX_ID_GYRO] = {
.chan = st_lsm6dsx_gyro_channels,
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 121bde49ccb7..f3e0788f51ca 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -1618,6 +1618,10 @@ static void iio_dev_release(struct device *device)
iio_device_detach_buffers(indio_dev);
+ mutex_destroy(&iio_dev_opaque->info_exist_lock);
+ mutex_destroy(&iio_dev_opaque->mlock);
+
+ lockdep_unregister_key(&iio_dev_opaque->info_exist_key);
lockdep_unregister_key(&iio_dev_opaque->mlock_key);
ida_free(&iio_ida, iio_dev_opaque->id);
@@ -1663,8 +1667,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
indio_dev->dev.type = &iio_device_type;
indio_dev->dev.bus = &iio_bus_type;
device_initialize(&indio_dev->dev);
- mutex_init(&iio_dev_opaque->mlock);
- mutex_init(&iio_dev_opaque->info_exist_lock);
+
INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list);
iio_dev_opaque->id = ida_alloc(&iio_ida, GFP_KERNEL);
@@ -1685,7 +1688,10 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers);
lockdep_register_key(&iio_dev_opaque->mlock_key);
- lockdep_set_class(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key);
+ lockdep_register_key(&iio_dev_opaque->info_exist_key);
+
+ mutex_init(&iio_dev_opaque->mlock);
+ mutex_init(&iio_dev_opaque->info_exist_lock);
return indio_dev;
}
diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h
index b24127e923db..d492aa93a7c3 100644
--- a/drivers/input/serio/i8042-acpipnpio.h
+++ b/drivers/input/serio/i8042-acpipnpio.h
@@ -115,6 +115,17 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
},
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER)
},
+ {
+ /*
+ * ASUS Zenbook UX425QA_UM425QA
+ * Some Zenbooks report "Zenbook" with a lowercase b.
+ */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Zenbook UX425QA_UM425QA"),
+ },
+ .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
+ },
{
/* ASUS ZenBook UX425UA/QA */
.matches = {
@@ -1176,6 +1187,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "WUJIE Series-X5SP4NAG"),
+ },
+ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+ },
/*
* A lot of modern Clevo barebones have touchpad and/or keyboard issues
* after suspend fixable with the forcenorestore quirk.
diff --git a/drivers/interconnect/debugfs-client.c b/drivers/interconnect/debugfs-client.c
index 778deeb4a7e8..24d7b5a57794 100644
--- a/drivers/interconnect/debugfs-client.c
+++ b/drivers/interconnect/debugfs-client.c
@@ -150,6 +150,11 @@ int icc_debugfs_client_init(struct dentry *icc_dir)
return ret;
}
+ src_node = devm_kstrdup(&pdev->dev, "", GFP_KERNEL);
+ dst_node = devm_kstrdup(&pdev->dev, "", GFP_KERNEL);
+ if (!src_node || !dst_node)
+ return -ENOMEM;
+
client_dir = debugfs_create_dir("test_client", icc_dir);
debugfs_create_str("src_node", 0600, client_dir, &src_node);
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index a1934fe4ad5a..91a2bcec1156 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -616,7 +616,7 @@ static struct its_collection *its_build_mapd_cmd(struct its_node *its,
struct its_cmd_block *cmd,
struct its_cmd_desc *desc)
{
- unsigned long itt_addr;
+ phys_addr_t itt_addr;
u8 size = ilog2(desc->its_mapd_cmd.dev->nr_ites);
itt_addr = virt_to_phys(desc->its_mapd_cmd.dev->itt);
@@ -787,7 +787,7 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
struct its_cmd_desc *desc)
{
struct its_vpe *vpe = valid_vpe(its, desc->its_vmapp_cmd.vpe);
- unsigned long vpt_addr, vconf_addr;
+ phys_addr_t vpt_addr, vconf_addr;
u64 target;
bool alloc;
@@ -2404,10 +2404,10 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
baser->psz = psz;
tmp = indirect ? GITS_LVL1_ENTRY_SIZE : esz;
- pr_info("ITS@%pa: allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n",
+ pr_info("ITS@%pa: allocated %d %s @%llx (%s, esz %d, psz %dK, shr %d)\n",
&its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / (int)tmp),
its_base_type_string[type],
- (unsigned long)virt_to_phys(base),
+ (u64)virt_to_phys(base),
indirect ? "indirect" : "flat", (int)esz,
psz / SZ_1K, (int)shr >> GITS_BASER_SHAREABILITY_SHIFT);
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
index 83d6b484d3c6..2ea1887ca2fa 100644
--- a/drivers/isdn/mISDN/timerdev.c
+++ b/drivers/isdn/mISDN/timerdev.c
@@ -109,14 +109,14 @@ mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off)
spin_unlock_irq(&dev->lock);
if (filep->f_flags & O_NONBLOCK)
return -EAGAIN;
- wait_event_interruptible(dev->wait, (dev->work ||
+ wait_event_interruptible(dev->wait, (READ_ONCE(dev->work) ||
!list_empty(list)));
if (signal_pending(current))
return -ERESTARTSYS;
spin_lock_irq(&dev->lock);
}
if (dev->work)
- dev->work = 0;
+ WRITE_ONCE(dev->work, 0);
if (!list_empty(list)) {
timer = list_first_entry(list, struct mISDNtimer, list);
list_del(&timer->list);
@@ -141,13 +141,16 @@ mISDN_poll(struct file *filep, poll_table *wait)
if (*debug & DEBUG_TIMER)
printk(KERN_DEBUG "%s(%p, %p)\n", __func__, filep, wait);
if (dev) {
+ u32 work;
+
poll_wait(filep, &dev->wait, wait);
mask = 0;
- if (dev->work || !list_empty(&dev->expired))
+ work = READ_ONCE(dev->work);
+ if (work || !list_empty(&dev->expired))
mask |= (EPOLLIN | EPOLLRDNORM);
if (*debug & DEBUG_TIMER)
printk(KERN_DEBUG "%s work(%d) empty(%d)\n", __func__,
- dev->work, list_empty(&dev->expired));
+ work, list_empty(&dev->expired));
}
return mask;
}
@@ -172,7 +175,7 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
struct mISDNtimer *timer;
if (!timeout) {
- dev->work = 1;
+ WRITE_ONCE(dev->work, 1);
wake_up_interruptible(&dev->wait);
id = 0;
} else {
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index e7d75716632b..ac803768e407 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -546,11 +546,6 @@ int led_classdev_register_ext(struct device *parent,
#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED
led_cdev->brightness_hw_changed = -1;
#endif
- /* add to the list of leds */
- down_write(&leds_list_lock);
- list_add_tail(&led_cdev->node, &leds_list);
- up_write(&leds_list_lock);
-
if (!led_cdev->max_brightness)
led_cdev->max_brightness = LED_FULL;
@@ -558,6 +553,11 @@ int led_classdev_register_ext(struct device *parent,
led_init_core(led_cdev);
+ /* add to the list of leds */
+ down_write(&leds_list_lock);
+ list_add_tail(&led_cdev->node, &leds_list);
+ up_write(&leds_list_lock);
+
#ifdef CONFIG_LEDS_TRIGGERS
led_trigger_set_default(led_cdev);
#endif
diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c
index 930c252753a0..9b4f0ffa7594 100644
--- a/drivers/misc/uacce/uacce.c
+++ b/drivers/misc/uacce/uacce.c
@@ -37,20 +37,34 @@ static int uacce_start_queue(struct uacce_queue *q)
return 0;
}
-static int uacce_put_queue(struct uacce_queue *q)
+static int uacce_stop_queue(struct uacce_queue *q)
{
struct uacce_device *uacce = q->uacce;
- if ((q->state == UACCE_Q_STARTED) && uacce->ops->stop_queue)
+ if (q->state != UACCE_Q_STARTED)
+ return 0;
+
+ if (uacce->ops->stop_queue)
uacce->ops->stop_queue(q);
- if ((q->state == UACCE_Q_INIT || q->state == UACCE_Q_STARTED) &&
- uacce->ops->put_queue)
+ q->state = UACCE_Q_INIT;
+
+ return 0;
+}
+
+static void uacce_put_queue(struct uacce_queue *q)
+{
+ struct uacce_device *uacce = q->uacce;
+
+ uacce_stop_queue(q);
+
+ if (q->state != UACCE_Q_INIT)
+ return;
+
+ if (uacce->ops->put_queue)
uacce->ops->put_queue(q);
q->state = UACCE_Q_ZOMBIE;
-
- return 0;
}
static long uacce_fops_unl_ioctl(struct file *filep,
@@ -77,7 +91,7 @@ static long uacce_fops_unl_ioctl(struct file *filep,
ret = uacce_start_queue(q);
break;
case UACCE_CMD_PUT_Q:
- ret = uacce_put_queue(q);
+ ret = uacce_stop_queue(q);
break;
default:
if (uacce->ops->ioctl)
@@ -211,8 +225,14 @@ static void uacce_vma_close(struct vm_area_struct *vma)
}
}
+static int uacce_vma_mremap(struct vm_area_struct *area)
+{
+ return -EPERM;
+}
+
static const struct vm_operations_struct uacce_vm_ops = {
.close = uacce_vma_close,
+ .mremap = uacce_vma_mremap,
};
static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma)
@@ -379,6 +399,9 @@ static ssize_t isolate_strategy_show(struct device *dev, struct device_attribute
struct uacce_device *uacce = to_uacce_device(dev);
u32 val;
+ if (!uacce->ops->isolate_err_threshold_read)
+ return -ENOENT;
+
val = uacce->ops->isolate_err_threshold_read(uacce);
return sysfs_emit(buf, "%u\n", val);
@@ -391,6 +414,9 @@ static ssize_t isolate_strategy_store(struct device *dev, struct device_attribut
unsigned long val;
int ret;
+ if (!uacce->ops->isolate_err_threshold_write)
+ return -ENOENT;
+
if (kstrtoul(buf, 0, &val) < 0)
return -EINVAL;
@@ -553,6 +579,8 @@ EXPORT_SYMBOL_GPL(uacce_alloc);
*/
int uacce_register(struct uacce_device *uacce)
{
+ int ret;
+
if (!uacce)
return -ENODEV;
@@ -563,7 +591,11 @@ int uacce_register(struct uacce_device *uacce)
uacce->cdev->ops = &uacce_fops;
uacce->cdev->owner = THIS_MODULE;
- return cdev_device_add(uacce->cdev, &uacce->dev);
+ ret = cdev_device_add(uacce->cdev, &uacce->dev);
+ if (ret)
+ uacce->cdev = NULL;
+
+ return ret;
}
EXPORT_SYMBOL_GPL(uacce_register);
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
index 87d78432a1e0..195cd25c2e05 100644
--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1307,6 +1307,46 @@ static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
return err;
}
+static int sdmmc_card_busy(struct mmc_host *mmc)
+{
+ struct realtek_pci_sdmmc *host = mmc_priv(mmc);
+ struct rtsx_pcr *pcr = host->pcr;
+ int err;
+ u8 stat;
+ u8 mask = SD_DAT3_STATUS | SD_DAT2_STATUS | SD_DAT1_STATUS
+ | SD_DAT0_STATUS;
+
+ mutex_lock(&pcr->pcr_mutex);
+
+ rtsx_pci_start_run(pcr);
+
+ err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+ SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP,
+ SD_CLK_TOGGLE_EN);
+ if (err)
+ goto out;
+
+ mdelay(1);
+
+ err = rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat);
+ if (err)
+ goto out;
+
+ err = rtsx_pci_write_register(pcr, SD_BUS_STAT,
+ SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0);
+out:
+ mutex_unlock(&pcr->pcr_mutex);
+
+ if (err)
+ return err;
+
+ /* check if any pin between dat[0:3] is low */
+ if ((stat & mask) != mask)
+ return 1;
+ else
+ return 0;
+}
+
static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
struct realtek_pci_sdmmc *host = mmc_priv(mmc);
@@ -1405,6 +1445,7 @@ static const struct mmc_host_ops realtek_pci_sdmmc_ops = {
.get_ro = sdmmc_get_ro,
.get_cd = sdmmc_get_cd,
.start_signal_voltage_switch = sdmmc_switch_voltage,
+ .card_busy = sdmmc_card_busy,
.execute_tuning = sdmmc_execute_tuning,
.init_sd_express = sdmmc_init_sd_express,
};
diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
index 4c6fa92a95a6..def7997f340a 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -244,6 +244,13 @@ static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock
sdhci_writel(host, extra, reg);
if (clock <= 52000000) {
+ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+ host->mmc->ios.timing == MMC_TIMING_MMC_HS400) {
+ dev_err(mmc_dev(host->mmc),
+ "Can't reduce the clock below 52MHz in HS200/HS400 mode");
+ return;
+ }
+
/*
* Disable DLL and reset both of sample and drive clock.
* The bypass bit and start bit need to be set if DLL is not locked.
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b3ccc064cbff..9385c3ac0c83 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1942,6 +1942,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
*/
if (!bond_has_slaves(bond)) {
if (bond_dev->type != slave_dev->type) {
+ if (slave_dev->type != ARPHRD_ETHER &&
+ BOND_MODE(bond) == BOND_MODE_8023AD) {
+ SLAVE_NL_ERR(bond_dev, slave_dev, extack,
+ "8023AD mode requires Ethernet devices");
+ return -EINVAL;
+ }
slave_dbg(bond_dev, slave_dev, "change device type from %d to %d\n",
bond_dev->type, slave_dev->type);
@@ -4180,8 +4186,9 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, const v
case BOND_XMIT_POLICY_ENCAP23:
case BOND_XMIT_POLICY_ENCAP34:
memset(fk, 0, sizeof(*fk));
- return __skb_flow_dissect(NULL, skb, &flow_keys_bonding,
- fk, data, l2_proto, nhoff, hlen, 0);
+ return __skb_flow_dissect(dev_net(bond->dev), skb,
+ &flow_keys_bonding, fk, data,
+ l2_proto, nhoff, hlen, 0);
default:
break;
}
diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c
index f65c1a1e05cc..0d40564febee 100644
--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
+++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
@@ -310,7 +310,7 @@ static int ctucan_set_secondary_sample_point(struct net_device *ndev)
}
ssp_cfg = FIELD_PREP(REG_TRV_DELAY_SSP_OFFSET, ssp_offset);
- ssp_cfg |= FIELD_PREP(REG_TRV_DELAY_SSP_SRC, 0x1);
+ ssp_cfg |= FIELD_PREP(REG_TRV_DELAY_SSP_SRC, 0x0);
}
ctucan_write32(priv, CTUCANFD_TRV_DELAY, ssp_cfg);
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 5355bac4dccb..fac8ac79df59 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -486,11 +486,17 @@ static void ems_usb_read_bulk_callback(struct urb *urb)
urb->transfer_buffer, RX_BUFFER_SIZE,
ems_usb_read_bulk_callback, dev);
+ usb_anchor_urb(urb, &dev->rx_submitted);
+
retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (!retval)
+ return;
+
+ usb_unanchor_urb(urb);
if (retval == -ENODEV)
netif_device_detach(netdev);
- else if (retval)
+ else
netdev_err(netdev,
"failed resubmitting read bulk urb: %d\n", retval);
}
diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
index 03ad10b01867..fdf2136824b3 100644
--- a/drivers/net/can/usb/esd_usb.c
+++ b/drivers/net/can/usb/esd_usb.c
@@ -539,13 +539,20 @@ static void esd_usb_read_bulk_callback(struct urb *urb)
urb->transfer_buffer, ESD_USB_RX_BUFFER_SIZE,
esd_usb_read_bulk_callback, dev);
+ usb_anchor_urb(urb, &dev->rx_submitted);
+
retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (!retval)
+ return;
+
+ usb_unanchor_urb(urb);
+
if (retval == -ENODEV) {
for (i = 0; i < dev->net_count; i++) {
if (dev->nets[i])
netif_device_detach(dev->nets[i]->netdev);
}
- } else if (retval) {
+ } else {
dev_err(dev->udev->dev.parent,
"failed resubmitting read bulk urb: %d\n", retval);
}
diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index bb49a2c0a9a5..77f193861bcc 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -1736,7 +1736,7 @@ static int es58x_alloc_rx_urbs(struct es58x_device *es58x_dev)
dev_dbg(dev, "%s: Allocated %d rx URBs each of size %u\n",
__func__, i, rx_buf_len);
- return ret;
+ return 0;
}
/**
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
index a65526a71ce4..63439affd59d 100644
--- a/drivers/net/can/usb/gs_usb.c
+++ b/drivers/net/can/usb/gs_usb.c
@@ -748,7 +748,13 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
hf, parent->hf_size_rx,
gs_usb_receive_bulk_callback, parent);
+ usb_anchor_urb(urb, &parent->rx_submitted);
+
rc = usb_submit_urb(urb, GFP_ATOMIC);
+ if (!rc)
+ return;
+
+ usb_unanchor_urb(urb);
/* USB failure take down all interfaces */
if (rc == -ENODEV) {
@@ -757,6 +763,9 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
if (parent->canch[rc])
netif_device_detach(parent->canch[rc]->netdev);
}
+ } else if (rc != -ESHUTDOWN && net_ratelimit()) {
+ netdev_info(netdev, "failed to re-submit IN URB: %pe\n",
+ ERR_PTR(urb->status));
}
}
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index 022b5b79247c..8af206c93d19 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -349,7 +349,14 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb)
urb->transfer_buffer, KVASER_USB_RX_BUFFER_SIZE,
kvaser_usb_read_bulk_callback, dev);
+ usb_anchor_urb(urb, &dev->rx_submitted);
+
err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (!err)
+ return;
+
+ usb_unanchor_urb(urb);
+
if (err == -ENODEV) {
for (i = 0; i < dev->nchannels; i++) {
if (!dev->nets[i])
@@ -357,7 +364,7 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb)
netif_device_detach(dev->nets[i]->netdev);
}
- } else if (err) {
+ } else {
dev_err(&dev->intf->dev,
"Failed resubmitting read bulk urb: %d\n", err);
}
diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
index ecc489afb841..b0fceff59b32 100644
--- a/drivers/net/can/usb/mcba_usb.c
+++ b/drivers/net/can/usb/mcba_usb.c
@@ -608,11 +608,17 @@ static void mcba_usb_read_bulk_callback(struct urb *urb)
urb->transfer_buffer, MCBA_USB_RX_BUFF_SIZE,
mcba_usb_read_bulk_callback, priv);
+ usb_anchor_urb(urb, &priv->rx_submitted);
+
retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (!retval)
+ return;
+
+ usb_unanchor_urb(urb);
if (retval == -ENODEV)
netif_device_detach(netdev);
- else if (retval)
+ else
netdev_err(netdev, "failed resubmitting read bulk urb: %d\n",
retval);
}
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
index 8a5596ce4e46..0fedfc287f1f 100644
--- a/drivers/net/can/usb/usb_8dev.c
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -541,11 +541,17 @@ static void usb_8dev_read_bulk_callback(struct urb *urb)
urb->transfer_buffer, RX_BUFFER_SIZE,
usb_8dev_read_bulk_callback, priv);
+ usb_anchor_urb(urb, &priv->rx_submitted);
+
retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (!retval)
+ return;
+
+ usb_unanchor_urb(urb);
if (retval == -ENODEV)
netif_device_detach(netdev);
- else if (retval)
+ else
netdev_err(netdev,
"failed resubmitting read bulk urb: %d\n", retval);
}
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index b4d57da71de2..3d6f8f3a8336 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -2105,7 +2105,7 @@ static void xgbe_get_stats64(struct net_device *netdev,
s->multicast = pstats->rxmulticastframes_g;
s->rx_length_errors = pstats->rxlengtherror;
s->rx_crc_errors = pstats->rxcrcerror;
- s->rx_fifo_errors = pstats->rxfifooverflow;
+ s->rx_over_errors = pstats->rxfifooverflow;
s->tx_packets = pstats->txframecount_gb;
s->tx_bytes = pstats->txoctetcount_gb;
@@ -2559,9 +2559,6 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
goto read_again;
if (error || packet->errors) {
- if (packet->errors)
- netif_err(pdata, rx_err, netdev,
- "error in received packet\n");
dev_kfree_skb(skb);
goto next_packet;
}
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 779f1324bb5f..0cda78b78fb8 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -3797,6 +3797,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
{
int status;
bool pmac_valid = false;
+ u32 pmac_id;
eth_zero_addr(mac);
@@ -3809,7 +3810,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
adapter->if_handle, 0);
} else {
status = be_cmd_get_mac_from_list(adapter, mac, &pmac_valid,
- NULL, adapter->if_handle, 0);
+ &pmac_id, adapter->if_handle, 0);
}
return status;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 011c8cc8429e..2ed1e290f9d7 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2141,7 +2141,7 @@ static int be_get_new_eqd(struct be_eq_obj *eqo)
struct be_aic_obj *aic;
struct be_rx_obj *rxo;
struct be_tx_obj *txo;
- u64 rx_pkts = 0, tx_pkts = 0;
+ u64 rx_pkts = 0, tx_pkts = 0, pkts;
ulong now;
u32 pps, delta;
int i;
@@ -2157,15 +2157,17 @@ static int be_get_new_eqd(struct be_eq_obj *eqo)
for_all_rx_queues_on_eq(adapter, eqo, rxo, i) {
do {
start = u64_stats_fetch_begin(&rxo->stats.sync);
- rx_pkts += rxo->stats.rx_pkts;
+ pkts = rxo->stats.rx_pkts;
} while (u64_stats_fetch_retry(&rxo->stats.sync, start));
+ rx_pkts += pkts;
}
for_all_tx_queues_on_eq(adapter, eqo, txo, i) {
do {
start = u64_stats_fetch_begin(&txo->stats.sync);
- tx_pkts += txo->stats.tx_reqs;
+ pkts = txo->stats.tx_reqs;
} while (u64_stats_fetch_retry(&txo->stats.sync, start));
+ tx_pkts += pkts;
}
/* Skip, if wrapped around or first calculation */
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index dbf44a17987e..34627de2e311 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2505,44 +2505,47 @@ static netdev_features_t hns3_features_check(struct sk_buff *skb,
static void hns3_fetch_stats(struct rtnl_link_stats64 *stats,
struct hns3_enet_ring *ring, bool is_tx)
{
+ struct ring_stats ring_stats;
unsigned int start;
do {
start = u64_stats_fetch_begin(&ring->syncp);
- if (is_tx) {
- stats->tx_bytes += ring->stats.tx_bytes;
- stats->tx_packets += ring->stats.tx_pkts;
- stats->tx_dropped += ring->stats.sw_err_cnt;
- stats->tx_dropped += ring->stats.tx_vlan_err;
- stats->tx_dropped += ring->stats.tx_l4_proto_err;
- stats->tx_dropped += ring->stats.tx_l2l3l4_err;
- stats->tx_dropped += ring->stats.tx_tso_err;
- stats->tx_dropped += ring->stats.over_max_recursion;
- stats->tx_dropped += ring->stats.hw_limitation;
- stats->tx_dropped += ring->stats.copy_bits_err;
- stats->tx_dropped += ring->stats.skb2sgl_err;
- stats->tx_dropped += ring->stats.map_sg_err;
- stats->tx_errors += ring->stats.sw_err_cnt;
- stats->tx_errors += ring->stats.tx_vlan_err;
- stats->tx_errors += ring->stats.tx_l4_proto_err;
- stats->tx_errors += ring->stats.tx_l2l3l4_err;
- stats->tx_errors += ring->stats.tx_tso_err;
- stats->tx_errors += ring->stats.over_max_recursion;
- stats->tx_errors += ring->stats.hw_limitation;
- stats->tx_errors += ring->stats.copy_bits_err;
- stats->tx_errors += ring->stats.skb2sgl_err;
- stats->tx_errors += ring->stats.map_sg_err;
- } else {
- stats->rx_bytes += ring->stats.rx_bytes;
- stats->rx_packets += ring->stats.rx_pkts;
- stats->rx_dropped += ring->stats.l2_err;
- stats->rx_errors += ring->stats.l2_err;
- stats->rx_errors += ring->stats.l3l4_csum_err;
- stats->rx_crc_errors += ring->stats.l2_err;
- stats->multicast += ring->stats.rx_multicast;
- stats->rx_length_errors += ring->stats.err_pkt_len;
- }
+ ring_stats = ring->stats;
} while (u64_stats_fetch_retry(&ring->syncp, start));
+
+ if (is_tx) {
+ stats->tx_bytes += ring_stats.tx_bytes;
+ stats->tx_packets += ring_stats.tx_pkts;
+ stats->tx_dropped += ring_stats.sw_err_cnt;
+ stats->tx_dropped += ring_stats.tx_vlan_err;
+ stats->tx_dropped += ring_stats.tx_l4_proto_err;
+ stats->tx_dropped += ring_stats.tx_l2l3l4_err;
+ stats->tx_dropped += ring_stats.tx_tso_err;
+ stats->tx_dropped += ring_stats.over_max_recursion;
+ stats->tx_dropped += ring_stats.hw_limitation;
+ stats->tx_dropped += ring_stats.copy_bits_err;
+ stats->tx_dropped += ring_stats.skb2sgl_err;
+ stats->tx_dropped += ring_stats.map_sg_err;
+ stats->tx_errors += ring_stats.sw_err_cnt;
+ stats->tx_errors += ring_stats.tx_vlan_err;
+ stats->tx_errors += ring_stats.tx_l4_proto_err;
+ stats->tx_errors += ring_stats.tx_l2l3l4_err;
+ stats->tx_errors += ring_stats.tx_tso_err;
+ stats->tx_errors += ring_stats.over_max_recursion;
+ stats->tx_errors += ring_stats.hw_limitation;
+ stats->tx_errors += ring_stats.copy_bits_err;
+ stats->tx_errors += ring_stats.skb2sgl_err;
+ stats->tx_errors += ring_stats.map_sg_err;
+ } else {
+ stats->rx_bytes += ring_stats.rx_bytes;
+ stats->rx_packets += ring_stats.rx_pkts;
+ stats->rx_dropped += ring_stats.l2_err;
+ stats->rx_errors += ring_stats.l2_err;
+ stats->rx_errors += ring_stats.l3l4_csum_err;
+ stats->rx_crc_errors += ring_stats.l2_err;
+ stats->multicast += ring_stats.rx_multicast;
+ stats->rx_length_errors += ring_stats.err_pkt_len;
+ }
}
static void hns3_nic_get_stats64(struct net_device *netdev,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 4d15eb73b972..659d6351f26c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -731,7 +731,7 @@ struct hclge_fd_tcam_config_3_cmd {
#define HCLGE_FD_AD_QID_M GENMASK(11, 2)
#define HCLGE_FD_AD_USE_COUNTER_B 12
#define HCLGE_FD_AD_COUNTER_NUM_S 13
-#define HCLGE_FD_AD_COUNTER_NUM_M GENMASK(20, 13)
+#define HCLGE_FD_AD_COUNTER_NUM_M GENMASK(19, 13)
#define HCLGE_FD_AD_NXT_STEP_B 20
#define HCLGE_FD_AD_NXT_KEY_S 21
#define HCLGE_FD_AD_NXT_KEY_M GENMASK(25, 21)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 2df0c6305b90..72a5df4e3a32 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -5617,7 +5617,7 @@ static int hclge_fd_ad_config(struct hclge_dev *hdev, u8 stage, int loc,
HCLGE_FD_AD_COUNTER_NUM_S, action->counter_id);
hnae3_set_bit(ad_data, HCLGE_FD_AD_NXT_STEP_B, action->use_next_stage);
hnae3_set_field(ad_data, HCLGE_FD_AD_NXT_KEY_M, HCLGE_FD_AD_NXT_KEY_S,
- action->counter_id);
+ action->next_input_key);
req->ad_data = cpu_to_le64(ad_data);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index a6a290514e54..7aef40b50b89 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -396,6 +396,8 @@ static int ice_vsi_alloc_ring_stats(struct ice_vsi *vsi)
if (!ring_stats)
goto err_out;
+ u64_stats_init(&ring_stats->syncp);
+
WRITE_ONCE(tx_ring_stats[i], ring_stats);
}
@@ -415,6 +417,8 @@ static int ice_vsi_alloc_ring_stats(struct ice_vsi *vsi)
if (!ring_stats)
goto err_out;
+ u64_stats_init(&ring_stats->syncp);
+
WRITE_ONCE(rx_ring_stats[i], ring_stats);
}
@@ -3893,22 +3897,31 @@ int ice_vsi_add_vlan_zero(struct ice_vsi *vsi)
int ice_vsi_del_vlan_zero(struct ice_vsi *vsi)
{
struct ice_vsi_vlan_ops *vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
+ struct ice_pf *pf = vsi->back;
struct ice_vlan vlan;
int err;
- vlan = ICE_VLAN(0, 0, 0);
- err = vlan_ops->del_vlan(vsi, &vlan);
- if (err && err != -EEXIST)
- return err;
+ if (pf->lag && pf->lag->primary) {
+ dev_dbg(ice_pf_to_dev(pf), "Interface is primary in aggregate - not deleting prune list\n");
+ } else {
+ vlan = ICE_VLAN(0, 0, 0);
+ err = vlan_ops->del_vlan(vsi, &vlan);
+ if (err && err != -EEXIST)
+ return err;
+ }
/* in SVM both VLAN 0 filters are identical */
if (!ice_is_dvm_ena(&vsi->back->hw))
return 0;
- vlan = ICE_VLAN(ETH_P_8021Q, 0, 0);
- err = vlan_ops->del_vlan(vsi, &vlan);
- if (err && err != -EEXIST)
- return err;
+ if (pf->lag && pf->lag->primary) {
+ dev_dbg(ice_pf_to_dev(pf), "Interface is primary in aggregate - not deleting QinQ prune list\n");
+ } else {
+ vlan = ICE_VLAN(ETH_P_8021Q, 0, 0);
+ err = vlan_ops->del_vlan(vsi, &vlan);
+ if (err && err != -EEXIST)
+ return err;
+ }
/* when deleting the last VLAN filter, make sure to disable the VLAN
* promisc mode so the filter isn't left by accident
diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
index a82af96e6bd1..4c07c1e4aa99 100644
--- a/drivers/net/ethernet/intel/igc/igc_ptp.c
+++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
@@ -758,36 +758,43 @@ static void igc_ptp_tx_reg_to_stamp(struct igc_adapter *adapter,
static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
{
struct igc_hw *hw = &adapter->hw;
+ u32 txstmpl_old;
u64 regval;
u32 mask;
int i;
+ /* Establish baseline of TXSTMPL_0 before checking TXTT_0.
+ * This baseline is used to detect if a new timestamp arrives in
+ * register 0 during the hardware bug workaround below.
+ */
+ txstmpl_old = rd32(IGC_TXSTMPL);
+
mask = rd32(IGC_TSYNCTXCTL) & IGC_TSYNCTXCTL_TXTT_ANY;
if (mask & IGC_TSYNCTXCTL_TXTT_0) {
regval = rd32(IGC_TXSTMPL);
regval |= (u64)rd32(IGC_TXSTMPH) << 32;
} else {
- /* There's a bug in the hardware that could cause
- * missing interrupts for TX timestamping. The issue
- * is that for new interrupts to be triggered, the
- * IGC_TXSTMPH_0 register must be read.
+ /* TXTT_0 not set - register 0 has no new timestamp initially.
+ *
+ * Hardware bug: Future timestamp interrupts won't fire unless
+ * TXSTMPH_0 is read, even if the timestamp was captured in
+ * registers 1-3.
*
- * To avoid discarding a valid timestamp that just
- * happened at the "wrong" time, we need to confirm
- * that there was no timestamp captured, we do that by
- * assuming that no two timestamps in sequence have
- * the same nanosecond value.
+ * Workaround: Read TXSTMPH_0 here to enable future interrupts.
+ * However, this read clears TXTT_0. If a timestamp arrives in
+ * register 0 after checking TXTT_0 but before this read, it
+ * would be lost.
*
- * So, we read the "low" register, read the "high"
- * register (to latch a new timestamp) and read the
- * "low" register again, if "old" and "new" versions
- * of the "low" register are different, a valid
- * timestamp was captured, we can read the "high"
- * register again.
+ * To detect this race: We saved a baseline read of TXSTMPL_0
+ * before TXTT_0 check. After performing the workaround read of
+ * TXSTMPH_0, we read TXSTMPL_0 again. Since consecutive
+ * timestamps never share the same nanosecond value, a change
+ * between the baseline and new TXSTMPL_0 indicates a timestamp
+ * arrived during the race window. If so, read the complete
+ * timestamp.
*/
- u32 txstmpl_old, txstmpl_new;
+ u32 txstmpl_new;
- txstmpl_old = rd32(IGC_TXSTMPL);
rd32(IGC_TXSTMPH);
txstmpl_new = rd32(IGC_TXSTMPL);
@@ -802,7 +809,7 @@ static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)
done:
/* Now that the problematic first register was handled, we can
- * use retrieve the timestamps from the other registers
+ * retrieve the timestamps from the other registers
* (starting from '1') with less complications.
*/
for (i = 1; i < IGC_MAX_TX_TSTAMP_REGS; i++) {
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
index 67e6d755b30e..846049b6c4d6 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -1541,8 +1541,8 @@ static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype,
return -ENODEV;
}
-static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,
- int num_lfs, struct rsrc_attach *attach)
+static int rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,
+ int num_lfs, struct rsrc_attach *attach)
{
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
struct rvu_hwinfo *hw = rvu->hw;
@@ -1552,21 +1552,21 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,
u64 cfg;
if (!num_lfs)
- return;
+ return -EINVAL;
blkaddr = rvu_get_attach_blkaddr(rvu, blktype, pcifunc, attach);
if (blkaddr < 0)
- return;
+ return -EFAULT;
block = &hw->block[blkaddr];
if (!block->lf.bmap)
- return;
+ return -ESRCH;
for (slot = 0; slot < num_lfs; slot++) {
/* Allocate the resource */
lf = rvu_alloc_rsrc(&block->lf);
if (lf < 0)
- return;
+ return -EFAULT;
cfg = (1ULL << 63) | (pcifunc << 8) | slot;
rvu_write64(rvu, blkaddr, block->lfcfg_reg |
@@ -1577,6 +1577,8 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,
/* Set start MSIX vector for this LF within this PF/VF */
rvu_set_msix_offset(rvu, pfvf, block, lf);
}
+
+ return 0;
}
static int rvu_check_rsrc_availability(struct rvu *rvu,
@@ -1714,22 +1716,31 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu,
int err;
/* If first request, detach all existing attached resources */
- if (!attach->modify)
- rvu_detach_rsrcs(rvu, NULL, pcifunc);
+ if (!attach->modify) {
+ err = rvu_detach_rsrcs(rvu, NULL, pcifunc);
+ if (err)
+ return err;
+ }
mutex_lock(&rvu->rsrc_lock);
/* Check if the request can be accommodated */
err = rvu_check_rsrc_availability(rvu, attach, pcifunc);
if (err)
- goto exit;
+ goto fail1;
/* Now attach the requested resources */
- if (attach->npalf)
- rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1, attach);
+ if (attach->npalf) {
+ err = rvu_attach_block(rvu, pcifunc, BLKTYPE_NPA, 1, attach);
+ if (err)
+ goto fail1;
+ }
- if (attach->nixlf)
- rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1, attach);
+ if (attach->nixlf) {
+ err = rvu_attach_block(rvu, pcifunc, BLKTYPE_NIX, 1, attach);
+ if (err)
+ goto fail2;
+ }
if (attach->sso) {
/* RVU func doesn't know which exact LF or slot is attached
@@ -1739,33 +1750,64 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu,
*/
if (attach->modify)
rvu_detach_block(rvu, pcifunc, BLKTYPE_SSO);
- rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO,
- attach->sso, attach);
+ err = rvu_attach_block(rvu, pcifunc, BLKTYPE_SSO,
+ attach->sso, attach);
+ if (err)
+ goto fail3;
}
if (attach->ssow) {
if (attach->modify)
rvu_detach_block(rvu, pcifunc, BLKTYPE_SSOW);
- rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW,
- attach->ssow, attach);
+ err = rvu_attach_block(rvu, pcifunc, BLKTYPE_SSOW,
+ attach->ssow, attach);
+ if (err)
+ goto fail4;
}
if (attach->timlfs) {
if (attach->modify)
rvu_detach_block(rvu, pcifunc, BLKTYPE_TIM);
- rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM,
- attach->timlfs, attach);
+ err = rvu_attach_block(rvu, pcifunc, BLKTYPE_TIM,
+ attach->timlfs, attach);
+ if (err)
+ goto fail5;
}
if (attach->cptlfs) {
if (attach->modify &&
rvu_attach_from_same_block(rvu, BLKTYPE_CPT, attach))
rvu_detach_block(rvu, pcifunc, BLKTYPE_CPT);
- rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT,
- attach->cptlfs, attach);
+ err = rvu_attach_block(rvu, pcifunc, BLKTYPE_CPT,
+ attach->cptlfs, attach);
+ if (err)
+ goto fail6;
}
-exit:
+ mutex_unlock(&rvu->rsrc_lock);
+ return 0;
+
+fail6:
+ if (attach->timlfs)
+ rvu_detach_block(rvu, pcifunc, BLKTYPE_TIM);
+
+fail5:
+ if (attach->ssow)
+ rvu_detach_block(rvu, pcifunc, BLKTYPE_SSOW);
+
+fail4:
+ if (attach->sso)
+ rvu_detach_block(rvu, pcifunc, BLKTYPE_SSO);
+
+fail3:
+ if (attach->nixlf)
+ rvu_detach_block(rvu, pcifunc, BLKTYPE_NIX);
+
+fail2:
+ if (attach->npalf)
+ rvu_detach_block(rvu, pcifunc, BLKTYPE_NPA);
+
+fail1:
mutex_unlock(&rvu->rsrc_lock);
return err;
}
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c
index 74953f67a2bf..3af58bc9f533 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c
@@ -330,7 +330,7 @@ static int cn10k_mcs_write_rx_flowid(struct otx2_nic *pfvf,
req->data[0] = FIELD_PREP(MCS_TCAM0_MAC_DA_MASK, mac_da);
req->mask[0] = ~0ULL;
- req->mask[0] = ~MCS_TCAM0_MAC_DA_MASK;
+ req->mask[0] &= ~MCS_TCAM0_MAC_DA_MASK;
req->data[1] = FIELD_PREP(MCS_TCAM1_ETYPE_MASK, ETH_P_MACSEC);
req->mask[1] = ~0ULL;
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
index c5de3ba33e2f..47bfa8f7ca53 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
@@ -893,13 +893,8 @@ static inline dma_addr_t otx2_dma_map_page(struct otx2_nic *pfvf,
size_t offset, size_t size,
enum dma_data_direction dir)
{
- dma_addr_t iova;
-
- iova = dma_map_page_attrs(pfvf->dev, page,
+ return dma_map_page_attrs(pfvf->dev, page,
offset, size, dir, DMA_ATTR_SKIP_CPU_SYNC);
- if (unlikely(dma_mapping_error(pfvf->dev, iova)))
- return (dma_addr_t)NULL;
- return iova;
}
static inline void otx2_dma_unmap_page(struct otx2_nic *pfvf,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 5c6f01abdcb9..03201bcda1a6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -5687,6 +5687,7 @@ int mlx5e_priv_init(struct mlx5e_priv *priv,
void mlx5e_priv_cleanup(struct mlx5e_priv *priv)
{
+ bool destroying = test_bit(MLX5E_STATE_DESTROYING, &priv->state);
int i;
/* bail if change profile failed and also rollback failed */
@@ -5712,6 +5713,8 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv)
}
memset(priv, 0, sizeof(*priv));
+ if (destroying) /* restore destroying bit, to allow unload */
+ set_bit(MLX5E_STATE_DESTROYING, &priv->state);
}
static unsigned int mlx5e_get_max_num_txqs(struct mlx5_core_dev *mdev,
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index aa114240e340..af001e2e688b 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1762,6 +1762,9 @@ static int netvsc_set_rxfh(struct net_device *dev, const u32 *indir,
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;
+ if (!ndc->rx_table_sz)
+ return -EOPNOTSUPP;
+
rndis_dev = ndev->extension;
if (indir) {
for (i = 0; i < ndc->rx_table_sz; i++)
diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index 025e0c19ec25..fce3ced90bd3 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -69,7 +69,6 @@ struct ipvl_dev {
DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE);
netdev_features_t sfeatures;
u32 msg_enable;
- spinlock_t addrs_lock;
};
struct ipvl_addr {
@@ -90,6 +89,7 @@ struct ipvl_port {
struct net_device *dev;
possible_net_t pnet;
struct hlist_head hlhead[IPVLAN_HASH_SIZE];
+ spinlock_t addrs_lock; /* guards hash-table and addrs */
struct list_head ipvlans;
u16 mode;
u16 flags;
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index 83bd65a22770..268ea41a17d5 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -107,17 +107,15 @@ void ipvlan_ht_addr_del(struct ipvl_addr *addr)
struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan,
const void *iaddr, bool is_v6)
{
- struct ipvl_addr *addr, *ret = NULL;
+ struct ipvl_addr *addr;
- rcu_read_lock();
- list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) {
- if (addr_equal(is_v6, addr, iaddr)) {
- ret = addr;
- break;
- }
+ assert_spin_locked(&ipvlan->port->addrs_lock);
+
+ list_for_each_entry(addr, &ipvlan->addrs, anode) {
+ if (addr_equal(is_v6, addr, iaddr))
+ return addr;
}
- rcu_read_unlock();
- return ret;
+ return NULL;
}
bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6)
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 57c79f5f2991..679e816146d8 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -74,6 +74,7 @@ static int ipvlan_port_create(struct net_device *dev)
for (idx = 0; idx < IPVLAN_HASH_SIZE; idx++)
INIT_HLIST_HEAD(&port->hlhead[idx]);
+ spin_lock_init(&port->addrs_lock);
skb_queue_head_init(&port->backlog);
INIT_WORK(&port->wq, ipvlan_process_multicast);
ida_init(&port->ida);
@@ -179,6 +180,7 @@ static void ipvlan_uninit(struct net_device *dev)
static int ipvlan_open(struct net_device *dev)
{
struct ipvl_dev *ipvlan = netdev_priv(dev);
+ struct ipvl_port *port = ipvlan->port;
struct ipvl_addr *addr;
if (ipvlan->port->mode == IPVLAN_MODE_L3 ||
@@ -187,10 +189,10 @@ static int ipvlan_open(struct net_device *dev)
else
dev->flags &= ~IFF_NOARP;
- rcu_read_lock();
- list_for_each_entry_rcu(addr, &ipvlan->addrs, anode)
+ spin_lock_bh(&port->addrs_lock);
+ list_for_each_entry(addr, &ipvlan->addrs, anode)
ipvlan_ht_addr_add(ipvlan, addr);
- rcu_read_unlock();
+ spin_unlock_bh(&port->addrs_lock);
return 0;
}
@@ -204,10 +206,10 @@ static int ipvlan_stop(struct net_device *dev)
dev_uc_unsync(phy_dev, dev);
dev_mc_unsync(phy_dev, dev);
- rcu_read_lock();
- list_for_each_entry_rcu(addr, &ipvlan->addrs, anode)
+ spin_lock_bh(&ipvlan->port->addrs_lock);
+ list_for_each_entry(addr, &ipvlan->addrs, anode)
ipvlan_ht_addr_del(addr);
- rcu_read_unlock();
+ spin_unlock_bh(&ipvlan->port->addrs_lock);
return 0;
}
@@ -574,7 +576,6 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
if (!tb[IFLA_MTU])
ipvlan_adjust_mtu(ipvlan, phy_dev);
INIT_LIST_HEAD(&ipvlan->addrs);
- spin_lock_init(&ipvlan->addrs_lock);
/* TODO Probably put random address here to be presented to the
* world but keep using the physical-dev address for the outgoing
@@ -652,13 +653,13 @@ void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
struct ipvl_dev *ipvlan = netdev_priv(dev);
struct ipvl_addr *addr, *next;
- spin_lock_bh(&ipvlan->addrs_lock);
+ spin_lock_bh(&ipvlan->port->addrs_lock);
list_for_each_entry_safe(addr, next, &ipvlan->addrs, anode) {
ipvlan_ht_addr_del(addr);
list_del_rcu(&addr->anode);
kfree_rcu(addr, rcu);
}
- spin_unlock_bh(&ipvlan->addrs_lock);
+ spin_unlock_bh(&ipvlan->port->addrs_lock);
ida_simple_remove(&ipvlan->port->ida, dev->dev_id);
list_del_rcu(&ipvlan->pnode);
@@ -805,6 +806,8 @@ static int ipvlan_add_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6)
{
struct ipvl_addr *addr;
+ assert_spin_locked(&ipvlan->port->addrs_lock);
+
addr = kzalloc(sizeof(struct ipvl_addr), GFP_ATOMIC);
if (!addr)
return -ENOMEM;
@@ -835,16 +838,16 @@ static void ipvlan_del_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6)
{
struct ipvl_addr *addr;
- spin_lock_bh(&ipvlan->addrs_lock);
+ spin_lock_bh(&ipvlan->port->addrs_lock);
addr = ipvlan_find_addr(ipvlan, iaddr, is_v6);
if (!addr) {
- spin_unlock_bh(&ipvlan->addrs_lock);
+ spin_unlock_bh(&ipvlan->port->addrs_lock);
return;
}
ipvlan_ht_addr_del(addr);
list_del_rcu(&addr->anode);
- spin_unlock_bh(&ipvlan->addrs_lock);
+ spin_unlock_bh(&ipvlan->port->addrs_lock);
kfree_rcu(addr, rcu);
}
@@ -866,14 +869,14 @@ static int ipvlan_add_addr6(struct ipvl_dev *ipvlan, struct in6_addr *ip6_addr)
{
int ret = -EINVAL;
- spin_lock_bh(&ipvlan->addrs_lock);
+ spin_lock_bh(&ipvlan->port->addrs_lock);
if (ipvlan_addr_busy(ipvlan->port, ip6_addr, true))
netif_err(ipvlan, ifup, ipvlan->dev,
"Failed to add IPv6=%pI6c addr for %s intf\n",
ip6_addr, ipvlan->dev->name);
else
ret = ipvlan_add_addr(ipvlan, ip6_addr, true);
- spin_unlock_bh(&ipvlan->addrs_lock);
+ spin_unlock_bh(&ipvlan->port->addrs_lock);
return ret;
}
@@ -912,21 +915,24 @@ static int ipvlan_addr6_validator_event(struct notifier_block *unused,
struct in6_validator_info *i6vi = (struct in6_validator_info *)ptr;
struct net_device *dev = (struct net_device *)i6vi->i6vi_dev->dev;
struct ipvl_dev *ipvlan = netdev_priv(dev);
+ int ret = NOTIFY_OK;
if (!ipvlan_is_valid_dev(dev))
return NOTIFY_DONE;
switch (event) {
case NETDEV_UP:
+ spin_lock_bh(&ipvlan->port->addrs_lock);
if (ipvlan_addr_busy(ipvlan->port, &i6vi->i6vi_addr, true)) {
NL_SET_ERR_MSG(i6vi->extack,
"Address already assigned to an ipvlan device");
- return notifier_from_errno(-EADDRINUSE);
+ ret = notifier_from_errno(-EADDRINUSE);
}
+ spin_unlock_bh(&ipvlan->port->addrs_lock);
break;
}
- return NOTIFY_OK;
+ return ret;
}
#endif
@@ -934,14 +940,14 @@ static int ipvlan_add_addr4(struct ipvl_dev *ipvlan, struct in_addr *ip4_addr)
{
int ret = -EINVAL;
- spin_lock_bh(&ipvlan->addrs_lock);
+ spin_lock_bh(&ipvlan->port->addrs_lock);
if (ipvlan_addr_busy(ipvlan->port, ip4_addr, false))
netif_err(ipvlan, ifup, ipvlan->dev,
"Failed to add IPv4=%pI4 on %s intf.\n",
ip4_addr, ipvlan->dev->name);
else
ret = ipvlan_add_addr(ipvlan, ip4_addr, false);
- spin_unlock_bh(&ipvlan->addrs_lock);
+ spin_unlock_bh(&ipvlan->port->addrs_lock);
return ret;
}
@@ -983,21 +989,24 @@ static int ipvlan_addr4_validator_event(struct notifier_block *unused,
struct in_validator_info *ivi = (struct in_validator_info *)ptr;
struct net_device *dev = (struct net_device *)ivi->ivi_dev->dev;
struct ipvl_dev *ipvlan = netdev_priv(dev);
+ int ret = NOTIFY_OK;
if (!ipvlan_is_valid_dev(dev))
return NOTIFY_DONE;
switch (event) {
case NETDEV_UP:
+ spin_lock_bh(&ipvlan->port->addrs_lock);
if (ipvlan_addr_busy(ipvlan->port, &ivi->ivi_addr, false)) {
NL_SET_ERR_MSG(ivi->extack,
"Address already assigned to an ipvlan device");
- return notifier_from_errno(-EADDRINUSE);
+ ret = notifier_from_errno(-EADDRINUSE);
}
+ spin_unlock_bh(&ipvlan->port->addrs_lock);
break;
}
- return NOTIFY_OK;
+ return ret;
}
static struct notifier_block ipvlan_addr4_notifier_block __read_mostly = {
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index c8da94af4161..09db43ce3176 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -58,7 +58,7 @@ struct macvlan_port {
struct macvlan_source_entry {
struct hlist_node hlist;
- struct macvlan_dev *vlan;
+ struct macvlan_dev __rcu *vlan;
unsigned char addr[6+2] __aligned(sizeof(u16));
struct rcu_head rcu;
};
@@ -145,7 +145,7 @@ static struct macvlan_source_entry *macvlan_hash_lookup_source(
hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
if (ether_addr_equal_64bits(entry->addr, addr) &&
- entry->vlan == vlan)
+ rcu_access_pointer(entry->vlan) == vlan)
return entry;
}
return NULL;
@@ -167,7 +167,7 @@ static int macvlan_hash_add_source(struct macvlan_dev *vlan,
return -ENOMEM;
ether_addr_copy(entry->addr, addr);
- entry->vlan = vlan;
+ RCU_INIT_POINTER(entry->vlan, vlan);
h = &port->vlan_source_hash[macvlan_eth_hash(addr)];
hlist_add_head_rcu(&entry->hlist, h);
vlan->macaddr_count++;
@@ -186,6 +186,7 @@ static void macvlan_hash_add(struct macvlan_dev *vlan)
static void macvlan_hash_del_source(struct macvlan_source_entry *entry)
{
+ RCU_INIT_POINTER(entry->vlan, NULL);
hlist_del_rcu(&entry->hlist);
kfree_rcu(entry, rcu);
}
@@ -389,7 +390,7 @@ static void macvlan_flush_sources(struct macvlan_port *port,
int i;
hash_for_each_safe(port->vlan_source_hash, i, next, entry, hlist)
- if (entry->vlan == vlan)
+ if (rcu_access_pointer(entry->vlan) == vlan)
macvlan_hash_del_source(entry);
vlan->macaddr_count = 0;
@@ -432,9 +433,14 @@ static bool macvlan_forward_source(struct sk_buff *skb,
hlist_for_each_entry_rcu(entry, h, hlist) {
if (ether_addr_equal_64bits(entry->addr, addr)) {
- if (entry->vlan->flags & MACVLAN_FLAG_NODST)
+ struct macvlan_dev *vlan = rcu_dereference(entry->vlan);
+
+ if (!vlan)
+ continue;
+
+ if (vlan->flags & MACVLAN_FLAG_NODST)
consume = true;
- macvlan_forward_source_one(skb, entry->vlan);
+ macvlan_forward_source_one(skb, vlan);
}
}
@@ -1685,7 +1691,7 @@ static int macvlan_fill_info_macaddr(struct sk_buff *skb,
struct macvlan_source_entry *entry;
hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
- if (entry->vlan != vlan)
+ if (rcu_access_pointer(entry->vlan) != vlan)
continue;
if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr))
return 1;
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c
index 608953d4f98d..ca64136372fc 100644
--- a/drivers/net/netdevsim/bpf.c
+++ b/drivers/net/netdevsim/bpf.c
@@ -244,7 +244,9 @@ static int nsim_bpf_create_prog(struct nsim_dev *nsim_dev,
&state->state, &nsim_bpf_string_fops);
debugfs_create_bool("loaded", 0400, state->ddir, &state->is_loaded);
+ mutex_lock(&nsim_dev->progs_list_lock);
list_add_tail(&state->l, &nsim_dev->bpf_bound_progs);
+ mutex_unlock(&nsim_dev->progs_list_lock);
prog->aux->offload->dev_priv = state;
@@ -273,12 +275,16 @@ static int nsim_bpf_translate(struct bpf_prog *prog)
static void nsim_bpf_destroy_prog(struct bpf_prog *prog)
{
struct nsim_bpf_bound_prog *state;
+ struct nsim_dev *nsim_dev;
state = prog->aux->offload->dev_priv;
+ nsim_dev = state->nsim_dev;
WARN(state->is_loaded,
"offload state destroyed while program still bound");
debugfs_remove_recursive(state->ddir);
+ mutex_lock(&nsim_dev->progs_list_lock);
list_del(&state->l);
+ mutex_unlock(&nsim_dev->progs_list_lock);
kfree(state);
}
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 3e0b61202f0c..2614d6509954 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -1545,6 +1545,7 @@ int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev)
nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
spin_lock_init(&nsim_dev->fa_cookie_lock);
+ mutex_init(&nsim_dev->progs_list_lock);
dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev);
@@ -1683,6 +1684,7 @@ void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev)
devl_unregister(devlink);
kfree(nsim_dev->vfconfigs);
kfree(nsim_dev->fa_cookie);
+ mutex_destroy(&nsim_dev->progs_list_lock);
devl_unlock(devlink);
devlink_free(devlink);
dev_set_drvdata(&nsim_bus_dev->dev, NULL);
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index dfc6e00b718e..f2a31acc5e2e 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -295,6 +295,7 @@ struct nsim_dev {
u32 prog_id_gen;
struct list_head bpf_bound_progs;
struct list_head bpf_bound_maps;
+ struct mutex progs_list_lock;
struct netdev_phys_item_id switch_id;
struct list_head port_list;
bool fw_update_status;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 875788918bcb..3dd59376a89e 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -268,6 +268,45 @@ static struct phy_driver genphy_driver;
static LIST_HEAD(phy_fixup_list);
static DEFINE_MUTEX(phy_fixup_lock);
+static void phy_link_change(struct phy_device *phydev, bool up)
+{
+ struct net_device *netdev = phydev->attached_dev;
+
+ if (up)
+ netif_carrier_on(netdev);
+ else
+ netif_carrier_off(netdev);
+ phydev->adjust_link(netdev);
+ if (phydev->mii_ts && phydev->mii_ts->link_state)
+ phydev->mii_ts->link_state(phydev->mii_ts, phydev);
+}
+
+/**
+ * phy_uses_state_machine - test whether consumer driver uses PAL state machine
+ * @phydev: the target PHY device structure
+ *
+ * Ultimately, this aims to indirectly determine whether the PHY is attached
+ * to a consumer which uses the state machine by calling phy_start() and
+ * phy_stop().
+ *
+ * When the PHY driver consumer uses phylib, it must have previously called
+ * phy_connect_direct() or one of its derivatives, so that phy_prepare_link()
+ * has set up a hook for monitoring state changes.
+ *
+ * When the PHY driver is used by the MAC driver consumer through phylink (the
+ * only other provider of a phy_link_change() method), using the PHY state
+ * machine is not optional.
+ *
+ * Return: true if consumer calls phy_start() and phy_stop(), false otherwise.
+ */
+static bool phy_uses_state_machine(struct phy_device *phydev)
+{
+ if (phydev->phy_link_change == phy_link_change)
+ return phydev->attached_dev && phydev->adjust_link;
+
+ return !!phydev->phy_link_change;
+}
+
static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
{
struct device_driver *drv = phydev->mdio.dev.driver;
@@ -328,7 +367,7 @@ static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
* may call phy routines that try to grab the same lock, and that may
* lead to a deadlock.
*/
- if (phydev->attached_dev && phydev->adjust_link)
+ if (phy_uses_state_machine(phydev))
phy_stop_machine(phydev);
if (!mdio_bus_phy_may_suspend(phydev))
@@ -382,7 +421,7 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
}
}
- if (phydev->attached_dev && phydev->adjust_link)
+ if (phy_uses_state_machine(phydev))
phy_start_machine(phydev);
return 0;
@@ -1069,19 +1108,6 @@ struct phy_device *phy_find_first(struct mii_bus *bus)
}
EXPORT_SYMBOL(phy_find_first);
-static void phy_link_change(struct phy_device *phydev, bool up)
-{
- struct net_device *netdev = phydev->attached_dev;
-
- if (up)
- netif_carrier_on(netdev);
- else
- netif_carrier_off(netdev);
- phydev->adjust_link(netdev);
- if (phydev->mii_ts && phydev->mii_ts->link_state)
- phydev->mii_ts->link_state(phydev->mii_ts, phydev);
-}
-
/**
* phy_prepare_link - prepares the PHY layer to monitor link status
* @phydev: target phy_device struct
@@ -1826,6 +1852,8 @@ void phy_detach(struct phy_device *phydev)
phydev->attached_dev->phydev = NULL;
phydev->attached_dev = NULL;
}
+
+ phydev->phy_link_change = NULL;
phydev->phylink = NULL;
if (!phydev->is_on_sfp_module)
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 8b6d6a1b3c2e..2b4716ccf0c5 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -603,10 +603,6 @@ static const struct usb_device_id products[] = {
USB_DEVICE(0x0fe6, 0x8101), /* DM9601 USB to Fast Ethernet Adapter */
.driver_info = (unsigned long)&dm9601_info,
},
- {
- USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */
- .driver_info = (unsigned long)&dm9601_info,
- },
{
USB_DEVICE(0x0a46, 0x9000), /* DM9000E */
.driver_info = (unsigned long)&dm9601_info,
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index e6a1864f03f9..a26a7435d84b 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -702,6 +702,7 @@ void usbnet_resume_rx(struct usbnet *dev)
struct sk_buff *skb;
int num = 0;
+ local_bh_disable();
clear_bit(EVENT_RX_PAUSED, &dev->flags);
while ((skb = skb_dequeue(&dev->rxq_pause)) != NULL) {
@@ -710,6 +711,7 @@ void usbnet_resume_rx(struct usbnet *dev)
}
tasklet_schedule(&dev->bh);
+ local_bh_enable();
netif_dbg(dev, rx_status, dev->net,
"paused rx queue disabled, %d skbs requeued\n", num);
@@ -1799,9 +1801,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
if ((dev->driver_info->flags & FLAG_NOARP) != 0)
net->flags |= IFF_NOARP;
- /* maybe the remote can't receive an Ethernet MTU */
- if (net->mtu > (dev->hard_mtu - net->hard_header_len))
- net->mtu = dev->hard_mtu - net->hard_header_len;
+ if (net->max_mtu > (dev->hard_mtu - net->hard_header_len))
+ net->max_mtu = dev->hard_mtu - net->hard_header_len;
+
+ if (net->mtu > net->max_mtu)
+ net->mtu = net->max_mtu;
+
} else if (!info->in || !info->out)
status = usbnet_get_endpoints (dev, udev);
else {
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 7767b6ff5a15..2b3b0beb55c8 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -226,16 +226,20 @@ static void veth_get_ethtool_stats(struct net_device *dev,
const struct veth_rq_stats *rq_stats = &rcv_priv->rq[i].stats;
const void *base = (void *)&rq_stats->vs;
unsigned int start, tx_idx = idx;
+ u64 buf[VETH_TQ_STATS_LEN];
size_t offset;
- tx_idx += (i % dev->real_num_tx_queues) * VETH_TQ_STATS_LEN;
do {
start = u64_stats_fetch_begin(&rq_stats->syncp);
for (j = 0; j < VETH_TQ_STATS_LEN; j++) {
offset = veth_tq_stats_desc[j].offset;
- data[tx_idx + j] += *(u64 *)(base + offset);
+ buf[j] = *(u64 *)(base + offset);
}
} while (u64_stats_fetch_retry(&rq_stats->syncp, start));
+
+ tx_idx += (i % dev->real_num_tx_queues) * VETH_TQ_STATS_LEN;
+ for (j = 0; j < VETH_TQ_STATS_LEN; j++)
+ data[tx_idx + j] += buf[j];
}
pp_idx = idx + dev->real_num_tx_queues * VETH_TQ_STATS_LEN;
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index afae4a8027f8..1bb006dd229b 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -1725,8 +1725,8 @@ static void _ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
(ce_state->src_ring->nentries *
sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN),
- ce_state->src_ring->base_addr_owner_space,
- ce_state->src_ring->base_addr_ce_space);
+ ce_state->src_ring->base_addr_owner_space_unaligned,
+ ce_state->src_ring->base_addr_ce_space_unaligned);
kfree(ce_state->src_ring);
}
@@ -1735,8 +1735,8 @@ static void _ath10k_ce_free_pipe(struct ath10k *ar, int ce_id)
(ce_state->dest_ring->nentries *
sizeof(struct ce_desc) +
CE_DESC_RING_ALIGN),
- ce_state->dest_ring->base_addr_owner_space,
- ce_state->dest_ring->base_addr_ce_space);
+ ce_state->dest_ring->base_addr_owner_space_unaligned,
+ ce_state->dest_ring->base_addr_ce_space_unaligned);
kfree(ce_state->dest_ring);
}
@@ -1756,8 +1756,8 @@ static void _ath10k_ce_free_pipe_64(struct ath10k *ar, int ce_id)
(ce_state->src_ring->nentries *
sizeof(struct ce_desc_64) +
CE_DESC_RING_ALIGN),
- ce_state->src_ring->base_addr_owner_space,
- ce_state->src_ring->base_addr_ce_space);
+ ce_state->src_ring->base_addr_owner_space_unaligned,
+ ce_state->src_ring->base_addr_ce_space_unaligned);
kfree(ce_state->src_ring);
}
@@ -1766,8 +1766,8 @@ static void _ath10k_ce_free_pipe_64(struct ath10k *ar, int ce_id)
(ce_state->dest_ring->nentries *
sizeof(struct ce_desc_64) +
CE_DESC_RING_ALIGN),
- ce_state->dest_ring->base_addr_owner_space,
- ce_state->dest_ring->base_addr_ce_space);
+ ce_state->dest_ring->base_addr_owner_space_unaligned,
+ ce_state->dest_ring->base_addr_ce_space_unaligned);
kfree(ce_state->dest_ring);
}
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 8cc51ab699de..dc54ea16c12a 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -4728,7 +4728,7 @@ ath11k_dp_rx_mon_mpdu_pop(struct ath11k *ar, int mac_id,
if (!msdu) {
ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
"msdu_pop: invalid buf_id %d\n", buf_id);
- break;
+ goto next_msdu;
}
rxcb = ATH11K_SKB_RXCB(msdu);
if (!rxcb->unmapped) {
@@ -5362,7 +5362,7 @@ ath11k_dp_rx_full_mon_mpdu_pop(struct ath11k *ar,
"full mon msdu_pop: invalid buf_id %d\n",
buf_id);
spin_unlock_bh(&rx_ring->idr_lock);
- break;
+ goto next_msdu;
}
idr_remove(&rx_ring->bufs_idr, buf_id);
spin_unlock_bh(&rx_ring->idr_lock);
diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c
index b66d23d6b2bd..a25943a1bff8 100644
--- a/drivers/net/wireless/ath/ath12k/ce.c
+++ b/drivers/net/wireless/ath/ath12k/ce.c
@@ -893,8 +893,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab)
dma_free_coherent(ab->dev,
pipe->src_ring->nentries * desc_sz +
CE_DESC_RING_ALIGN,
- pipe->src_ring->base_addr_owner_space,
- pipe->src_ring->base_addr_ce_space);
+ pipe->src_ring->base_addr_owner_space_unaligned,
+ pipe->src_ring->base_addr_ce_space_unaligned);
kfree(pipe->src_ring);
pipe->src_ring = NULL;
}
@@ -904,8 +904,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab)
dma_free_coherent(ab->dev,
pipe->dest_ring->nentries * desc_sz +
CE_DESC_RING_ALIGN,
- pipe->dest_ring->base_addr_owner_space,
- pipe->dest_ring->base_addr_ce_space);
+ pipe->dest_ring->base_addr_owner_space_unaligned,
+ pipe->dest_ring->base_addr_ce_space_unaligned);
kfree(pipe->dest_ring);
pipe->dest_ring = NULL;
}
@@ -916,8 +916,8 @@ void ath12k_ce_free_pipes(struct ath12k_base *ab)
dma_free_coherent(ab->dev,
pipe->status_ring->nentries * desc_sz +
CE_DESC_RING_ALIGN,
- pipe->status_ring->base_addr_owner_space,
- pipe->status_ring->base_addr_ce_space);
+ pipe->status_ring->base_addr_owner_space_unaligned,
+ pipe->status_ring->base_addr_ce_space_unaligned);
kfree(pipe->status_ring);
pipe->status_ring = NULL;
}
diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
index 10690e82358b..99f888bfd105 100644
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
@@ -827,7 +827,7 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter,
bool coex_flag)
{
- u8 i;
+ u8 i, j;
u32 rx_win_size;
struct mwifiex_private *priv;
@@ -867,8 +867,8 @@ static void mwifiex_update_ampdu_rxwinsize(struct mwifiex_adapter *adapter,
if (rx_win_size != priv->add_ba_param.rx_win_size) {
if (!priv->media_connected)
continue;
- for (i = 0; i < MAX_NUM_TID; i++)
- mwifiex_11n_delba(priv, i);
+ for (j = 0; j < MAX_NUM_TID; j++)
+ mwifiex_11n_delba(priv, j);
}
}
}
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 05890536e353..d7ad5329e525 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -2023,6 +2023,7 @@ int rsi_mac80211_attach(struct rsi_common *common)
hw->queues = MAX_HW_QUEUES;
hw->extra_tx_headroom = RSI_NEEDED_HEADROOM;
+ hw->vif_data_size = sizeof(struct vif_priv);
hw->max_rates = 1;
hw->max_rate_tries = MAX_RETRIES;
diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c
index 6b89d596ba9a..590b038e449e 100644
--- a/drivers/nfc/virtual_ncidev.c
+++ b/drivers/nfc/virtual_ncidev.c
@@ -125,10 +125,6 @@ static ssize_t virtual_ncidev_write(struct file *file,
kfree_skb(skb);
return -EFAULT;
}
- if (strnlen(skb->data, count) != count) {
- kfree_skb(skb);
- return -EINVAL;
- }
nci_recv_frame(vdev->ndev, skb);
return count;
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index 92ba315cfe19..5963e8b695ff 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -279,6 +279,21 @@ int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
}
EXPORT_SYMBOL_GPL(nvmf_reg_write32);
+int nvmf_subsystem_reset(struct nvme_ctrl *ctrl)
+{
+ int ret;
+
+ if (!nvme_wait_reset(ctrl))
+ return -EBUSY;
+
+ ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, NVME_SUBSYS_RESET);
+ if (ret)
+ return ret;
+
+ return nvme_try_sched_reset(ctrl);
+}
+EXPORT_SYMBOL_GPL(nvmf_subsystem_reset);
+
/**
* nvmf_log_connect_error() - Error-parsing-diagnostic print out function for
* connect() errors.
diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h
index 80e15ad3936f..e75c68738240 100644
--- a/drivers/nvme/host/fabrics.h
+++ b/drivers/nvme/host/fabrics.h
@@ -206,6 +206,7 @@ static inline unsigned int nvmf_nr_io_queues(struct nvmf_ctrl_options *opts)
int nvmf_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val);
int nvmf_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val);
int nvmf_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val);
+int nvmf_subsystem_reset(struct nvme_ctrl *ctrl);
int nvmf_connect_admin_queue(struct nvme_ctrl *ctrl);
int nvmf_connect_io_queue(struct nvme_ctrl *ctrl, u16 qid);
int nvmf_register_transport(struct nvmf_transport_ops *ops);
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 2954f0a27474..4fdb62ae996b 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -2384,7 +2384,7 @@ nvme_fc_ctrl_get(struct nvme_fc_ctrl *ctrl)
* controller. Called after last nvme_put_ctrl() call
*/
static void
-nvme_fc_nvme_ctrl_freed(struct nvme_ctrl *nctrl)
+nvme_fc_free_ctrl(struct nvme_ctrl *nctrl)
{
struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl);
@@ -3349,7 +3349,8 @@ static const struct nvme_ctrl_ops nvme_fc_ctrl_ops = {
.reg_read32 = nvmf_reg_read32,
.reg_read64 = nvmf_reg_read64,
.reg_write32 = nvmf_reg_write32,
- .free_ctrl = nvme_fc_nvme_ctrl_freed,
+ .subsystem_reset = nvmf_subsystem_reset,
+ .free_ctrl = nvme_fc_free_ctrl,
.submit_async_event = nvme_fc_submit_async_event,
.delete_ctrl = nvme_fc_delete_ctrl,
.get_address = nvmf_get_address,
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index e867ac859a87..fd9edeb0d9fe 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -562,6 +562,7 @@ struct nvme_ctrl_ops {
int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val);
void (*free_ctrl)(struct nvme_ctrl *ctrl);
void (*submit_async_event)(struct nvme_ctrl *ctrl);
+ int (*subsystem_reset)(struct nvme_ctrl *ctrl);
void (*delete_ctrl)(struct nvme_ctrl *ctrl);
void (*stop_ctrl)(struct nvme_ctrl *ctrl);
int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
@@ -660,18 +661,9 @@ int nvme_try_sched_reset(struct nvme_ctrl *ctrl);
static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl)
{
- int ret;
-
- if (!ctrl->subsystem)
+ if (!ctrl->subsystem || !ctrl->ops->subsystem_reset)
return -ENOTTY;
- if (!nvme_wait_reset(ctrl))
- return -EBUSY;
-
- ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65);
- if (ret)
- return ret;
-
- return nvme_try_sched_reset(ctrl);
+ return ctrl->ops->subsystem_reset(ctrl);
}
/*
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 053385c84bf8..8ea38cd6ff30 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1143,6 +1143,44 @@ static void nvme_pci_submit_async_event(struct nvme_ctrl *ctrl)
spin_unlock(&nvmeq->sq_lock);
}
+static int nvme_pci_subsystem_reset(struct nvme_ctrl *ctrl)
+{
+ struct nvme_dev *dev = to_nvme_dev(ctrl);
+ int ret = 0;
+
+ /*
+ * Taking the shutdown_lock ensures the BAR mapping is not being
+ * altered by reset_work. Holding this lock before the RESETTING state
+ * change, if successful, also ensures nvme_remove won't be able to
+ * proceed to iounmap until we're done.
+ */
+ mutex_lock(&dev->shutdown_lock);
+ if (!dev->bar_mapped_size) {
+ ret = -ENODEV;
+ goto unlock;
+ }
+
+ if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) {
+ ret = -EBUSY;
+ goto unlock;
+ }
+
+ writel(NVME_SUBSYS_RESET, dev->bar + NVME_REG_NSSR);
+
+ if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) ||
+ !nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE))
+ goto unlock;
+
+ /*
+ * Read controller status to flush the previous write and trigger a
+ * pcie read error.
+ */
+ readl(dev->bar + NVME_REG_CSTS);
+unlock:
+ mutex_unlock(&dev->shutdown_lock);
+ return ret;
+}
+
static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id)
{
struct nvme_command c = { };
@@ -2910,6 +2948,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
.reg_read64 = nvme_pci_reg_read64,
.free_ctrl = nvme_pci_free_ctrl,
.submit_async_event = nvme_pci_submit_async_event,
+ .subsystem_reset = nvme_pci_subsystem_reset,
.get_address = nvme_pci_get_address,
.print_device_info = nvme_pci_print_device_info,
.supports_pci_p2pdma = nvme_pci_supports_pci_p2pdma,
@@ -3563,6 +3602,8 @@ static const struct pci_device_id nvme_id_table[] = {
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
{ PCI_DEVICE(0x1e49, 0x0041), /* ZHITAI TiPro7000 NVMe SSD */
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
+ { PCI_DEVICE(0x1fa0, 0x2283), /* Wodposit WPBSNM8-256GTP */
+ .driver_data = NVME_QUIRK_NO_SECONDARY_TEMP_THRESH, },
{ PCI_DEVICE(0x025e, 0xf1ac), /* SOLIDIGM P44 pro SSDPFKKW020X7 */
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
{ PCI_DEVICE(0xc0a9, 0x540a), /* Crucial P2 */
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 055b95d2ce93..8803fa04a322 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -2174,6 +2174,7 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = {
.reg_read32 = nvmf_reg_read32,
.reg_read64 = nvmf_reg_read64,
.reg_write32 = nvmf_reg_write32,
+ .subsystem_reset = nvmf_subsystem_reset,
.free_ctrl = nvme_rdma_free_ctrl,
.submit_async_event = nvme_rdma_submit_async_event,
.delete_ctrl = nvme_rdma_delete_ctrl,
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 5b76670f34be..f2b171c3169b 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -2561,6 +2561,7 @@ static const struct nvme_ctrl_ops nvme_tcp_ctrl_ops = {
.reg_read32 = nvmf_reg_read32,
.reg_read64 = nvmf_reg_read64,
.reg_write32 = nvmf_reg_write32,
+ .subsystem_reset = nvmf_subsystem_reset,
.free_ctrl = nvme_tcp_free_ctrl,
.submit_async_event = nvme_tcp_submit_async_event,
.delete_ctrl = nvme_tcp_delete_ctrl,
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 6a539c3b8b53..3bdff81eb3af 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -969,8 +969,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
if (unlikely(data->ttag >= queue->nr_cmds)) {
pr_err("queue %d: received out of bound ttag %u, nr_cmds %u\n",
queue->idx, data->ttag, queue->nr_cmds);
- nvmet_tcp_fatal_error(queue);
- return -EPROTO;
+ goto err_proto;
}
cmd = &queue->cmds[data->ttag];
} else {
@@ -981,9 +980,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
pr_err("ttag %u unexpected data offset %u (expected %u)\n",
data->ttag, le32_to_cpu(data->data_offset),
cmd->rbytes_done);
- /* FIXME: use path and transport errors */
- nvmet_tcp_fatal_error(queue);
- return -EPROTO;
+ goto err_proto;
}
exp_data_len = le32_to_cpu(data->hdr.plen) -
@@ -996,9 +993,19 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
cmd->pdu_len == 0 ||
cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) {
pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len);
- /* FIXME: use proper transport errors */
- nvmet_tcp_fatal_error(queue);
- return -EPROTO;
+ goto err_proto;
+ }
+ /*
+ * Ensure command data structures are initialized. We must check both
+ * cmd->req.sg and cmd->iov because they can have different NULL states:
+ * - Uninitialized commands: both NULL
+ * - READ commands: cmd->req.sg allocated, cmd->iov NULL
+ * - WRITE commands: both allocated
+ */
+ if (unlikely(!cmd->req.sg || !cmd->iov)) {
+ pr_err("queue %d: H2CData PDU received for invalid command state (ttag %u)\n",
+ queue->idx, data->ttag);
+ goto err_proto;
}
cmd->pdu_recv = 0;
nvmet_tcp_build_pdu_iovec(cmd);
@@ -1006,6 +1013,11 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
queue->rcv_state = NVMET_TCP_RECV_DATA;
return 0;
+
+err_proto:
+ /* FIXME: use proper transport errors */
+ nvmet_tcp_fatal_error(queue);
+ return -EPROTO;
}
static int nvmet_tcp_done_recv_pdu(struct nvmet_tcp_queue *queue)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index ccadc22f18c0..d10248a5c0a5 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1788,13 +1788,17 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
end--;
len = end - start;
- if (kstrtoint(end, 10, &id) < 0)
+ if (kstrtoint(end, 10, &id) < 0) {
+ of_node_put(np);
continue;
+ }
/* Allocate an alias_prop with enough space for the stem */
ap = dt_alloc(sizeof(*ap) + len + 1, __alignof__(*ap));
- if (!ap)
+ if (!ap) {
+ of_node_put(np);
continue;
+ }
memset(ap, 0, sizeof(*ap) + len + 1);
ap->alias = start;
of_alias_add(ap, np, id, start, len);
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index f235ab55b91e..ccf7f0ffa67f 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -616,7 +616,7 @@ static int __init of_platform_default_populate_init(void)
node = of_find_node_by_path("/firmware");
if (node) {
- of_platform_populate(node, NULL, NULL, NULL);
+ of_platform_default_populate(node, NULL, NULL);
of_node_put(node);
}
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index a3927daebeb0..e9ae66cc4189 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -180,12 +180,6 @@ config PCI_P2PDMA
P2P DMA transactions must be between devices behind the same root
port.
- Enabling this option will reduce the entropy of x86 KASLR memory
- regions. For example - on a 46 bit system, the entropy goes down
- from 16 bits to 15 bits. The actual reduction in entropy depends
- on the physical address bits, on processor features, kernel config
- (5 level page table) and physical memory present on the system.
-
If unsure, say N.
config PCI_LABEL
diff --git a/drivers/phy/broadcom/phy-bcm-ns-usb3.c b/drivers/phy/broadcom/phy-bcm-ns-usb3.c
index 2c8b1b7dda5b..5c2710597df2 100644
--- a/drivers/phy/broadcom/phy-bcm-ns-usb3.c
+++ b/drivers/phy/broadcom/phy-bcm-ns-usb3.c
@@ -203,7 +203,7 @@ static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev)
usb3->dev = dev;
usb3->mdiodev = mdiodev;
- usb3->family = (enum bcm_ns_family)device_get_match_data(dev);
+ usb3->family = (unsigned long)device_get_match_data(dev);
syscon_np = of_parse_phandle(dev->of_node, "usb3-dmp-syscon", 0);
err = of_address_to_resource(syscon_np, 0, &res);
diff --git a/drivers/phy/broadcom/phy-bcm-ns2-pcie.c b/drivers/phy/broadcom/phy-bcm-ns2-pcie.c
index 2eaa41f8fc70..67a6ae5ecba0 100644
--- a/drivers/phy/broadcom/phy-bcm-ns2-pcie.c
+++ b/drivers/phy/broadcom/phy-bcm-ns2-pcie.c
@@ -61,8 +61,6 @@ static int ns2_pci_phy_probe(struct mdio_device *mdiodev)
return PTR_ERR(provider);
}
- dev_info(dev, "%s PHY registered\n", dev_name(dev));
-
return 0;
}
diff --git a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
index 36ad02c33ac5..8473fa574529 100644
--- a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
+++ b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
@@ -395,7 +395,6 @@ static int ns2_drd_phy_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, driver);
- dev_info(dev, "Registered NS2 DRD Phy device\n");
queue_delayed_work(system_power_efficient_wq, &driver->wq_extcon,
driver->debounce_jiffies);
diff --git a/drivers/phy/broadcom/phy-bcm-sr-pcie.c b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
index 8a4aadf166cf..c85af6508677 100644
--- a/drivers/phy/broadcom/phy-bcm-sr-pcie.c
+++ b/drivers/phy/broadcom/phy-bcm-sr-pcie.c
@@ -277,8 +277,6 @@ static int sr_pcie_phy_probe(struct platform_device *pdev)
return PTR_ERR(provider);
}
- dev_info(dev, "Stingray PCIe PHY driver initialized\n");
-
return 0;
}
diff --git a/drivers/phy/broadcom/phy-brcm-sata.c b/drivers/phy/broadcom/phy-brcm-sata.c
index ed9e18791ec9..6838cb76e826 100644
--- a/drivers/phy/broadcom/phy-brcm-sata.c
+++ b/drivers/phy/broadcom/phy-brcm-sata.c
@@ -836,7 +836,7 @@ static int brcm_sata_phy_probe(struct platform_device *pdev)
return PTR_ERR(provider);
}
- dev_info(dev, "registered %d port(s)\n", count);
+ dev_dbg(dev, "registered %d port(s)\n", count);
return 0;
put_child:
diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
index afd52392cd53..7bdf7aba41ff 100644
--- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -89,7 +89,8 @@ static int imx8_pcie_phy_power_on(struct phy *phy)
writel(imx8_phy->tx_deemph_gen2,
imx8_phy->base + PCIE_PHY_TRSV_REG6);
break;
- case IMX8MP: /* Do nothing. */
+ case IMX8MP:
+ reset_control_assert(imx8_phy->reset);
break;
}
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index f914f016b3d2..043063699e06 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -206,6 +206,7 @@ static void imx8m_phy_tune(struct imx8mq_usb_phy *imx_phy)
if (imx_phy->pcs_tx_swing_full != PHY_TUNE_DEFAULT) {
value = readl(imx_phy->base + PHY_CTRL5);
+ value &= ~PHY_CTRL5_PCS_TX_SWING_FULL_MASK;
value |= FIELD_PREP(PHY_CTRL5_PCS_TX_SWING_FULL_MASK,
imx_phy->pcs_tx_swing_full);
writel(value, imx_phy->base + PHY_CTRL5);
diff --git a/drivers/phy/marvell/phy-pxa-usb.c b/drivers/phy/marvell/phy-pxa-usb.c
index 6c98eb9608e9..c0bb71f80c04 100644
--- a/drivers/phy/marvell/phy-pxa-usb.c
+++ b/drivers/phy/marvell/phy-pxa-usb.c
@@ -325,7 +325,6 @@ static int pxa_usb_phy_probe(struct platform_device *pdev)
phy_create_lookup(pxa_usb_phy->phy, "usb", "mv-otg");
}
- dev_info(dev, "Marvell PXA USB PHY");
return 0;
}
diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
index a43e20abb10d..ad7bf049d726 100644
--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
+++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
@@ -251,8 +251,6 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
if (IS_ERR(phy_provider))
return PTR_ERR(phy_provider);
- dev_info(dev, "Registered Qcom-eUSB2 repeater\n");
-
return 0;
}
diff --git a/drivers/phy/qualcomm/phy-qcom-m31.c b/drivers/phy/qualcomm/phy-qcom-m31.c
index a5e60039a264..116cfa6ddac6 100644
--- a/drivers/phy/qualcomm/phy-qcom-m31.c
+++ b/drivers/phy/qualcomm/phy-qcom-m31.c
@@ -267,8 +267,6 @@ static int m31usb_phy_probe(struct platform_device *pdev)
phy_set_drvdata(qphy->phy, qphy);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
- if (!IS_ERR(phy_provider))
- dev_info(dev, "Registered M31 USB phy\n");
return PTR_ERR_OR_ZERO(phy_provider);
}
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c
index c52655a383ce..d3c26a39873f 100644
--- a/drivers/phy/qualcomm/phy-qcom-qusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c
@@ -1063,31 +1063,29 @@ static int qusb2_phy_probe(struct platform_device *pdev)
or->hsdisc_trim.override = true;
}
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
+ dev_set_drvdata(dev, qphy);
+
/*
- * Prevent runtime pm from being ON by default. Users can enable
- * it using power/control in sysfs.
+ * Enable runtime PM support, but forbid it by default.
+ * Users can allow it again via the power/control attribute in sysfs.
*/
+ pm_runtime_set_active(dev);
pm_runtime_forbid(dev);
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
generic_phy = devm_phy_create(dev, NULL, &qusb2_phy_gen_ops);
if (IS_ERR(generic_phy)) {
ret = PTR_ERR(generic_phy);
dev_err(dev, "failed to create phy, %d\n", ret);
- pm_runtime_disable(dev);
return ret;
}
qphy->phy = generic_phy;
- dev_set_drvdata(dev, qphy);
phy_set_drvdata(generic_phy, qphy);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
- if (!IS_ERR(phy_provider))
- dev_info(dev, "Registered Qcom-QUSB2 phy\n");
- else
- pm_runtime_disable(dev);
return PTR_ERR_OR_ZERO(phy_provider);
}
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c b/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c
index 1484691a41d5..4a1dfef5ff8f 100644
--- a/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c
+++ b/drivers/phy/qualcomm/phy-qcom-snps-eusb2.c
@@ -13,15 +13,15 @@
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
-#define USB_PHY_UTMI_CTRL0 (0x3c)
+#define QCOM_USB_PHY_UTMI_CTRL0 (0x3c)
#define SLEEPM BIT(0)
#define OPMODE_MASK GENMASK(4, 3)
#define OPMODE_NONDRIVING BIT(3)
-#define USB_PHY_UTMI_CTRL5 (0x50)
+#define QCOM_USB_PHY_UTMI_CTRL5 (0x50)
#define POR BIT(1)
-#define USB_PHY_HS_PHY_CTRL_COMMON0 (0x54)
+#define QCOM_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54)
#define PHY_ENABLE BIT(0)
#define SIDDQ_SEL BIT(1)
#define SIDDQ BIT(2)
@@ -30,15 +30,15 @@
#define FSEL_19_2_MHZ_VAL (0x0)
#define FSEL_38_4_MHZ_VAL (0x4)
-#define USB_PHY_CFG_CTRL_1 (0x58)
+#define QCOM_USB_PHY_CFG_CTRL_1 (0x58)
#define PHY_CFG_PLL_CPBIAS_CNTRL_MASK GENMASK(7, 1)
-#define USB_PHY_CFG_CTRL_2 (0x5c)
+#define QCOM_USB_PHY_CFG_CTRL_2 (0x5c)
#define PHY_CFG_PLL_FB_DIV_7_0_MASK GENMASK(7, 0)
#define DIV_7_0_19_2_MHZ_VAL (0x90)
#define DIV_7_0_38_4_MHZ_VAL (0xc8)
-#define USB_PHY_CFG_CTRL_3 (0x60)
+#define QCOM_USB_PHY_CFG_CTRL_3 (0x60)
#define PHY_CFG_PLL_FB_DIV_11_8_MASK GENMASK(3, 0)
#define DIV_11_8_19_2_MHZ_VAL (0x1)
#define DIV_11_8_38_4_MHZ_VAL (0x0)
@@ -46,73 +46,73 @@
#define PHY_CFG_PLL_REF_DIV GENMASK(7, 4)
#define PLL_REF_DIV_VAL (0x0)
-#define USB_PHY_HS_PHY_CTRL2 (0x64)
+#define QCOM_USB_PHY_HS_PHY_CTRL2 (0x64)
#define VBUSVLDEXT0 BIT(0)
#define USB2_SUSPEND_N BIT(2)
#define USB2_SUSPEND_N_SEL BIT(3)
#define VBUS_DET_EXT_SEL BIT(4)
-#define USB_PHY_CFG_CTRL_4 (0x68)
+#define QCOM_USB_PHY_CFG_CTRL_4 (0x68)
#define PHY_CFG_PLL_GMP_CNTRL_MASK GENMASK(1, 0)
#define PHY_CFG_PLL_INT_CNTRL_MASK GENMASK(7, 2)
-#define USB_PHY_CFG_CTRL_5 (0x6c)
+#define QCOM_USB_PHY_CFG_CTRL_5 (0x6c)
#define PHY_CFG_PLL_PROP_CNTRL_MASK GENMASK(4, 0)
#define PHY_CFG_PLL_VREF_TUNE_MASK GENMASK(7, 6)
-#define USB_PHY_CFG_CTRL_6 (0x70)
+#define QCOM_USB_PHY_CFG_CTRL_6 (0x70)
#define PHY_CFG_PLL_VCO_CNTRL_MASK GENMASK(2, 0)
-#define USB_PHY_CFG_CTRL_7 (0x74)
+#define QCOM_USB_PHY_CFG_CTRL_7 (0x74)
-#define USB_PHY_CFG_CTRL_8 (0x78)
+#define QCOM_USB_PHY_CFG_CTRL_8 (0x78)
#define PHY_CFG_TX_FSLS_VREF_TUNE_MASK GENMASK(1, 0)
#define PHY_CFG_TX_FSLS_VREG_BYPASS BIT(2)
#define PHY_CFG_TX_HS_VREF_TUNE_MASK GENMASK(5, 3)
#define PHY_CFG_TX_HS_XV_TUNE_MASK GENMASK(7, 6)
-#define USB_PHY_CFG_CTRL_9 (0x7c)
+#define QCOM_USB_PHY_CFG_CTRL_9 (0x7c)
#define PHY_CFG_TX_PREEMP_TUNE_MASK GENMASK(2, 0)
#define PHY_CFG_TX_RES_TUNE_MASK GENMASK(4, 3)
#define PHY_CFG_TX_RISE_TUNE_MASK GENMASK(6, 5)
#define PHY_CFG_RCAL_BYPASS BIT(7)
-#define USB_PHY_CFG_CTRL_10 (0x80)
+#define QCOM_USB_PHY_CFG_CTRL_10 (0x80)
-#define USB_PHY_CFG0 (0x94)
+#define QCOM_USB_PHY_CFG0 (0x94)
#define DATAPATH_CTRL_OVERRIDE_EN BIT(0)
#define CMN_CTRL_OVERRIDE_EN BIT(1)
-#define UTMI_PHY_CMN_CTRL0 (0x98)
+#define QCOM_UTMI_PHY_CMN_CTRL0 (0x98)
#define TESTBURNIN BIT(6)
-#define USB_PHY_FSEL_SEL (0xb8)
+#define QCOM_USB_PHY_FSEL_SEL (0xb8)
#define FSEL_SEL BIT(0)
-#define USB_PHY_APB_ACCESS_CMD (0x130)
+#define QCOM_USB_PHY_APB_ACCESS_CMD (0x130)
#define RW_ACCESS BIT(0)
#define APB_START_CMD BIT(1)
#define APB_LOGIC_RESET BIT(2)
-#define USB_PHY_APB_ACCESS_STATUS (0x134)
+#define QCOM_USB_PHY_APB_ACCESS_STATUS (0x134)
#define ACCESS_DONE BIT(0)
#define TIMED_OUT BIT(1)
#define ACCESS_ERROR BIT(2)
#define ACCESS_IN_PROGRESS BIT(3)
-#define USB_PHY_APB_ADDRESS (0x138)
+#define QCOM_USB_PHY_APB_ADDRESS (0x138)
#define APB_REG_ADDR_MASK GENMASK(7, 0)
-#define USB_PHY_APB_WRDATA_LSB (0x13c)
+#define QCOM_USB_PHY_APB_WRDATA_LSB (0x13c)
#define APB_REG_WRDATA_7_0_MASK GENMASK(3, 0)
-#define USB_PHY_APB_WRDATA_MSB (0x140)
+#define QCOM_USB_PHY_APB_WRDATA_MSB (0x140)
#define APB_REG_WRDATA_15_8_MASK GENMASK(7, 4)
-#define USB_PHY_APB_RDDATA_LSB (0x144)
+#define QCOM_USB_PHY_APB_RDDATA_LSB (0x144)
#define APB_REG_RDDATA_7_0_MASK GENMASK(3, 0)
-#define USB_PHY_APB_RDDATA_MSB (0x148)
+#define QCOM_USB_PHY_APB_RDDATA_MSB (0x148)
#define APB_REG_RDDATA_15_8_MASK GENMASK(7, 4)
static const char * const eusb2_hsphy_vreg_names[] = {
@@ -121,7 +121,7 @@ static const char * const eusb2_hsphy_vreg_names[] = {
#define EUSB2_NUM_VREGS ARRAY_SIZE(eusb2_hsphy_vreg_names)
-struct qcom_snps_eusb2_hsphy {
+struct snps_eusb2_hsphy {
struct phy *phy;
void __iomem *base;
@@ -135,17 +135,17 @@ struct qcom_snps_eusb2_hsphy {
struct phy *repeater;
};
-static int qcom_snps_eusb2_hsphy_set_mode(struct phy *p, enum phy_mode mode, int submode)
+static int snps_eusb2_hsphy_set_mode(struct phy *p, enum phy_mode mode, int submode)
{
- struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p);
+ struct snps_eusb2_hsphy *phy = phy_get_drvdata(p);
phy->mode = mode;
return phy_set_mode_ext(phy->repeater, mode, submode);
}
-static void qcom_snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset,
- u32 mask, u32 val)
+static void snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset,
+ u32 mask, u32 val)
{
u32 reg;
@@ -158,65 +158,65 @@ static void qcom_snps_eusb2_hsphy_write_mask(void __iomem *base, u32 offset,
readl_relaxed(base + offset);
}
-static void qcom_eusb2_default_parameters(struct qcom_snps_eusb2_hsphy *phy)
+static void qcom_eusb2_default_parameters(struct snps_eusb2_hsphy *phy)
{
/* default parameters: tx pre-emphasis */
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9,
- PHY_CFG_TX_PREEMP_TUNE_MASK,
- FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9,
+ PHY_CFG_TX_PREEMP_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_PREEMP_TUNE_MASK, 0));
/* tx rise/fall time */
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9,
- PHY_CFG_TX_RISE_TUNE_MASK,
- FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9,
+ PHY_CFG_TX_RISE_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_RISE_TUNE_MASK, 0x2));
/* source impedance adjustment */
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_9,
- PHY_CFG_TX_RES_TUNE_MASK,
- FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_9,
+ PHY_CFG_TX_RES_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_RES_TUNE_MASK, 0x1));
/* dc voltage level adjustement */
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8,
- PHY_CFG_TX_HS_VREF_TUNE_MASK,
- FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_8,
+ PHY_CFG_TX_HS_VREF_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_HS_VREF_TUNE_MASK, 0x3));
/* transmitter HS crossover adjustement */
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_8,
- PHY_CFG_TX_HS_XV_TUNE_MASK,
- FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_8,
+ PHY_CFG_TX_HS_XV_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_TX_HS_XV_TUNE_MASK, 0x0));
}
-static int qcom_eusb2_ref_clk_init(struct qcom_snps_eusb2_hsphy *phy)
+static int qcom_eusb2_ref_clk_init(struct snps_eusb2_hsphy *phy)
{
unsigned long ref_clk_freq = clk_get_rate(phy->ref_clk);
switch (ref_clk_freq) {
case 19200000:
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
- FSEL_MASK,
- FIELD_PREP(FSEL_MASK, FSEL_19_2_MHZ_VAL));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0,
+ FSEL_MASK,
+ FIELD_PREP(FSEL_MASK, FSEL_19_2_MHZ_VAL));
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2,
- PHY_CFG_PLL_FB_DIV_7_0_MASK,
- DIV_7_0_19_2_MHZ_VAL);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_2,
+ PHY_CFG_PLL_FB_DIV_7_0_MASK,
+ DIV_7_0_19_2_MHZ_VAL);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3,
- PHY_CFG_PLL_FB_DIV_11_8_MASK,
- DIV_11_8_19_2_MHZ_VAL);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3,
+ PHY_CFG_PLL_FB_DIV_11_8_MASK,
+ DIV_11_8_19_2_MHZ_VAL);
break;
case 38400000:
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
- FSEL_MASK,
- FIELD_PREP(FSEL_MASK, FSEL_38_4_MHZ_VAL));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0,
+ FSEL_MASK,
+ FIELD_PREP(FSEL_MASK, FSEL_38_4_MHZ_VAL));
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_2,
- PHY_CFG_PLL_FB_DIV_7_0_MASK,
- DIV_7_0_38_4_MHZ_VAL);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_2,
+ PHY_CFG_PLL_FB_DIV_7_0_MASK,
+ DIV_7_0_38_4_MHZ_VAL);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3,
- PHY_CFG_PLL_FB_DIV_11_8_MASK,
- DIV_11_8_38_4_MHZ_VAL);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3,
+ PHY_CFG_PLL_FB_DIV_11_8_MASK,
+ DIV_11_8_38_4_MHZ_VAL);
break;
default:
@@ -224,15 +224,15 @@ static int qcom_eusb2_ref_clk_init(struct qcom_snps_eusb2_hsphy *phy)
return -EINVAL;
}
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_3,
- PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_3,
+ PHY_CFG_PLL_REF_DIV, PLL_REF_DIV_VAL);
return 0;
}
-static int qcom_snps_eusb2_hsphy_init(struct phy *p)
+static int snps_eusb2_hsphy_init(struct phy *p)
{
- struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p);
+ struct snps_eusb2_hsphy *phy = phy_get_drvdata(p);
int ret;
ret = regulator_bulk_enable(ARRAY_SIZE(phy->vregs), phy->vregs);
@@ -265,73 +265,73 @@ static int qcom_snps_eusb2_hsphy_init(struct phy *p)
goto disable_ref_clk;
}
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG0,
- CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG0,
+ CMN_CTRL_OVERRIDE_EN, CMN_CTRL_OVERRIDE_EN);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, POR);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL5, POR, POR);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
- PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0,
+ PHY_ENABLE | RETENABLEN, PHY_ENABLE | RETENABLEN);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_APB_ACCESS_CMD,
- APB_LOGIC_RESET, APB_LOGIC_RESET);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_APB_ACCESS_CMD,
+ APB_LOGIC_RESET, APB_LOGIC_RESET);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_UTMI_PHY_CMN_CTRL0, TESTBURNIN, 0);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_FSEL_SEL,
- FSEL_SEL, FSEL_SEL);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_FSEL_SEL,
+ FSEL_SEL, FSEL_SEL);
/* update ref_clk related registers */
ret = qcom_eusb2_ref_clk_init(phy);
if (ret)
- goto disable_ref_clk;
+ return ret;
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_1,
- PHY_CFG_PLL_CPBIAS_CNTRL_MASK,
- FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x1));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_1,
+ PHY_CFG_PLL_CPBIAS_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_CPBIAS_CNTRL_MASK, 0x1));
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4,
- PHY_CFG_PLL_INT_CNTRL_MASK,
- FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_4,
+ PHY_CFG_PLL_INT_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_INT_CNTRL_MASK, 0x8));
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_4,
- PHY_CFG_PLL_GMP_CNTRL_MASK,
- FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_4,
+ PHY_CFG_PLL_GMP_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_GMP_CNTRL_MASK, 0x1));
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5,
- PHY_CFG_PLL_PROP_CNTRL_MASK,
- FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_5,
+ PHY_CFG_PLL_PROP_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_PROP_CNTRL_MASK, 0x10));
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_6,
- PHY_CFG_PLL_VCO_CNTRL_MASK,
- FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_6,
+ PHY_CFG_PLL_VCO_CNTRL_MASK,
+ FIELD_PREP(PHY_CFG_PLL_VCO_CNTRL_MASK, 0x0));
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_CFG_CTRL_5,
- PHY_CFG_PLL_VREF_TUNE_MASK,
- FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1));
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_CFG_CTRL_5,
+ PHY_CFG_PLL_VREF_TUNE_MASK,
+ FIELD_PREP(PHY_CFG_PLL_VREF_TUNE_MASK, 0x1));
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2,
- VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2,
+ VBUS_DET_EXT_SEL, VBUS_DET_EXT_SEL);
/* set default parameters */
qcom_eusb2_default_parameters(phy);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2,
- USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
- USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2,
+ USB2_SUSPEND_N_SEL | USB2_SUSPEND_N,
+ USB2_SUSPEND_N_SEL | USB2_SUSPEND_N);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL0, SLEEPM, SLEEPM);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
- SIDDQ_SEL, SIDDQ_SEL);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0,
+ SIDDQ_SEL, SIDDQ_SEL);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL_COMMON0,
- SIDDQ, 0);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL_COMMON0,
+ SIDDQ, 0);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_UTMI_CTRL5, POR, 0);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_UTMI_CTRL5, POR, 0);
- qcom_snps_eusb2_hsphy_write_mask(phy->base, USB_PHY_HS_PHY_CTRL2,
- USB2_SUSPEND_N_SEL, 0);
+ snps_eusb2_hsphy_write_mask(phy->base, QCOM_USB_PHY_HS_PHY_CTRL2,
+ USB2_SUSPEND_N_SEL, 0);
return 0;
@@ -344,9 +344,9 @@ static int qcom_snps_eusb2_hsphy_init(struct phy *p)
return ret;
}
-static int qcom_snps_eusb2_hsphy_exit(struct phy *p)
+static int snps_eusb2_hsphy_exit(struct phy *p)
{
- struct qcom_snps_eusb2_hsphy *phy = phy_get_drvdata(p);
+ struct snps_eusb2_hsphy *phy = phy_get_drvdata(p);
clk_disable_unprepare(phy->ref_clk);
@@ -357,18 +357,18 @@ static int qcom_snps_eusb2_hsphy_exit(struct phy *p)
return 0;
}
-static const struct phy_ops qcom_snps_eusb2_hsphy_ops = {
- .init = qcom_snps_eusb2_hsphy_init,
- .exit = qcom_snps_eusb2_hsphy_exit,
- .set_mode = qcom_snps_eusb2_hsphy_set_mode,
+static const struct phy_ops snps_eusb2_hsphy_ops = {
+ .init = snps_eusb2_hsphy_init,
+ .exit = snps_eusb2_hsphy_exit,
+ .set_mode = snps_eusb2_hsphy_set_mode,
.owner = THIS_MODULE,
};
-static int qcom_snps_eusb2_hsphy_probe(struct platform_device *pdev)
+static int snps_eusb2_hsphy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- struct qcom_snps_eusb2_hsphy *phy;
+ struct snps_eusb2_hsphy *phy;
struct phy_provider *phy_provider;
struct phy *generic_phy;
int ret, i;
@@ -405,7 +405,7 @@ static int qcom_snps_eusb2_hsphy_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(phy->repeater),
"failed to get repeater\n");
- generic_phy = devm_phy_create(dev, NULL, &qcom_snps_eusb2_hsphy_ops);
+ generic_phy = devm_phy_create(dev, NULL, &snps_eusb2_hsphy_ops);
if (IS_ERR(generic_phy)) {
dev_err(dev, "failed to create phy %d\n", ret);
return PTR_ERR(generic_phy);
@@ -418,25 +418,23 @@ static int qcom_snps_eusb2_hsphy_probe(struct platform_device *pdev)
if (IS_ERR(phy_provider))
return PTR_ERR(phy_provider);
- dev_info(dev, "Registered Qcom-eUSB2 phy\n");
-
return 0;
}
-static const struct of_device_id qcom_snps_eusb2_hsphy_of_match_table[] = {
+static const struct of_device_id snps_eusb2_hsphy_of_match_table[] = {
{ .compatible = "qcom,sm8550-snps-eusb2-phy", },
{ },
};
-MODULE_DEVICE_TABLE(of, qcom_snps_eusb2_hsphy_of_match_table);
+MODULE_DEVICE_TABLE(of, snps_eusb2_hsphy_of_match_table);
-static struct platform_driver qcom_snps_eusb2_hsphy_driver = {
- .probe = qcom_snps_eusb2_hsphy_probe,
+static struct platform_driver snps_eusb2_hsphy_driver = {
+ .probe = snps_eusb2_hsphy_probe,
.driver = {
- .name = "qcom-snps-eusb2-hsphy",
- .of_match_table = qcom_snps_eusb2_hsphy_of_match_table,
+ .name = "snps-eusb2-hsphy",
+ .of_match_table = snps_eusb2_hsphy_of_match_table,
},
};
-module_platform_driver(qcom_snps_eusb2_hsphy_driver);
-MODULE_DESCRIPTION("Qualcomm SNPS eUSB2 HS PHY driver");
+module_platform_driver(snps_eusb2_hsphy_driver);
+MODULE_DESCRIPTION("Synopsys eUSB2 HS PHY driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index b982c3f0d4b5..a806a22b5eef 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -420,11 +420,9 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
if (of_property_read_bool(node, "extcon")) {
edev = extcon_get_edev_by_phandle(rphy->dev, 0);
- if (IS_ERR(edev)) {
- if (PTR_ERR(edev) != -EPROBE_DEFER)
- dev_err(rphy->dev, "Invalid or missing extcon\n");
- return PTR_ERR(edev);
- }
+ if (IS_ERR(edev))
+ return dev_err_probe(rphy->dev, PTR_ERR(edev),
+ "invalid or missing extcon\n");
} else {
/* Initialize extcon device */
edev = devm_extcon_dev_allocate(rphy->dev,
@@ -434,10 +432,9 @@ static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
return -ENOMEM;
ret = devm_extcon_dev_register(rphy->dev, edev);
- if (ret) {
- dev_err(rphy->dev, "failed to register extcon device\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(rphy->dev, ret,
+ "failed to register extcon device\n");
}
rphy->edev = edev;
@@ -789,17 +786,20 @@ static void rockchip_chg_detect_work(struct work_struct *work)
container_of(work, struct rockchip_usb2phy_port, chg_work.work);
struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
struct regmap *base = get_reg_base(rphy);
- bool is_dcd, tmout, vout;
+ bool is_dcd, tmout, vout, vbus_attach;
unsigned long delay;
+ vbus_attach = property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
+
dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
rphy->chg_state);
switch (rphy->chg_state) {
case USB_CHG_STATE_UNDEFINED:
- if (!rport->suspended)
+ if (!rport->suspended && !vbus_attach)
rockchip_usb2phy_power_off(rport->phy);
/* put the controller in non-driving mode */
- property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
+ if (!vbus_attach)
+ property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
/* Start DCD processing stage 1 */
rockchip_chg_enable_dcd(rphy, true);
rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
@@ -862,7 +862,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
fallthrough;
case USB_CHG_STATE_DETECTED:
/* put the controller in normal mode */
- property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
+ if (!vbus_attach)
+ property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
dev_dbg(&rport->phy->dev, "charger = %s\n",
chg_to_string(rphy->chg_type));
@@ -1392,10 +1393,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
}
ret = rockchip_usb2phy_clk480m_register(rphy);
- if (ret) {
- dev_err(dev, "failed to register 480m output clock\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register 480m output clock\n");
if (rphy->phy_cfg->phy_tuning) {
ret = rphy->phy_cfg->phy_tuning(rphy);
@@ -1415,8 +1414,7 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
if (IS_ERR(phy)) {
- dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
- ret = PTR_ERR(phy);
+ ret = dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
goto put_child;
}
@@ -1453,9 +1451,8 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
"rockchip_usb2phy",
rphy);
if (ret) {
- dev_err(rphy->dev,
- "failed to request usb2phy irq handle\n");
- goto put_child;
+ dev_err_probe(rphy->dev, ret, "failed to request usb2phy irq handle\n");
+ return ret;
}
}
diff --git a/drivers/phy/st/phy-stih407-usb.c b/drivers/phy/st/phy-stih407-usb.c
index a4ae2cca7f63..02e6117709dc 100644
--- a/drivers/phy/st/phy-stih407-usb.c
+++ b/drivers/phy/st/phy-stih407-usb.c
@@ -149,8 +149,6 @@ static int stih407_usb2_picophy_probe(struct platform_device *pdev)
if (IS_ERR(phy_provider))
return PTR_ERR(phy_provider);
- dev_info(dev, "STiH407 USB Generic picoPHY driver probed!");
-
return 0;
}
diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c
index d5e7e44000b5..4a8f2ab65571 100644
--- a/drivers/phy/st/phy-stm32-usbphyc.c
+++ b/drivers/phy/st/phy-stm32-usbphyc.c
@@ -712,7 +712,7 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
}
ret = of_property_read_u32(child, "reg", &index);
- if (ret || index > usbphyc->nphys) {
+ if (ret || index >= usbphyc->nphys) {
dev_err(&phy->dev, "invalid reg property: %d\n", ret);
if (!ret)
ret = -EINVAL;
@@ -757,8 +757,8 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
}
version = readl_relaxed(usbphyc->base + STM32_USBPHYC_VERSION);
- dev_info(dev, "registered rev:%lu.%lu\n",
- FIELD_GET(MAJREV, version), FIELD_GET(MINREV, version));
+ dev_dbg(dev, "registered rev: %lu.%lu\n",
+ FIELD_GET(MAJREV, version), FIELD_GET(MINREV, version));
return 0;
diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c
index e818f6c3980e..bec9616c4a2e 100644
--- a/drivers/phy/tegra/xusb-tegra186.c
+++ b/drivers/phy/tegra/xusb-tegra186.c
@@ -84,6 +84,7 @@
#define XUSB_PADCTL_USB2_BIAS_PAD_CTL0 0x284
#define BIAS_PAD_PD BIT(11)
#define HS_SQUELCH_LEVEL(x) (((x) & 0x7) << 0)
+#define HS_DISCON_LEVEL(x) (((x) & 0x7) << 3)
#define XUSB_PADCTL_USB2_BIAS_PAD_CTL1 0x288
#define USB2_TRK_START_TIMER(x) (((x) & 0x7f) << 12)
@@ -623,6 +624,8 @@ static void tegra186_utmi_bias_pad_power_on(struct tegra_xusb_padctl *padctl)
value &= ~BIAS_PAD_PD;
value &= ~HS_SQUELCH_LEVEL(~0);
value |= HS_SQUELCH_LEVEL(priv->calib.hs_squelch);
+ value &= ~HS_DISCON_LEVEL(~0);
+ value |= HS_DISCON_LEVEL(0x7);
padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
udelay(1);
diff --git a/drivers/phy/ti/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c
index 6b265992d988..e5918d3b486c 100644
--- a/drivers/phy/ti/phy-twl4030-usb.c
+++ b/drivers/phy/ti/phy-twl4030-usb.c
@@ -784,7 +784,6 @@ static int twl4030_usb_probe(struct platform_device *pdev)
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(twl->dev);
- dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
return 0;
}
diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
index b62b158cffd8..e9bade74997b 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
@@ -10,6 +10,8 @@
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/string.h>
#include <linux/wmi.h>
#include "bioscfg.h"
#include "../../firmware_attributes_class.h"
@@ -786,6 +788,12 @@ static int hp_init_bios_buffer_attribute(enum hp_wmi_data_type attr_type,
if (ret < 0)
goto buff_attr_exit;
+ if (strlen(str) == 0) {
+ pr_debug("Ignoring attribute with empty name\n");
+ ret = 0;
+ goto buff_attr_exit;
+ }
+
if (attr_type == HPWMI_PASSWORD_TYPE ||
attr_type == HPWMI_SECURE_PLATFORM_TYPE)
temp_kset = bioscfg_drv.authentication_dir_kset;
diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
index 3166ef328eba..f1eec0e4ba07 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
+++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
@@ -10,6 +10,7 @@
#include <linux/wmi.h>
#include <linux/types.h>
+#include <linux/string.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -56,14 +57,14 @@ enum mechanism_values {
#define PASSWD_MECHANISM_TYPES "password"
-#define HP_WMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4"
+#define HP_WMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4"
-#define HP_WMI_BIOS_STRING_GUID "988D08E3-68F4-4c35-AF3E-6A1B8106F83C"
+#define HP_WMI_BIOS_STRING_GUID "988D08E3-68F4-4C35-AF3E-6A1B8106F83C"
#define HP_WMI_BIOS_INTEGER_GUID "8232DE3D-663D-4327-A8F4-E293ADB9BF05"
#define HP_WMI_BIOS_ENUMERATION_GUID "2D114B49-2DFB-4130-B8FE-4A3C09E75133"
#define HP_WMI_BIOS_ORDERED_LIST_GUID "14EA9746-CE1F-4098-A0E0-7045CB4DA745"
#define HP_WMI_BIOS_PASSWORD_GUID "322F2028-0F84-4901-988E-015176049E2D"
-#define HP_WMI_SET_BIOS_SETTING_GUID "1F4C91EB-DC5C-460b-951D-C7CB9B4B8D5E"
+#define HP_WMI_SET_BIOS_SETTING_GUID "1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E"
enum hp_wmi_spm_commandtype {
HPWMI_SECUREPLATFORM_GET_STATE = 0x10,
@@ -285,8 +286,9 @@ enum hp_wmi_data_elements {
{ \
int i; \
\
- for (i = 0; i <= bioscfg_drv.type##_instances_count; i++) { \
- if (!strcmp(kobj->name, bioscfg_drv.type##_data[i].attr_name_kobj->name)) \
+ for (i = 0; i < bioscfg_drv.type##_instances_count; i++) { \
+ if (bioscfg_drv.type##_data[i].attr_name_kobj && \
+ !strcmp(kobj->name, bioscfg_drv.type##_data[i].attr_name_kobj->name)) \
return i; \
} \
return -EIO; \
diff --git a/drivers/pmdomain/imx/imx8m-blk-ctrl.c b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
index 0dfaf1d14035..ce452c2b1746 100644
--- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c
+++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
@@ -845,22 +845,25 @@ static int imx8mq_vpu_power_notifier(struct notifier_block *nb,
return NOTIFY_OK;
}
+/*
+ * For i.MX8MQ, the ADB in the VPUMIX domain has no separate reset and clock
+ * enable bits, but is ungated and reset together with the VPUs.
+ * Resetting G1 or G2 separately may led to system hang.
+ * Remove the rst_mask and clk_mask from the domain data of G1 and G2,
+ * Let imx8mq_vpu_power_notifier() do really vpu reset.
+ */
static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = {
[IMX8MQ_VPUBLK_PD_G1] = {
.name = "vpublk-g1",
.clk_names = (const char *[]){ "g1", },
.num_clks = 1,
.gpc_name = "g1",
- .rst_mask = BIT(1),
- .clk_mask = BIT(1),
},
[IMX8MQ_VPUBLK_PD_G2] = {
.name = "vpublk-g2",
.clk_names = (const char *[]){ "g2", },
.num_clks = 1,
.gpc_name = "g2",
- .rst_mask = BIT(0),
- .clk_mask = BIT(0),
},
};
diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c
index 1bb9f70ab04c..823604952b5e 100644
--- a/drivers/pmdomain/qcom/rpmhpd.c
+++ b/drivers/pmdomain/qcom/rpmhpd.c
@@ -217,6 +217,8 @@ static struct rpmhpd *sa8540p_rpmhpds[] = {
[SC8280XP_MMCX_AO] = &mmcx_ao,
[SC8280XP_MX] = &mx,
[SC8280XP_MX_AO] = &mx_ao,
+ [SC8280XP_MXC] = &mxc,
+ [SC8280XP_MXC_AO] = &mxc_ao,
[SC8280XP_NSP] = &nsp,
};
@@ -541,6 +543,8 @@ static struct rpmhpd *sc8280xp_rpmhpds[] = {
[SC8280XP_MMCX_AO] = &mmcx_ao,
[SC8280XP_MX] = &mx,
[SC8280XP_MX_AO] = &mx_ao,
+ [SC8280XP_MXC] = &mxc,
+ [SC8280XP_MXC_AO] = &mxc_ao,
[SC8280XP_NSP] = &nsp,
[SC8280XP_QPHY] = &qphy,
};
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 6f6019fb41c0..1ed12e86ee00 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -103,14 +103,16 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
return 0;
}
-int ptp_open(struct posix_clock *pc, fmode_t fmode)
+int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
{
return 0;
}
-long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
+long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+ unsigned long arg)
{
- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+ struct ptp_clock *ptp =
+ container_of(pccontext->clk, struct ptp_clock, clock);
struct ptp_sys_offset_extended *extoff = NULL;
struct ptp_sys_offset_precise precise_offset;
struct system_device_crosststamp xtstamp;
@@ -151,6 +153,10 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
case PTP_EXTTS_REQUEST:
case PTP_EXTTS_REQUEST2:
+ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
+ err = -EACCES;
+ break;
+ }
memset(&req, 0, sizeof(req));
if (copy_from_user(&req.extts, (void __user *)arg,
@@ -192,6 +198,10 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
case PTP_PEROUT_REQUEST:
case PTP_PEROUT_REQUEST2:
+ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
+ err = -EACCES;
+ break;
+ }
memset(&req, 0, sizeof(req));
if (copy_from_user(&req.perout, (void __user *)arg,
@@ -260,6 +270,10 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
case PTP_ENABLE_PPS:
case PTP_ENABLE_PPS2:
+ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
+ err = -EACCES;
+ break;
+ }
memset(&req, 0, sizeof(req));
if (!capable(CAP_SYS_TIME))
@@ -398,6 +412,10 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
case PTP_PIN_SETFUNC:
case PTP_PIN_SETFUNC2:
+ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
+ err = -EACCES;
+ break;
+ }
if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
err = -EFAULT;
break;
@@ -437,9 +455,11 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
return err;
}
-__poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
+__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
+ poll_table *wait)
{
- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+ struct ptp_clock *ptp =
+ container_of(pccontext->clk, struct ptp_clock, clock);
poll_wait(fp, &ptp->tsev_wq, wait);
@@ -448,10 +468,11 @@ __poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
#define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event))
-ssize_t ptp_read(struct posix_clock *pc,
- uint rdflags, char __user *buf, size_t cnt)
+ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
+ char __user *buf, size_t cnt)
{
- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+ struct ptp_clock *ptp =
+ container_of(pccontext->clk, struct ptp_clock, clock);
struct timestamp_event_queue *queue = &ptp->tsevq;
struct ptp_extts_event *event;
unsigned long flags;
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
index 3fbd1d68a9bc..e25be08fa6ae 100644
--- a/drivers/ptp/ptp_private.h
+++ b/drivers/ptp/ptp_private.h
@@ -136,16 +136,18 @@ extern struct class *ptp_class;
int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
enum ptp_pin_function func, unsigned int chan);
-long ptp_ioctl(struct posix_clock *pc,
- unsigned int cmd, unsigned long arg);
+long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+ unsigned long arg);
-int ptp_open(struct posix_clock *pc, fmode_t fmode);
+int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode);
-ssize_t ptp_read(struct posix_clock *pc,
- uint flags, char __user *buf, size_t cnt);
+int ptp_release(struct posix_clock_context *pccontext);
-__poll_t ptp_poll(struct posix_clock *pc,
- struct file *fp, poll_table *wait);
+ssize_t ptp_read(struct posix_clock_context *pccontext, uint flags, char __user *buf,
+ size_t cnt);
+
+__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
+ poll_table *wait);
/*
* see ptp_sysfs.c
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index a85d3a40ee49..ae2bea27a18a 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -878,6 +878,9 @@ qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha, void **pkt,
payload_size = sizeof(purex->els_frame_payload);
}
+ if (total_bytes > sizeof(item->iocb.iocb))
+ total_bytes = sizeof(item->iocb.iocb);
+
pending_bytes = total_bytes;
no_bytes = (pending_bytes > payload_size) ? payload_size :
pending_bytes;
@@ -1163,6 +1166,10 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt,
total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF)
- PURX_ELS_HEADER_SIZE;
+
+ if (total_bytes > sizeof(item->iocb.iocb))
+ total_bytes = sizeof(item->iocb.iocb);
+
pending_bytes = total_bytes;
entry_count = entry_count_remaining = purex->entry_count;
no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ?
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 43eff1107038..c4c05cf38aa5 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -282,11 +282,20 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head)
{
struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu);
struct Scsi_Host *shost = scmd->device->host;
- unsigned int busy = scsi_host_busy(shost);
+ unsigned int busy;
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
shost->host_failed++;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ /*
+ * The counting of busy requests needs to occur after adding to
+ * host_failed or after the lock acquire for adding to host_failed
+ * to prevent a race with host unbusy and missing an eh wakeup.
+ */
+ busy = scsi_host_busy(shost);
+
+ spin_lock_irqsave(shost->host_lock, flags);
scsi_eh_wakeup(shost, busy);
spin_unlock_irqrestore(shost->host_lock, flags);
}
@@ -1039,6 +1048,9 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
unsigned char *cmnd, int cmnd_size, unsigned sense_bytes)
{
struct scsi_device *sdev = scmd->device;
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ struct request *rq = scsi_cmd_to_rq(scmd);
+#endif
/*
* We need saved copies of a number of fields - this is because
@@ -1090,6 +1102,18 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
(sdev->lun << 5 & 0xe0);
+ /*
+ * Encryption must be disabled for the commands submitted by the error handler.
+ * Hence, clear the encryption context information.
+ */
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ ses->rq_crypt_keyslot = rq->crypt_keyslot;
+ ses->rq_crypt_ctx = rq->crypt_ctx;
+
+ rq->crypt_keyslot = NULL;
+ rq->crypt_ctx = NULL;
+#endif
+
/*
* Zero the sense buffer. The scsi spec mandates that any
* untransferred sense data should be interpreted as being zero.
@@ -1107,6 +1131,10 @@ EXPORT_SYMBOL(scsi_eh_prep_cmnd);
*/
void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
{
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ struct request *rq = scsi_cmd_to_rq(scmd);
+#endif
+
/*
* Restore original data
*/
@@ -1119,6 +1147,11 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
scmd->underflow = ses->underflow;
scmd->prot_op = ses->prot_op;
scmd->eh_eflags = ses->eh_eflags;
+
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ rq->crypt_keyslot = ses->rq_crypt_keyslot;
+ rq->crypt_ctx = ses->rq_crypt_ctx;
+#endif
}
EXPORT_SYMBOL(scsi_eh_restore_cmnd);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index bd75e3ebc14d..efd1f1d6e4e9 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -278,6 +278,14 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
rcu_read_lock();
__clear_bit(SCMD_STATE_INFLIGHT, &cmd->state);
if (unlikely(scsi_host_in_recovery(shost))) {
+ /*
+ * Ensure the clear of SCMD_STATE_INFLIGHT is visible to
+ * other CPUs before counting busy requests. Otherwise,
+ * reordering can cause CPUs to race and miss an eh wakeup
+ * when no CPU sees all busy requests as done or timed out.
+ */
+ smp_mb();
+
unsigned int busy = scsi_host_busy(shost);
spin_lock_irqsave(shost->host_lock, flags);
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 954a1cc50ba7..9dcad02ce489 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1145,7 +1145,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
* The current SCSI handling on the host side does
* not correctly handle:
* INQUIRY command with page code parameter set to 0x80
- * MODE_SENSE command with cmd[2] == 0x1c
+ * MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c
* MAINTENANCE_IN is not supported by HyperV FC passthrough
*
* Setup srb and scsi status so this won't be fatal.
@@ -1155,6 +1155,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device,
if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
(stor_pkt->vm_srb.cdb[0] == MODE_SENSE) ||
+ (stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) ||
(stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN &&
hv_dev_is_fc(device))) {
vstor_packet->vm_srb.scsi_status = 0;
diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c
index 01cbd4621981..fdc099abd2cc 100644
--- a/drivers/slimbus/core.c
+++ b/drivers/slimbus/core.c
@@ -378,6 +378,8 @@ struct slim_device *slim_get_device(struct slim_controller *ctrl,
sbdev = slim_alloc_device(ctrl, e_addr, NULL);
if (!sbdev)
return ERR_PTR(-ENOMEM);
+
+ get_device(&sbdev->dev);
}
return sbdev;
@@ -496,21 +498,24 @@ int slim_device_report_present(struct slim_controller *ctrl,
if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n",
ctrl->sched.clk_state, ret);
- goto slimbus_not_active;
+ goto out_put_rpm;
}
sbdev = slim_get_device(ctrl, e_addr);
- if (IS_ERR(sbdev))
- return -ENODEV;
+ if (IS_ERR(sbdev)) {
+ ret = -ENODEV;
+ goto out_put_rpm;
+ }
if (sbdev->is_laddr_valid) {
*laddr = sbdev->laddr;
- return 0;
+ ret = 0;
+ } else {
+ ret = slim_device_alloc_laddr(sbdev, true);
}
- ret = slim_device_alloc_laddr(sbdev, true);
-
-slimbus_not_active:
+ put_device(&sbdev->dev);
+out_put_rpm:
pm_runtime_mark_last_busy(ctrl->dev);
pm_runtime_put_autosuspend(ctrl->dev);
return ret;
diff --git a/drivers/spi/spi-sprd-adi.c b/drivers/spi/spi-sprd-adi.c
index bf01feedbf93..f25b34a91756 100644
--- a/drivers/spi/spi-sprd-adi.c
+++ b/drivers/spi/spi-sprd-adi.c
@@ -138,8 +138,7 @@ struct sprd_adi_data {
u32 slave_offset;
u32 slave_addr_size;
int (*read_check)(u32 val, u32 reg);
- int (*restart)(struct notifier_block *this,
- unsigned long mode, void *cmd);
+ int (*restart)(struct sys_off_data *data);
void (*wdg_rst)(void *p);
};
@@ -150,7 +149,6 @@ struct sprd_adi {
struct hwspinlock *hwlock;
unsigned long slave_vbase;
unsigned long slave_pbase;
- struct notifier_block restart_handler;
const struct sprd_adi_data *data;
};
@@ -370,11 +368,9 @@ static void sprd_adi_set_wdt_rst_mode(void *p)
#endif
}
-static int sprd_adi_restart(struct notifier_block *this, unsigned long mode,
- void *cmd, struct sprd_adi_wdg *wdg)
+static int sprd_adi_restart(struct sprd_adi *sadi, unsigned long mode,
+ const char *cmd, struct sprd_adi_wdg *wdg)
{
- struct sprd_adi *sadi = container_of(this, struct sprd_adi,
- restart_handler);
u32 val, reboot_mode = 0;
if (!cmd)
@@ -448,8 +444,7 @@ static int sprd_adi_restart(struct notifier_block *this, unsigned long mode,
return NOTIFY_DONE;
}
-static int sprd_adi_restart_sc9860(struct notifier_block *this,
- unsigned long mode, void *cmd)
+static int sprd_adi_restart_sc9860(struct sys_off_data *data)
{
struct sprd_adi_wdg wdg = {
.base = PMIC_WDG_BASE,
@@ -458,7 +453,7 @@ static int sprd_adi_restart_sc9860(struct notifier_block *this,
.wdg_clk = PMIC_CLK_EN,
};
- return sprd_adi_restart(this, mode, cmd, &wdg);
+ return sprd_adi_restart(data->cb_data, data->mode, data->cmd, &wdg);
}
static void sprd_adi_hw_init(struct sprd_adi *sadi)
@@ -533,7 +528,7 @@ static int sprd_adi_probe(struct platform_device *pdev)
pdev->id = of_alias_get_id(np, "spi");
num_chipselect = of_get_child_count(np);
- ctlr = spi_alloc_master(&pdev->dev, sizeof(struct sprd_adi));
+ ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(struct sprd_adi));
if (!ctlr)
return -ENOMEM;
@@ -541,10 +536,8 @@ static int sprd_adi_probe(struct platform_device *pdev)
sadi = spi_controller_get_devdata(ctlr);
sadi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(sadi->base)) {
- ret = PTR_ERR(sadi->base);
- goto put_ctlr;
- }
+ if (IS_ERR(sadi->base))
+ return PTR_ERR(sadi->base);
sadi->slave_vbase = (unsigned long)sadi->base +
data->slave_offset;
@@ -556,18 +549,15 @@ static int sprd_adi_probe(struct platform_device *pdev)
if (ret > 0 || (IS_ENABLED(CONFIG_HWSPINLOCK) && ret == 0)) {
sadi->hwlock =
devm_hwspin_lock_request_specific(&pdev->dev, ret);
- if (!sadi->hwlock) {
- ret = -ENXIO;
- goto put_ctlr;
- }
+ if (!sadi->hwlock)
+ return -ENXIO;
} else {
switch (ret) {
case -ENOENT:
dev_info(&pdev->dev, "no hardware spinlock supplied\n");
break;
default:
- dev_err_probe(&pdev->dev, ret, "failed to find hwlock id\n");
- goto put_ctlr;
+ return dev_err_probe(&pdev->dev, ret, "failed to find hwlock id\n");
}
}
@@ -584,34 +574,18 @@ static int sprd_adi_probe(struct platform_device *pdev)
ctlr->transfer_one = sprd_adi_transfer_one;
ret = devm_spi_register_controller(&pdev->dev, ctlr);
- if (ret) {
- dev_err(&pdev->dev, "failed to register SPI controller\n");
- goto put_ctlr;
- }
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "failed to register SPI controller\n");
if (sadi->data->restart) {
- sadi->restart_handler.notifier_call = sadi->data->restart;
- sadi->restart_handler.priority = 128;
- ret = register_restart_handler(&sadi->restart_handler);
- if (ret) {
- dev_err(&pdev->dev, "can not register restart handler\n");
- goto put_ctlr;
- }
+ ret = devm_register_restart_handler(&pdev->dev,
+ sadi->data->restart,
+ sadi);
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "can not register restart handler\n");
}
return 0;
-
-put_ctlr:
- spi_controller_put(ctlr);
- return ret;
-}
-
-static void sprd_adi_remove(struct platform_device *pdev)
-{
- struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
- struct sprd_adi *sadi = spi_controller_get_devdata(ctlr);
-
- unregister_restart_handler(&sadi->restart_handler);
}
static struct sprd_adi_data sc9860_data = {
@@ -657,7 +631,6 @@ static struct platform_driver sprd_adi_driver = {
.of_match_table = sprd_adi_of_match,
},
.probe = sprd_adi_probe,
- .remove_new = sprd_adi_remove,
};
module_platform_driver(sprd_adi_driver);
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 18fddd65c010..623fd4aa8499 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1563,7 +1563,7 @@ static int pci_fintek_rs485_config(struct uart_port *port, struct ktermios *term
}
static const struct serial_rs485 pci_fintek_rs485_supported = {
- .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND,
+ .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND,
/* F81504/508/512 does not support RTS delay before or after send */
};
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 3180419424c0..10a1bc059ea1 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -1004,6 +1004,11 @@ int usb_get_bos_descriptor(struct usb_device *dev)
__u8 cap_type;
int ret;
+ if (dev->quirks & USB_QUIRK_NO_BOS) {
+ dev_dbg(ddev, "skipping BOS descriptor\n");
+ return -ENOMSG;
+ }
+
bos = kzalloc(sizeof(*bos), GFP_KERNEL);
if (!bos)
return -ENOMEM;
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index c322d0c1d965..323a949bbb05 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -447,6 +447,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x0c45, 0x7056), .driver_info =
USB_QUIRK_IGNORE_REMOTE_WAKEUP },
+ /* Elgato 4K X - BOS descriptor fetch hangs at SuperSpeed Plus */
+ { USB_DEVICE(0x0fd9, 0x009b), .driver_info = USB_QUIRK_NO_BOS },
+
/* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */
{ USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM },
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 22975a4b19a4..45c9a399f8a5 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -892,6 +892,8 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc)
reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
dwc->ip = DWC3_GSNPS_ID(reg);
+ if (dwc->ip == DWC4_IP)
+ dwc->ip = DWC32_IP;
/* This should read as U3 followed by revision number */
if (DWC3_IP_IS(DWC3)) {
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 06be72f78969..9fc91f5c0bdb 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1221,6 +1221,7 @@ struct dwc3 {
#define DWC3_IP 0x5533
#define DWC31_IP 0x3331
#define DWC32_IP 0x3332
+#define DWC4_IP 0x3430
u32 revision;
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index 4a75507325dd..1cd4757f24da 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -376,3 +376,4 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("Hauke Mehrtens");
MODULE_AUTHOR("Alan Stern");
MODULE_LICENSE("GPL");
+MODULE_SOFTDEP("pre: ehci_platform");
diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 712389599d46..55b61df0ebb7 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -191,3 +191,4 @@ static struct platform_driver uhci_platform_driver = {
.of_match_table = platform_uhci_ids,
},
};
+MODULE_SOFTDEP("pre: ehci_platform");
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 53f36762de9b..02c738a6e511 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -850,6 +850,7 @@ static const struct usb_device_id id_table_combined[] = {
{ USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID, 1) },
{ USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID, 1) },
{ USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID, 1) },
+ { USB_DEVICE(FTDI_VID, FTDI_AXE027_PID) },
{ USB_DEVICE_INTERFACE_NUMBER(FTDI_VID, FTDI_TURTELIZER_PID, 1) },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_SCU18) },
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 2539b9e2f712..6c76cfebfd0e 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -96,6 +96,8 @@
#define LMI_LM3S_EVAL_BOARD_PID 0xbcd9
#define LMI_LM3S_ICDI_BOARD_PID 0xbcda
+#define FTDI_AXE027_PID 0xBD90 /* PICAXE AXE027 USB download cable */
+
#define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmbH */
/* OpenDCC (www.opendcc.de) product id */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 2dfbf62d934a..60993836cf91 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1505,6 +1505,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff), /* Telit LE910Cx (RNDIS) */
.driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x1250, 0xff, 0x00, 0x00) }, /* Telit LE910Cx (rmnet) */
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1252, 0xff) }, /* Telit LE910Cx (MBIM) */
{ USB_DEVICE(TELIT_VENDOR_ID, 0x1260),
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
{ USB_DEVICE(TELIT_VENDOR_ID, 0x1261),
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 2e39686e01c9..5e6d68958409 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -6637,7 +6637,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
port->port_type = port->typec_caps.type;
port->role_sw = fwnode_usb_role_switch_get(tcpc->fwnode);
- if (!port->role_sw)
+ if (IS_ERR_OR_NULL(port->role_sw))
port->role_sw = usb_role_switch_get(port->dev);
if (IS_ERR(port->role_sw)) {
err = PTR_ERR(port->role_sw);
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index c85e80c7e130..3cbb23bbe236 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -1846,53 +1846,35 @@ static ssize_t alarms_store(struct device *device,
struct w1_slave *sl = dev_to_w1_slave(device);
struct therm_info info;
u8 new_config_register[3]; /* array of data to be written */
- int temp, ret;
- char *token = NULL;
+ long long temp;
+ int ret = 0;
s8 tl, th; /* 1 byte per value + temp ring order */
- char *p_args, *orig;
-
- p_args = orig = kmalloc(size, GFP_KERNEL);
- /* Safe string copys as buf is const */
- if (!p_args) {
- dev_warn(device,
- "%s: error unable to allocate memory %d\n",
- __func__, -ENOMEM);
- return size;
- }
- strcpy(p_args, buf);
-
- /* Split string using space char */
- token = strsep(&p_args, " ");
-
- if (!token) {
- dev_info(device,
- "%s: error parsing args %d\n", __func__, -EINVAL);
- goto free_m;
- }
-
- /* Convert 1st entry to int */
- ret = kstrtoint (token, 10, &temp);
+ const char *p = buf;
+ char *endp;
+
+ temp = simple_strtoll(p, &endp, 10);
+ if (p == endp || *endp != ' ')
+ ret = -EINVAL;
+ else if (temp < INT_MIN || temp > INT_MAX)
+ ret = -ERANGE;
if (ret) {
dev_info(device,
"%s: error parsing args %d\n", __func__, ret);
- goto free_m;
+ return size;
}
tl = int_to_short(temp);
- /* Split string using space char */
- token = strsep(&p_args, " ");
- if (!token) {
- dev_info(device,
- "%s: error parsing args %d\n", __func__, -EINVAL);
- goto free_m;
- }
- /* Convert 2nd entry to int */
- ret = kstrtoint (token, 10, &temp);
+ p = endp + 1;
+ temp = simple_strtoll(p, &endp, 10);
+ if (p == endp)
+ ret = -EINVAL;
+ else if (temp < INT_MIN || temp > INT_MAX)
+ ret = -ERANGE;
if (ret) {
dev_info(device,
"%s: error parsing args %d\n", __func__, ret);
- goto free_m;
+ return size;
}
/* Prepare to cast to short by eliminating out of range values */
@@ -1915,7 +1897,7 @@ static ssize_t alarms_store(struct device *device,
dev_info(device,
"%s: error reading from the slave device %d\n",
__func__, ret);
- goto free_m;
+ return size;
}
/* Write data in the device RAM */
@@ -1923,7 +1905,7 @@ static ssize_t alarms_store(struct device *device,
dev_info(device,
"%s: Device not supported by the driver %d\n",
__func__, -ENODEV);
- goto free_m;
+ return size;
}
ret = SLAVE_SPECIFIC_FUNC(sl)->write_data(sl, new_config_register);
@@ -1932,10 +1914,6 @@ static ssize_t alarms_store(struct device *device,
"%s: error writing to the slave device %d\n",
__func__, ret);
-free_m:
- /* free allocated memory */
- kfree(orig);
-
return size;
}
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 5353cbd75126..570c1ff780fc 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -758,8 +758,6 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
if (err < 0) {
dev_err(&dev->dev, "%s: Attaching %s failed.\n", __func__,
sl->name);
- dev->slave_count--;
- w1_family_put(sl->family);
atomic_dec(&sl->master->refcnt);
kfree(sl);
return err;
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 8b77e4c06e43..3fbea676b377 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1262,6 +1262,7 @@ static void scsiback_remove(struct xenbus_device *dev)
gnttab_page_cache_shrink(&info->free_pages, 0);
dev_set_drvdata(&dev->dev, NULL);
+ kfree(info);
}
static int scsiback_probe(struct xenbus_device *dev,
diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
index 5a3a41c6d509..2dda388c9853 100644
--- a/fs/btrfs/block-group.c
+++ b/fs/btrfs/block-group.c
@@ -4377,6 +4377,43 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info)
}
}
+static void check_removing_space_info(struct btrfs_space_info *space_info)
+{
+ struct btrfs_fs_info *info = space_info->fs_info;
+
+ if (space_info->subgroup_id == BTRFS_SUB_GROUP_PRIMARY) {
+ /* This is a top space_info, proceed with its children first. */
+ for (int i = 0; i < BTRFS_SPACE_INFO_SUB_GROUP_MAX; i++) {
+ if (space_info->sub_group[i]) {
+ check_removing_space_info(space_info->sub_group[i]);
+ kfree(space_info->sub_group[i]);
+ space_info->sub_group[i] = NULL;
+ }
+ }
+ }
+
+ /*
+ * Do not hide this behind enospc_debug, this is actually important and
+ * indicates a real bug if this happens.
+ */
+ if (WARN_ON(space_info->bytes_pinned > 0 || space_info->bytes_may_use > 0))
+ btrfs_dump_space_info(info, space_info, 0, 0);
+
+ /*
+ * If there was a failure to cleanup a log tree, very likely due to an
+ * IO failure on a writeback attempt of one or more of its extent
+ * buffers, we could not do proper (and cheap) unaccounting of their
+ * reserved space, so don't warn on bytes_reserved > 0 in that case.
+ */
+ if (!(space_info->flags & BTRFS_BLOCK_GROUP_METADATA) ||
+ !BTRFS_FS_LOG_CLEANUP_ERROR(info)) {
+ if (WARN_ON(space_info->bytes_reserved > 0))
+ btrfs_dump_space_info(info, space_info, 0, 0);
+ }
+
+ WARN_ON(space_info->reclaim_size > 0);
+}
+
/*
* Must be called only after stopping all workers, since we could have block
* group caching kthreads running, and therefore they could race with us if we
@@ -4478,28 +4515,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
struct btrfs_space_info,
list);
- /*
- * Do not hide this behind enospc_debug, this is actually
- * important and indicates a real bug if this happens.
- */
- if (WARN_ON(space_info->bytes_pinned > 0 ||
- space_info->bytes_may_use > 0))
- btrfs_dump_space_info(info, space_info, 0, 0);
-
- /*
- * If there was a failure to cleanup a log tree, very likely due
- * to an IO failure on a writeback attempt of one or more of its
- * extent buffers, we could not do proper (and cheap) unaccounting
- * of their reserved space, so don't warn on bytes_reserved > 0 in
- * that case.
- */
- if (!(space_info->flags & BTRFS_BLOCK_GROUP_METADATA) ||
- !BTRFS_FS_LOG_CLEANUP_ERROR(info)) {
- if (WARN_ON(space_info->bytes_reserved > 0))
- btrfs_dump_space_info(info, space_info, 0, 0);
- }
-
- WARN_ON(space_info->reclaim_size > 0);
+ check_removing_space_info(space_info);
list_del(&space_info->list);
btrfs_sysfs_remove_space_info(space_info);
}
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 7ad1734cbbfc..3c26e91a8055 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1654,7 +1654,7 @@ static void backup_super_roots(struct btrfs_fs_info *info)
btrfs_set_backup_chunk_root_level(root_backup,
btrfs_header_level(info->chunk_root->node));
- if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) {
+ if (!btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index c25eb4416a67..6768e2231d61 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -6545,6 +6545,8 @@ static int range_is_hole_in_parent(struct send_ctx *sctx,
extent_end = btrfs_file_extent_end(path);
if (extent_end <= start)
goto next;
+ if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE)
+ return 0;
if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0) {
search_start = extent_end;
goto next;
diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c
index 27690c518f6d..00d596a8176f 100644
--- a/fs/btrfs/space-info.c
+++ b/fs/btrfs/space-info.c
@@ -222,18 +222,11 @@ void btrfs_update_space_info_chunk_size(struct btrfs_space_info *space_info,
WRITE_ONCE(space_info->chunk_size, chunk_size);
}
-static int create_space_info(struct btrfs_fs_info *info, u64 flags)
+static void init_space_info(struct btrfs_fs_info *info,
+ struct btrfs_space_info *space_info, u64 flags)
{
-
- struct btrfs_space_info *space_info;
- int i;
- int ret;
-
- space_info = kzalloc(sizeof(*space_info), GFP_NOFS);
- if (!space_info)
- return -ENOMEM;
-
- for (i = 0; i < BTRFS_NR_RAID_TYPES; i++)
+ space_info->fs_info = info;
+ for (int i = 0; i < BTRFS_NR_RAID_TYPES; i++)
INIT_LIST_HEAD(&space_info->block_groups[i]);
init_rwsem(&space_info->groups_sem);
spin_lock_init(&space_info->lock);
@@ -244,19 +237,73 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags)
INIT_LIST_HEAD(&space_info->priority_tickets);
space_info->clamp = 1;
btrfs_update_space_info_chunk_size(space_info, calc_chunk_size(info, flags));
+ space_info->subgroup_id = BTRFS_SUB_GROUP_PRIMARY;
if (btrfs_is_zoned(info))
space_info->bg_reclaim_threshold = BTRFS_DEFAULT_ZONED_RECLAIM_THRESH;
+}
+
+static int create_space_info_sub_group(struct btrfs_space_info *parent, u64 flags,
+ enum btrfs_space_info_sub_group id, int index)
+{
+ struct btrfs_fs_info *fs_info = parent->fs_info;
+ struct btrfs_space_info *sub_group;
+ int ret;
+
+ ASSERT(parent->subgroup_id == BTRFS_SUB_GROUP_PRIMARY);
+ ASSERT(id != BTRFS_SUB_GROUP_PRIMARY);
+
+ sub_group = kzalloc(sizeof(*sub_group), GFP_NOFS);
+ if (!sub_group)
+ return -ENOMEM;
+
+ init_space_info(fs_info, sub_group, flags);
+ parent->sub_group[index] = sub_group;
+ sub_group->parent = parent;
+ sub_group->subgroup_id = id;
+
+ ret = btrfs_sysfs_add_space_info_type(fs_info, sub_group);
+ if (ret) {
+ kfree(sub_group);
+ parent->sub_group[index] = NULL;
+ }
+ return ret;
+}
+
+static int create_space_info(struct btrfs_fs_info *info, u64 flags)
+{
+
+ struct btrfs_space_info *space_info;
+ int ret = 0;
+
+ space_info = kzalloc(sizeof(*space_info), GFP_NOFS);
+ if (!space_info)
+ return -ENOMEM;
+
+ init_space_info(info, space_info, flags);
+
+ if (btrfs_is_zoned(info)) {
+ if (flags & BTRFS_BLOCK_GROUP_DATA)
+ ret = create_space_info_sub_group(space_info, flags,
+ BTRFS_SUB_GROUP_DATA_RELOC,
+ 0);
+ if (ret)
+ goto out_free;
+ }
ret = btrfs_sysfs_add_space_info_type(info, space_info);
if (ret)
- return ret;
+ goto out_free;
list_add(&space_info->list, &info->space_info);
if (flags & BTRFS_BLOCK_GROUP_DATA)
info->data_sinfo = space_info;
return ret;
+
+out_free:
+ kfree(space_info);
+ return ret;
}
int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
@@ -490,8 +537,9 @@ static void __btrfs_dump_space_info(const struct btrfs_fs_info *fs_info,
lockdep_assert_held(&info->lock);
/* The free space could be negative in case of overcommit */
- btrfs_info(fs_info, "space_info %s has %lld free, is %sfull",
- flag_str,
+ btrfs_info(fs_info,
+ "space_info %s (sub-group id %d) has %lld free, is %sfull",
+ flag_str, info->subgroup_id,
(s64)(info->total_bytes - btrfs_space_info_used(info, true)),
info->full ? "" : "not ");
btrfs_info(fs_info,
diff --git a/fs/btrfs/space-info.h b/fs/btrfs/space-info.h
index b0187f25dbb5..0670f074902d 100644
--- a/fs/btrfs/space-info.h
+++ b/fs/btrfs/space-info.h
@@ -83,7 +83,17 @@ enum btrfs_flush_state {
COMMIT_TRANS = 11,
};
+enum btrfs_space_info_sub_group {
+ BTRFS_SUB_GROUP_PRIMARY,
+ BTRFS_SUB_GROUP_DATA_RELOC,
+};
+
+#define BTRFS_SPACE_INFO_SUB_GROUP_MAX 1
struct btrfs_space_info {
+ struct btrfs_fs_info *fs_info;
+ struct btrfs_space_info *parent;
+ struct btrfs_space_info *sub_group[BTRFS_SPACE_INFO_SUB_GROUP_MAX];
+ int subgroup_id;
spinlock_t lock;
u64 total_bytes; /* total bytes in the space,
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index 512d4cbac1ca..9609579d2289 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -1641,16 +1641,28 @@ void btrfs_sysfs_remove_space_info(struct btrfs_space_info *space_info)
kobject_put(&space_info->kobj);
}
-static const char *alloc_name(u64 flags)
+static const char *alloc_name(struct btrfs_space_info *space_info)
{
+ u64 flags = space_info->flags;
+
switch (flags) {
case BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA:
return "mixed";
case BTRFS_BLOCK_GROUP_METADATA:
+ ASSERT(space_info->subgroup_id == BTRFS_SUB_GROUP_PRIMARY);
return "metadata";
case BTRFS_BLOCK_GROUP_DATA:
- return "data";
+ switch (space_info->subgroup_id) {
+ case BTRFS_SUB_GROUP_PRIMARY:
+ return "data";
+ case BTRFS_SUB_GROUP_DATA_RELOC:
+ return "data-reloc";
+ default:
+ WARN_ON_ONCE(1);
+ return "data (unknown sub-group)";
+ }
case BTRFS_BLOCK_GROUP_SYSTEM:
+ ASSERT(space_info->subgroup_id == BTRFS_SUB_GROUP_PRIMARY);
return "system";
default:
WARN_ON(1);
@@ -1669,7 +1681,7 @@ int btrfs_sysfs_add_space_info_type(struct btrfs_fs_info *fs_info,
ret = kobject_init_and_add(&space_info->kobj, &space_info_ktype,
fs_info->space_info_kobj, "%s",
- alloc_name(space_info->flags));
+ alloc_name(space_info));
if (ret) {
kobject_put(&space_info->kobj);
return ret;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 20add63421b3..ce1e5b5dae3a 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -517,13 +517,14 @@ static inline int is_transaction_blocked(struct btrfs_transaction *trans)
* when this is done, it is safe to start a new transaction, but the current
* transaction might not be fully on disk.
*/
-static void wait_current_trans(struct btrfs_fs_info *fs_info)
+static void wait_current_trans(struct btrfs_fs_info *fs_info, unsigned int type)
{
struct btrfs_transaction *cur_trans;
spin_lock(&fs_info->trans_lock);
cur_trans = fs_info->running_transaction;
- if (cur_trans && is_transaction_blocked(cur_trans)) {
+ if (cur_trans && is_transaction_blocked(cur_trans) &&
+ (btrfs_blocked_trans_types[cur_trans->state] & type)) {
refcount_inc(&cur_trans->use_count);
spin_unlock(&fs_info->trans_lock);
@@ -676,12 +677,12 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
sb_start_intwrite(fs_info->sb);
if (may_wait_transaction(fs_info, type))
- wait_current_trans(fs_info);
+ wait_current_trans(fs_info, type);
do {
ret = join_transaction(fs_info, type);
if (ret == -EBUSY) {
- wait_current_trans(fs_info);
+ wait_current_trans(fs_info, type);
if (unlikely(type == TRANS_ATTACH ||
type == TRANS_JOIN_NOSTART))
ret = -ENOENT;
@@ -966,7 +967,7 @@ int btrfs_wait_for_commit(struct btrfs_fs_info *fs_info, u64 transid)
void btrfs_throttle(struct btrfs_fs_info *fs_info)
{
- wait_current_trans(fs_info);
+ wait_current_trans(fs_info, TRANS_START);
}
bool btrfs_should_end_transaction(struct btrfs_trans_handle *trans)
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index ad6e11a42f40..bb4b7f280267 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1037,6 +1037,7 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode,
ext4_error_inode(ea_inode, __func__, __LINE__, 0,
"EA inode %lu ref wraparound: ref_count=%lld ref_change=%d",
ea_inode->i_ino, ref_count, ref_change);
+ brelse(iloc.bh);
ret = -EFSCORRUPTED;
goto out;
}
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index b25b741e3c96..483f69807062 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -492,7 +492,7 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs)
new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO);
bio_clone_blkg_association(new, prev);
new->bi_iter.bi_sector = bio_end_sector(prev);
- bio_chain(prev, new);
+ bio_chain(new, prev);
submit_bio(prev);
return new;
}
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index 95d5dca67145..ed18e9e87c25 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -103,7 +103,7 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
sizeof(struct nfs4_ff_ds_version),
gfp_flags);
if (!ds_versions)
- goto out_scratch;
+ goto out_err_drain_dsaddrs;
for (i = 0; i < version_count; i++) {
/* 20 = version(4) + minor_version(4) + rsize(4) + wsize(4) +
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 185994185fac..78ebdf20c1ef 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1582,12 +1582,9 @@ static int __init init_nfsd(void)
if (retval)
goto out_free_pnfs;
nfsd_lockd_init(); /* lockd->nfsd callbacks */
- retval = create_proc_exports_entry();
- if (retval)
- goto out_free_lockd;
retval = register_pernet_subsys(&nfsd_net_ops);
if (retval < 0)
- goto out_free_exports;
+ goto out_free_lockd;
retval = register_cld_notifier();
if (retval)
goto out_free_subsys;
@@ -1595,18 +1592,20 @@ static int __init init_nfsd(void)
if (retval)
goto out_free_cld;
retval = register_filesystem(&nfsd_fs_type);
+ if (retval)
+ goto out_free_nfsd4;
+ retval = create_proc_exports_entry();
if (retval)
goto out_free_all;
return 0;
out_free_all:
+ unregister_filesystem(&nfsd_fs_type);
+out_free_nfsd4:
nfsd4_destroy_laundry_wq();
out_free_cld:
unregister_cld_notifier();
out_free_subsys:
unregister_pernet_subsys(&nfsd_net_ops);
-out_free_exports:
- remove_proc_entry("fs/nfs/exports", NULL);
- remove_proc_entry("fs/nfs", NULL);
out_free_lockd:
nfsd_lockd_shutdown();
nfsd_drc_slab_free();
@@ -1619,13 +1618,13 @@ static int __init init_nfsd(void)
static void __exit exit_nfsd(void)
{
+ remove_proc_entry("fs/nfs/exports", NULL);
+ remove_proc_entry("fs/nfs", NULL);
unregister_filesystem(&nfsd_fs_type);
nfsd4_destroy_laundry_wq();
unregister_cld_notifier();
unregister_pernet_subsys(&nfsd_net_ops);
nfsd_drc_slab_free();
- remove_proc_entry("fs/nfs/exports", NULL);
- remove_proc_entry("fs/nfs", NULL);
nfsd_lockd_shutdown();
nfsd4_free_slabs();
nfsd4_exit_pnfs();
diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
index 76326299ba36..ce381eafd084 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -1327,7 +1327,7 @@ struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
fa |= FILE_ATTRIBUTE_READONLY;
/* Allocate PATH_MAX bytes. */
- new_de = __getname();
+ new_de = kmem_cache_zalloc(names_cachep, GFP_KERNEL);
if (!new_de) {
err = -ENOMEM;
goto out1;
@@ -1756,10 +1756,9 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry)
struct NTFS_DE *de;
/* Allocate PATH_MAX bytes. */
- de = __getname();
+ de = kmem_cache_zalloc(names_cachep, GFP_KERNEL);
if (!de)
return -ENOMEM;
- memset(de, 0, PATH_MAX);
/* Mark rw ntfs as dirty. It will be cleared at umount. */
ntfs_set_state(sbi, NTFS_DIRTY_DIRTY);
@@ -1795,7 +1794,7 @@ int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry)
return -EINVAL;
/* Allocate PATH_MAX bytes. */
- de = __getname();
+ de = kmem_cache_zalloc(names_cachep, GFP_KERNEL);
if (!de)
return -ENOMEM;
diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
index 0ca788009c93..450a9f8ca7c7 100644
--- a/fs/smb/server/mgmt/user_session.c
+++ b/fs/smb/server/mgmt/user_session.c
@@ -59,10 +59,12 @@ static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess)
struct ksmbd_session_rpc *entry;
long index;
+ down_write(&sess->rpc_lock);
xa_for_each(&sess->rpc_handle_list, index, entry) {
xa_erase(&sess->rpc_handle_list, index);
__session_rpc_close(sess, entry);
}
+ up_write(&sess->rpc_lock);
xa_destroy(&sess->rpc_handle_list);
}
@@ -92,7 +94,7 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
{
struct ksmbd_session_rpc *entry, *old;
struct ksmbd_rpc_command *resp;
- int method;
+ int method, id;
method = __rpc_method(rpc_name);
if (!method)
@@ -102,26 +104,29 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
if (!entry)
return -ENOMEM;
+ down_read(&sess->rpc_lock);
entry->method = method;
- entry->id = ksmbd_ipc_id_alloc();
- if (entry->id < 0)
+ entry->id = id = ksmbd_ipc_id_alloc();
+ if (id < 0)
goto free_entry;
- old = xa_store(&sess->rpc_handle_list, entry->id, entry, GFP_KERNEL);
+ old = xa_store(&sess->rpc_handle_list, id, entry, GFP_KERNEL);
if (xa_is_err(old))
goto free_id;
- resp = ksmbd_rpc_open(sess, entry->id);
+ resp = ksmbd_rpc_open(sess, id);
if (!resp)
goto erase_xa;
+ up_read(&sess->rpc_lock);
kvfree(resp);
- return entry->id;
+ return id;
erase_xa:
xa_erase(&sess->rpc_handle_list, entry->id);
free_id:
ksmbd_rpc_id_free(entry->id);
free_entry:
kfree(entry);
+ up_read(&sess->rpc_lock);
return -EINVAL;
}
@@ -129,9 +134,11 @@ void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id)
{
struct ksmbd_session_rpc *entry;
+ down_write(&sess->rpc_lock);
entry = xa_erase(&sess->rpc_handle_list, id);
if (entry)
__session_rpc_close(sess, entry);
+ up_write(&sess->rpc_lock);
}
int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
@@ -438,6 +445,7 @@ static struct ksmbd_session *__session_create(int protocol)
sess->sequence_number = 1;
rwlock_init(&sess->tree_conns_lock);
atomic_set(&sess->refcnt, 2);
+ init_rwsem(&sess->rpc_lock);
ret = __init_smb2_session(sess);
if (ret)
diff --git a/fs/smb/server/mgmt/user_session.h b/fs/smb/server/mgmt/user_session.h
index f21348381d59..c5749d6ec715 100644
--- a/fs/smb/server/mgmt/user_session.h
+++ b/fs/smb/server/mgmt/user_session.h
@@ -63,6 +63,7 @@ struct ksmbd_session {
rwlock_t tree_conns_lock;
atomic_t refcnt;
+ struct rw_semaphore rpc_lock;
};
static inline int test_session_flag(struct ksmbd_session *sess, int bit)
diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
index fdac4a1714ec..3d1b31f90ed6 100644
--- a/include/asm-generic/hyperv-tlfs.h
+++ b/include/asm-generic/hyperv-tlfs.h
@@ -625,6 +625,37 @@ struct hv_retarget_device_interrupt {
struct hv_device_interrupt_target int_target;
} __packed __aligned(8);
+/*
+ * These Hyper-V registers provide information equivalent to the CPUID
+ * instruction on x86/x64.
+ */
+#define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */
+#define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */
+#define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */
+
+/*
+ * Synthetic register definitions equivalent to MSRs on x86/x64
+ */
+#define HV_REGISTER_CRASH_P0 0x00000210
+#define HV_REGISTER_CRASH_P1 0x00000211
+#define HV_REGISTER_CRASH_P2 0x00000212
+#define HV_REGISTER_CRASH_P3 0x00000213
+#define HV_REGISTER_CRASH_P4 0x00000214
+#define HV_REGISTER_CRASH_CTL 0x00000215
+
+#define HV_REGISTER_GUEST_OSID 0x00090002
+#define HV_REGISTER_VP_INDEX 0x00090003
+#define HV_REGISTER_TIME_REF_COUNT 0x00090004
+#define HV_REGISTER_REFERENCE_TSC 0x00090017
+
+#define HV_REGISTER_SINT0 0x000A0000
+#define HV_REGISTER_SCONTROL 0x000A0010
+#define HV_REGISTER_SIEFP 0x000A0012
+#define HV_REGISTER_SIMP 0x000A0013
+#define HV_REGISTER_EOM 0x000A0014
+
+#define HV_REGISTER_STIMER0_CONFIG 0x000B0000
+#define HV_REGISTER_STIMER0_COUNT 0x000B0001
/* HvGetVpRegisters hypercall input with variable size reg name list*/
struct hv_get_vp_registers_input {
@@ -640,7 +671,6 @@ struct hv_get_vp_registers_input {
} element[];
} __packed;
-
/* HvGetVpRegisters returns an array of these output elements */
struct hv_get_vp_registers_output {
union {
diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
index 430f0ae0dde2..04424a446bb7 100644
--- a/include/asm-generic/mshyperv.h
+++ b/include/asm-generic/mshyperv.h
@@ -157,7 +157,7 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)
* possibly deliver another msg from the
* hypervisor
*/
- hv_set_register(HV_REGISTER_EOM, 0);
+ hv_set_msr(HV_MSR_EOM, 0);
}
}
diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h
index 7c201a66bc69..0abd1c4c5314 100644
--- a/include/dt-bindings/power/qcom,rpmhpd.h
+++ b/include/dt-bindings/power/qcom,rpmhpd.h
@@ -26,5 +26,240 @@
#define RPMHPD_QPHY 16
#define RPMHPD_DDR 17
#define RPMHPD_XO 18
+#define RPMHPD_NSP2 19
+
+/* RPMh Power Domain performance levels */
+#define RPMH_REGULATOR_LEVEL_RETENTION 16
+#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60
+#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80
+#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96
+#define RPMH_REGULATOR_LEVEL_SVS 128
+#define RPMH_REGULATOR_LEVEL_SVS_L0 144
+#define RPMH_REGULATOR_LEVEL_SVS_L1 192
+#define RPMH_REGULATOR_LEVEL_SVS_L2 224
+#define RPMH_REGULATOR_LEVEL_NOM 256
+#define RPMH_REGULATOR_LEVEL_NOM_L0 288
+#define RPMH_REGULATOR_LEVEL_NOM_L1 320
+#define RPMH_REGULATOR_LEVEL_NOM_L2 336
+#define RPMH_REGULATOR_LEVEL_TURBO 384
+#define RPMH_REGULATOR_LEVEL_TURBO_L0 400
+#define RPMH_REGULATOR_LEVEL_TURBO_L1 416
+#define RPMH_REGULATOR_LEVEL_TURBO_L2 432
+#define RPMH_REGULATOR_LEVEL_TURBO_L3 448
+#define RPMH_REGULATOR_LEVEL_TURBO_L4 452
+#define RPMH_REGULATOR_LEVEL_TURBO_L5 456
+#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464
+#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480
+
+/*
+ * Platform-specific power domain bindings. Don't add new entries here, use
+ * RPMHPD_* above.
+ */
+
+/* SA8775P Power Domain Indexes */
+#define SA8775P_CX 0
+#define SA8775P_CX_AO 1
+#define SA8775P_DDR 2
+#define SA8775P_EBI 3
+#define SA8775P_GFX 4
+#define SA8775P_LCX 5
+#define SA8775P_LMX 6
+#define SA8775P_MMCX 7
+#define SA8775P_MMCX_AO 8
+#define SA8775P_MSS 9
+#define SA8775P_MX 10
+#define SA8775P_MX_AO 11
+#define SA8775P_MXC 12
+#define SA8775P_MXC_AO 13
+#define SA8775P_NSP0 14
+#define SA8775P_NSP1 15
+#define SA8775P_XO 16
+
+/* SDM670 Power Domain Indexes */
+#define SDM670_MX 0
+#define SDM670_MX_AO 1
+#define SDM670_CX 2
+#define SDM670_CX_AO 3
+#define SDM670_LMX 4
+#define SDM670_LCX 5
+#define SDM670_GFX 6
+#define SDM670_MSS 7
+
+/* SDM845 Power Domain Indexes */
+#define SDM845_EBI 0
+#define SDM845_MX 1
+#define SDM845_MX_AO 2
+#define SDM845_CX 3
+#define SDM845_CX_AO 4
+#define SDM845_LMX 5
+#define SDM845_LCX 6
+#define SDM845_GFX 7
+#define SDM845_MSS 8
+
+/* SDX55 Power Domain Indexes */
+#define SDX55_MSS 0
+#define SDX55_MX 1
+#define SDX55_CX 2
+
+/* SDX65 Power Domain Indexes */
+#define SDX65_MSS 0
+#define SDX65_MX 1
+#define SDX65_MX_AO 2
+#define SDX65_CX 3
+#define SDX65_CX_AO 4
+#define SDX65_MXC 5
+
+/* SM6350 Power Domain Indexes */
+#define SM6350_CX 0
+#define SM6350_GFX 1
+#define SM6350_LCX 2
+#define SM6350_LMX 3
+#define SM6350_MSS 4
+#define SM6350_MX 5
+
+/* SM8150 Power Domain Indexes */
+#define SM8150_MSS 0
+#define SM8150_EBI 1
+#define SM8150_LMX 2
+#define SM8150_LCX 3
+#define SM8150_GFX 4
+#define SM8150_MX 5
+#define SM8150_MX_AO 6
+#define SM8150_CX 7
+#define SM8150_CX_AO 8
+#define SM8150_MMCX 9
+#define SM8150_MMCX_AO 10
+
+/* SA8155P is a special case, kept for backwards compatibility */
+#define SA8155P_CX SM8150_CX
+#define SA8155P_CX_AO SM8150_CX_AO
+#define SA8155P_EBI SM8150_EBI
+#define SA8155P_GFX SM8150_GFX
+#define SA8155P_MSS SM8150_MSS
+#define SA8155P_MX SM8150_MX
+#define SA8155P_MX_AO SM8150_MX_AO
+
+/* SM8250 Power Domain Indexes */
+#define SM8250_CX 0
+#define SM8250_CX_AO 1
+#define SM8250_EBI 2
+#define SM8250_GFX 3
+#define SM8250_LCX 4
+#define SM8250_LMX 5
+#define SM8250_MMCX 6
+#define SM8250_MMCX_AO 7
+#define SM8250_MX 8
+#define SM8250_MX_AO 9
+
+/* SM8350 Power Domain Indexes */
+#define SM8350_CX 0
+#define SM8350_CX_AO 1
+#define SM8350_EBI 2
+#define SM8350_GFX 3
+#define SM8350_LCX 4
+#define SM8350_LMX 5
+#define SM8350_MMCX 6
+#define SM8350_MMCX_AO 7
+#define SM8350_MX 8
+#define SM8350_MX_AO 9
+#define SM8350_MXC 10
+#define SM8350_MXC_AO 11
+#define SM8350_MSS 12
+
+/* SM8450 Power Domain Indexes */
+#define SM8450_CX 0
+#define SM8450_CX_AO 1
+#define SM8450_EBI 2
+#define SM8450_GFX 3
+#define SM8450_LCX 4
+#define SM8450_LMX 5
+#define SM8450_MMCX 6
+#define SM8450_MMCX_AO 7
+#define SM8450_MX 8
+#define SM8450_MX_AO 9
+#define SM8450_MXC 10
+#define SM8450_MXC_AO 11
+#define SM8450_MSS 12
+
+/* SM8550 Power Domain Indexes */
+#define SM8550_CX 0
+#define SM8550_CX_AO 1
+#define SM8550_EBI 2
+#define SM8550_GFX 3
+#define SM8550_LCX 4
+#define SM8550_LMX 5
+#define SM8550_MMCX 6
+#define SM8550_MMCX_AO 7
+#define SM8550_MX 8
+#define SM8550_MX_AO 9
+#define SM8550_MXC 10
+#define SM8550_MXC_AO 11
+#define SM8550_MSS 12
+#define SM8550_NSP 13
+
+/* QDU1000/QRU1000 Power Domain Indexes */
+#define QDU1000_EBI 0
+#define QDU1000_MSS 1
+#define QDU1000_CX 2
+#define QDU1000_MX 3
+
+/* SC7180 Power Domain Indexes */
+#define SC7180_CX 0
+#define SC7180_CX_AO 1
+#define SC7180_GFX 2
+#define SC7180_MX 3
+#define SC7180_MX_AO 4
+#define SC7180_LMX 5
+#define SC7180_LCX 6
+#define SC7180_MSS 7
+
+/* SC7280 Power Domain Indexes */
+#define SC7280_CX 0
+#define SC7280_CX_AO 1
+#define SC7280_EBI 2
+#define SC7280_GFX 3
+#define SC7280_MX 4
+#define SC7280_MX_AO 5
+#define SC7280_LMX 6
+#define SC7280_LCX 7
+#define SC7280_MSS 8
+
+/* SC8180X Power Domain Indexes */
+#define SC8180X_CX 0
+#define SC8180X_CX_AO 1
+#define SC8180X_EBI 2
+#define SC8180X_GFX 3
+#define SC8180X_LCX 4
+#define SC8180X_LMX 5
+#define SC8180X_MMCX 6
+#define SC8180X_MMCX_AO 7
+#define SC8180X_MSS 8
+#define SC8180X_MX 9
+#define SC8180X_MX_AO 10
+
+/* SC8280XP Power Domain Indexes */
+#define SC8280XP_CX 0
+#define SC8280XP_CX_AO 1
+#define SC8280XP_DDR 2
+#define SC8280XP_EBI 3
+#define SC8280XP_GFX 4
+#define SC8280XP_LCX 5
+#define SC8280XP_LMX 6
+#define SC8280XP_MMCX 7
+#define SC8280XP_MMCX_AO 8
+#define SC8280XP_MSS 9
+#define SC8280XP_MX 10
+#define SC8280XP_MXC 12
+#define SC8280XP_MX_AO 11
+#define SC8280XP_NSP 13
+#define SC8280XP_QPHY 14
+#define SC8280XP_XO 15
+#define SC8280XP_MXC_AO 16
#endif
diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
index 83be996cb5eb..f160f373be2a 100644
--- a/include/dt-bindings/power/qcom-rpmpd.h
+++ b/include/dt-bindings/power/qcom-rpmpd.h
@@ -4,66 +4,7 @@
#ifndef _DT_BINDINGS_POWER_QCOM_RPMPD_H
#define _DT_BINDINGS_POWER_QCOM_RPMPD_H
-/* SA8775P Power Domain Indexes */
-#define SA8775P_CX 0
-#define SA8775P_CX_AO 1
-#define SA8775P_DDR 2
-#define SA8775P_EBI 3
-#define SA8775P_GFX 4
-#define SA8775P_LCX 5
-#define SA8775P_LMX 6
-#define SA8775P_MMCX 7
-#define SA8775P_MMCX_AO 8
-#define SA8775P_MSS 9
-#define SA8775P_MX 10
-#define SA8775P_MX_AO 11
-#define SA8775P_MXC 12
-#define SA8775P_MXC_AO 13
-#define SA8775P_NSP0 14
-#define SA8775P_NSP1 15
-#define SA8775P_XO 16
-
-/* SDM670 Power Domain Indexes */
-#define SDM670_MX 0
-#define SDM670_MX_AO 1
-#define SDM670_CX 2
-#define SDM670_CX_AO 3
-#define SDM670_LMX 4
-#define SDM670_LCX 5
-#define SDM670_GFX 6
-#define SDM670_MSS 7
-
-/* SDM845 Power Domain Indexes */
-#define SDM845_EBI 0
-#define SDM845_MX 1
-#define SDM845_MX_AO 2
-#define SDM845_CX 3
-#define SDM845_CX_AO 4
-#define SDM845_LMX 5
-#define SDM845_LCX 6
-#define SDM845_GFX 7
-#define SDM845_MSS 8
-
-/* SDX55 Power Domain Indexes */
-#define SDX55_MSS 0
-#define SDX55_MX 1
-#define SDX55_CX 2
-
-/* SDX65 Power Domain Indexes */
-#define SDX65_MSS 0
-#define SDX65_MX 1
-#define SDX65_MX_AO 2
-#define SDX65_CX 3
-#define SDX65_CX_AO 4
-#define SDX65_MXC 5
-
-/* SM6350 Power Domain Indexes */
-#define SM6350_CX 0
-#define SM6350_GFX 1
-#define SM6350_LCX 2
-#define SM6350_LMX 3
-#define SM6350_MSS 4
-#define SM6350_MX 5
+#include <dt-bindings/power/qcom,rpmhpd.h>
/* SM6350 Power Domain Indexes */
#define SM6375_VDDCX 0
@@ -77,170 +18,6 @@
#define SM6375_VDD_LPI_CX 8
#define SM6375_VDD_LPI_MX 9
-/* SM8150 Power Domain Indexes */
-#define SM8150_MSS 0
-#define SM8150_EBI 1
-#define SM8150_LMX 2
-#define SM8150_LCX 3
-#define SM8150_GFX 4
-#define SM8150_MX 5
-#define SM8150_MX_AO 6
-#define SM8150_CX 7
-#define SM8150_CX_AO 8
-#define SM8150_MMCX 9
-#define SM8150_MMCX_AO 10
-
-/* SA8155P is a special case, kept for backwards compatibility */
-#define SA8155P_CX SM8150_CX
-#define SA8155P_CX_AO SM8150_CX_AO
-#define SA8155P_EBI SM8150_EBI
-#define SA8155P_GFX SM8150_GFX
-#define SA8155P_MSS SM8150_MSS
-#define SA8155P_MX SM8150_MX
-#define SA8155P_MX_AO SM8150_MX_AO
-
-/* SM8250 Power Domain Indexes */
-#define SM8250_CX 0
-#define SM8250_CX_AO 1
-#define SM8250_EBI 2
-#define SM8250_GFX 3
-#define SM8250_LCX 4
-#define SM8250_LMX 5
-#define SM8250_MMCX 6
-#define SM8250_MMCX_AO 7
-#define SM8250_MX 8
-#define SM8250_MX_AO 9
-
-/* SM8350 Power Domain Indexes */
-#define SM8350_CX 0
-#define SM8350_CX_AO 1
-#define SM8350_EBI 2
-#define SM8350_GFX 3
-#define SM8350_LCX 4
-#define SM8350_LMX 5
-#define SM8350_MMCX 6
-#define SM8350_MMCX_AO 7
-#define SM8350_MX 8
-#define SM8350_MX_AO 9
-#define SM8350_MXC 10
-#define SM8350_MXC_AO 11
-#define SM8350_MSS 12
-
-/* SM8450 Power Domain Indexes */
-#define SM8450_CX 0
-#define SM8450_CX_AO 1
-#define SM8450_EBI 2
-#define SM8450_GFX 3
-#define SM8450_LCX 4
-#define SM8450_LMX 5
-#define SM8450_MMCX 6
-#define SM8450_MMCX_AO 7
-#define SM8450_MX 8
-#define SM8450_MX_AO 9
-#define SM8450_MXC 10
-#define SM8450_MXC_AO 11
-#define SM8450_MSS 12
-
-/* SM8550 Power Domain Indexes */
-#define SM8550_CX 0
-#define SM8550_CX_AO 1
-#define SM8550_EBI 2
-#define SM8550_GFX 3
-#define SM8550_LCX 4
-#define SM8550_LMX 5
-#define SM8550_MMCX 6
-#define SM8550_MMCX_AO 7
-#define SM8550_MX 8
-#define SM8550_MX_AO 9
-#define SM8550_MXC 10
-#define SM8550_MXC_AO 11
-#define SM8550_MSS 12
-#define SM8550_NSP 13
-
-/* QDU1000/QRU1000 Power Domain Indexes */
-#define QDU1000_EBI 0
-#define QDU1000_MSS 1
-#define QDU1000_CX 2
-#define QDU1000_MX 3
-
-/* SC7180 Power Domain Indexes */
-#define SC7180_CX 0
-#define SC7180_CX_AO 1
-#define SC7180_GFX 2
-#define SC7180_MX 3
-#define SC7180_MX_AO 4
-#define SC7180_LMX 5
-#define SC7180_LCX 6
-#define SC7180_MSS 7
-
-/* SC7280 Power Domain Indexes */
-#define SC7280_CX 0
-#define SC7280_CX_AO 1
-#define SC7280_EBI 2
-#define SC7280_GFX 3
-#define SC7280_MX 4
-#define SC7280_MX_AO 5
-#define SC7280_LMX 6
-#define SC7280_LCX 7
-#define SC7280_MSS 8
-
-/* SC8180X Power Domain Indexes */
-#define SC8180X_CX 0
-#define SC8180X_CX_AO 1
-#define SC8180X_EBI 2
-#define SC8180X_GFX 3
-#define SC8180X_LCX 4
-#define SC8180X_LMX 5
-#define SC8180X_MMCX 6
-#define SC8180X_MMCX_AO 7
-#define SC8180X_MSS 8
-#define SC8180X_MX 9
-#define SC8180X_MX_AO 10
-
-/* SC8280XP Power Domain Indexes */
-#define SC8280XP_CX 0
-#define SC8280XP_CX_AO 1
-#define SC8280XP_DDR 2
-#define SC8280XP_EBI 3
-#define SC8280XP_GFX 4
-#define SC8280XP_LCX 5
-#define SC8280XP_LMX 6
-#define SC8280XP_MMCX 7
-#define SC8280XP_MMCX_AO 8
-#define SC8280XP_MSS 9
-#define SC8280XP_MX 10
-#define SC8280XP_MXC 12
-#define SC8280XP_MX_AO 11
-#define SC8280XP_NSP 13
-#define SC8280XP_QPHY 14
-#define SC8280XP_XO 15
-
-/* SDM845 Power Domain performance levels */
-#define RPMH_REGULATOR_LEVEL_RETENTION 16
-#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
-#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52
-#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56
-#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60
-#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
-#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72
-#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80
-#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96
-#define RPMH_REGULATOR_LEVEL_SVS 128
-#define RPMH_REGULATOR_LEVEL_SVS_L0 144
-#define RPMH_REGULATOR_LEVEL_SVS_L1 192
-#define RPMH_REGULATOR_LEVEL_SVS_L2 224
-#define RPMH_REGULATOR_LEVEL_NOM 256
-#define RPMH_REGULATOR_LEVEL_NOM_L0 288
-#define RPMH_REGULATOR_LEVEL_NOM_L1 320
-#define RPMH_REGULATOR_LEVEL_NOM_L2 336
-#define RPMH_REGULATOR_LEVEL_TURBO 384
-#define RPMH_REGULATOR_LEVEL_TURBO_L0 400
-#define RPMH_REGULATOR_LEVEL_TURBO_L1 416
-#define RPMH_REGULATOR_LEVEL_TURBO_L2 432
-#define RPMH_REGULATOR_LEVEL_TURBO_L3 448
-#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464
-#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480
-
/* MDM9607 Power Domains */
#define MDM9607_VDDCX 0
#define MDM9607_VDDCX_AO 1
@@ -278,6 +55,27 @@
#define MSM8909_VDDMX MSM8916_VDDMX
#define MSM8909_VDDMX_AO MSM8916_VDDMX_AO
+/* MSM8917 Power Domain Indexes */
+#define MSM8917_VDDCX 0
+#define MSM8917_VDDCX_AO 1
+#define MSM8917_VDDCX_VFL 2
+#define MSM8917_VDDMX 3
+#define MSM8917_VDDMX_AO 4
+
+/* MSM8937 Power Domain Indexes */
+#define MSM8937_VDDCX MSM8917_VDDCX
+#define MSM8937_VDDCX_AO MSM8917_VDDCX_AO
+#define MSM8937_VDDCX_VFL MSM8917_VDDCX_VFL
+#define MSM8937_VDDMX MSM8917_VDDMX
+#define MSM8937_VDDMX_AO MSM8917_VDDMX_AO
+
+/* QM215 Power Domain Indexes */
+#define QM215_VDDCX MSM8917_VDDCX
+#define QM215_VDDCX_AO MSM8917_VDDCX_AO
+#define QM215_VDDCX_VFL MSM8917_VDDCX_VFL
+#define QM215_VDDMX MSM8917_VDDMX
+#define QM215_VDDMX_AO MSM8917_VDDMX_AO
+
/* MSM8953 Power Domain Indexes */
#define MSM8953_VDDMD 0
#define MSM8953_VDDMD_AO 1
diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h
index 5aec3945555b..0e184cd5d6ac 100644
--- a/include/linux/iio/iio-opaque.h
+++ b/include/linux/iio/iio-opaque.h
@@ -14,6 +14,7 @@
* @mlock: lock used to prevent simultaneous device state changes
* @mlock_key: lockdep class for iio_dev lock
* @info_exist_lock: lock to prevent use during removal
+ * @info_exist_key: lockdep class for info_exist lock
* @trig_readonly: mark the current trigger immutable
* @event_interface: event chrdevs associated with interrupt lines
* @attached_buffers: array of buffers statically attached by the driver
@@ -47,6 +48,7 @@ struct iio_dev_opaque {
struct mutex mlock;
struct lock_class_key mlock_key;
struct mutex info_exist_lock;
+ struct lock_class_key info_exist_key;
bool trig_readonly;
struct iio_event_interface *event_interface;
struct iio_buffer **attached_buffers;
diff --git a/include/linux/kfence.h b/include/linux/kfence.h
index 401af4757514..90edba2e59f9 100644
--- a/include/linux/kfence.h
+++ b/include/linux/kfence.h
@@ -211,6 +211,7 @@ struct kmem_obj_info;
* __kfence_obj_info() - fill kmem_obj_info struct
* @kpp: kmem_obj_info to be filled
* @object: the object
+ * @slab: the slab
*
* Return:
* * false - not a KFENCE object
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index b61038de139e..e88b02fff7f2 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -28,6 +28,9 @@
#define NVME_NSID_ALL 0xffffffff
+/* Special NSSR value, 'NVMe' */
+#define NVME_SUBSYS_RESET 0x4E564D65
+
enum nvme_subsys_type {
/* Referral to another discovery type target subsystem */
NVME_NQN_DISC = 1,
diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
index 468328b1e1dd..a500d3160fe8 100644
--- a/include/linux/posix-clock.h
+++ b/include/linux/posix-clock.h
@@ -14,6 +14,7 @@
#include <linux/rwsem.h>
struct posix_clock;
+struct posix_clock_context;
/**
* struct posix_clock_operations - functional interface to the clock
@@ -50,18 +51,18 @@ struct posix_clock_operations {
/*
* Optional character device methods:
*/
- long (*ioctl) (struct posix_clock *pc,
- unsigned int cmd, unsigned long arg);
+ long (*ioctl)(struct posix_clock_context *pccontext, unsigned int cmd,
+ unsigned long arg);
- int (*open) (struct posix_clock *pc, fmode_t f_mode);
+ int (*open)(struct posix_clock_context *pccontext, fmode_t f_mode);
- __poll_t (*poll) (struct posix_clock *pc,
- struct file *file, poll_table *wait);
+ __poll_t (*poll)(struct posix_clock_context *pccontext, struct file *file,
+ poll_table *wait);
- int (*release) (struct posix_clock *pc);
+ int (*release)(struct posix_clock_context *pccontext);
- ssize_t (*read) (struct posix_clock *pc,
- uint flags, char __user *buf, size_t cnt);
+ ssize_t (*read)(struct posix_clock_context *pccontext, uint flags,
+ char __user *buf, size_t cnt);
};
/**
@@ -90,6 +91,28 @@ struct posix_clock {
bool zombie;
};
+/**
+ * struct posix_clock_context - represents clock file operations context
+ *
+ * @clk: Pointer to the clock
+ * @fp: Pointer to the file used to open the clock
+ * @private_clkdata: Pointer to user data
+ *
+ * Drivers should use struct posix_clock_context during specific character
+ * device file operation methods to access the posix clock. In particular,
+ * the file pointer can be used to verify correct access mode for ioctl()
+ * calls.
+ *
+ * Drivers can store a private data structure during the open operation
+ * if they have specific information that is required in other file
+ * operations.
+ */
+struct posix_clock_context {
+ struct posix_clock *clk;
+ struct file *fp;
+ void *private_clkdata;
+};
+
/**
* posix_clock_register() - register a new clock
* @clk: Pointer to the clock. Caller must provide 'ops' field
diff --git a/include/linux/textsearch.h b/include/linux/textsearch.h
index 6673e4d4ac2e..4933777404d6 100644
--- a/include/linux/textsearch.h
+++ b/include/linux/textsearch.h
@@ -35,6 +35,7 @@ struct ts_state
* @get_pattern: return head of pattern
* @get_pattern_len: return length of pattern
* @owner: module reference to algorithm
+ * @list: list to search
*/
struct ts_ops
{
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index 59409c1fc3de..2f7bd2fdc616 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -75,4 +75,7 @@
/* short SET_ADDRESS request timeout */
#define USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT BIT(16)
+/* skip BOS descriptor request */
+#define USB_QUIRK_NO_BOS BIT(17)
+
#endif /* __LINUX_USB_QUIRKS_H */
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
index 1ae08e81339f..15679be90c5c 100644
--- a/include/scsi/scsi_eh.h
+++ b/include/scsi/scsi_eh.h
@@ -41,6 +41,12 @@ struct scsi_eh_save {
unsigned char cmnd[32];
struct scsi_data_buffer sdb;
struct scatterlist sense_sgl;
+
+ /* struct request fields */
+#ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ struct bio_crypt_ctx *rq_crypt_ctx;
+ struct blk_crypto_keyslot *rq_crypt_keyslot;
+#endif
};
extern void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd,
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index ed4449cbdf80..911eeb19cc65 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -1427,7 +1427,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s
#define snd_pcm_lib_mmap_iomem NULL
#endif
-void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime);
+int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime);
/**
* snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer
diff --git a/include/uapi/linux/comedi.h b/include/uapi/linux/comedi.h
index 7314e5ee0a1e..798ec9a39e12 100644
--- a/include/uapi/linux/comedi.h
+++ b/include/uapi/linux/comedi.h
@@ -640,7 +640,7 @@ struct comedi_chaninfo {
/**
* struct comedi_rangeinfo - used to retrieve the range table for a channel
- * @range_type: Encodes subdevice index (bits 27:24), channel index
+ * @range_type: Encodes subdevice index (bits 31:24), channel index
* (bits 23:16) and range table length (bits 15:0).
* @range_ptr: Pointer to array of @struct comedi_krange to be filled
* in with the range table for the channel or subdevice.
diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
index 1c4ef4e4eb52..c848a5018d12 100644
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -554,9 +554,9 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
__releases(&acct->lock)
{
struct io_wq *wq = worker->wq;
- bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state);
do {
+ bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state);
struct io_wq_work *work;
/*
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index 07a5824ad98d..712c724a7444 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -3191,11 +3191,11 @@ static __cold void io_ring_exit_work(struct work_struct *work)
mutex_unlock(&ctx->uring_lock);
}
- if (ctx->flags & IORING_SETUP_DEFER_TASKRUN)
- io_move_task_work_from_local(ctx);
-
- while (io_uring_try_cancel_requests(ctx, NULL, true))
+ do {
+ if (ctx->flags & IORING_SETUP_DEFER_TASKRUN)
+ io_move_task_work_from_local(ctx);
cond_resched();
+ } while (io_uring_try_cancel_requests(ctx, NULL, true));
if (ctx->sq_data) {
struct io_sq_data *sqd = ctx->sq_data;
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index ccea52adcba6..0320f49bd1f4 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -941,7 +941,7 @@ static bool update_needs_ipi(struct hrtimer_cpu_base *cpu_base,
return true;
/* Extra check for softirq clock bases */
- if (base->clockid < HRTIMER_BASE_MONOTONIC_SOFT)
+ if (base->index < HRTIMER_BASE_MONOTONIC_SOFT)
continue;
if (cpu_base->softirq_activated)
continue;
diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
index 05e73d209aa8..827abede7274 100644
--- a/kernel/time/posix-clock.c
+++ b/kernel/time/posix-clock.c
@@ -19,7 +19,8 @@
*/
static struct posix_clock *get_posix_clock(struct file *fp)
{
- struct posix_clock *clk = fp->private_data;
+ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = pccontext->clk;
down_read(&clk->rwsem);
@@ -39,6 +40,7 @@ static void put_posix_clock(struct posix_clock *clk)
static ssize_t posix_clock_read(struct file *fp, char __user *buf,
size_t count, loff_t *ppos)
{
+ struct posix_clock_context *pccontext = fp->private_data;
struct posix_clock *clk = get_posix_clock(fp);
int err = -EINVAL;
@@ -46,7 +48,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
return -ENODEV;
if (clk->ops.read)
- err = clk->ops.read(clk, fp->f_flags, buf, count);
+ err = clk->ops.read(pccontext, fp->f_flags, buf, count);
put_posix_clock(clk);
@@ -55,6 +57,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
{
+ struct posix_clock_context *pccontext = fp->private_data;
struct posix_clock *clk = get_posix_clock(fp);
__poll_t result = 0;
@@ -62,7 +65,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
return EPOLLERR;
if (clk->ops.poll)
- result = clk->ops.poll(clk, fp, wait);
+ result = clk->ops.poll(pccontext, fp, wait);
put_posix_clock(clk);
@@ -72,6 +75,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
static long posix_clock_ioctl(struct file *fp,
unsigned int cmd, unsigned long arg)
{
+ struct posix_clock_context *pccontext = fp->private_data;
struct posix_clock *clk = get_posix_clock(fp);
int err = -ENOTTY;
@@ -79,7 +83,7 @@ static long posix_clock_ioctl(struct file *fp,
return -ENODEV;
if (clk->ops.ioctl)
- err = clk->ops.ioctl(clk, cmd, arg);
+ err = clk->ops.ioctl(pccontext, cmd, arg);
put_posix_clock(clk);
@@ -90,6 +94,7 @@ static long posix_clock_ioctl(struct file *fp,
static long posix_clock_compat_ioctl(struct file *fp,
unsigned int cmd, unsigned long arg)
{
+ struct posix_clock_context *pccontext = fp->private_data;
struct posix_clock *clk = get_posix_clock(fp);
int err = -ENOTTY;
@@ -97,7 +102,7 @@ static long posix_clock_compat_ioctl(struct file *fp,
return -ENODEV;
if (clk->ops.ioctl)
- err = clk->ops.ioctl(clk, cmd, arg);
+ err = clk->ops.ioctl(pccontext, cmd, arg);
put_posix_clock(clk);
@@ -110,6 +115,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
int err;
struct posix_clock *clk =
container_of(inode->i_cdev, struct posix_clock, cdev);
+ struct posix_clock_context *pccontext;
down_read(&clk->rwsem);
@@ -117,15 +123,24 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
err = -ENODEV;
goto out;
}
- if (clk->ops.open)
- err = clk->ops.open(clk, fp->f_mode);
- else
- err = 0;
-
- if (!err) {
- get_device(clk->dev);
- fp->private_data = clk;
+ pccontext = kzalloc(sizeof(*pccontext), GFP_KERNEL);
+ if (!pccontext) {
+ err = -ENOMEM;
+ goto out;
}
+ pccontext->clk = clk;
+ pccontext->fp = fp;
+ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+ if (err) {
+ kfree(pccontext);
+ goto out;
+ }
+ }
+
+ fp->private_data = pccontext;
+ get_device(clk->dev);
+ err = 0;
out:
up_read(&clk->rwsem);
return err;
@@ -133,14 +148,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
static int posix_clock_release(struct inode *inode, struct file *fp)
{
- struct posix_clock *clk = fp->private_data;
+ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk;
int err = 0;
+ if (!pccontext)
+ return -ENODEV;
+ clk = pccontext->clk;
+
if (clk->ops.release)
- err = clk->ops.release(clk);
+ err = clk->ops.release(pccontext);
put_device(clk->dev);
+ kfree(pccontext);
fp->private_data = NULL;
return err;
@@ -232,7 +253,7 @@ static int pc_clock_adjtime(clockid_t id, struct __kernel_timex *tx)
if (err)
return err;
- if ((cd.fp->f_mode & FMODE_WRITE) == 0) {
+ if (tx->modes && (cd.fp->f_mode & FMODE_WRITE) == 0) {
err = -EACCES;
goto out;
}
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index e6d2f2a94235..99d1e8b57f85 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -2047,6 +2047,15 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
hist_field->fn_num = HIST_FIELD_FN_RELDYNSTRING;
else
hist_field->fn_num = HIST_FIELD_FN_PSTRING;
+ } else if (field->filter_type == FILTER_STACKTRACE) {
+ flags |= HIST_FIELD_FL_STACKTRACE;
+
+ hist_field->size = MAX_FILTER_STR_VAL;
+ hist_field->type = kstrdup_const(field->type, GFP_KERNEL);
+ if (!hist_field->type)
+ goto free;
+
+ hist_field->fn_num = HIST_FIELD_FN_STACK;
} else {
hist_field->size = field->size;
hist_field->is_signed = field->is_signed;
diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index 181af676f93d..02e2440da829 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -137,7 +137,9 @@ static int synth_event_define_fields(struct trace_event_call *call)
struct synth_event *event = call->data;
unsigned int i, size, n_u64;
char *name, *type;
+ int filter_type;
bool is_signed;
+ bool is_stack;
int ret = 0;
for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
@@ -145,8 +147,12 @@ static int synth_event_define_fields(struct trace_event_call *call)
is_signed = event->fields[i]->is_signed;
type = event->fields[i]->type;
name = event->fields[i]->name;
+ is_stack = event->fields[i]->is_stack;
+
+ filter_type = is_stack ? FILTER_STACKTRACE : FILTER_OTHER;
+
ret = trace_define_field(call, type, name, offset, size,
- is_signed, FILTER_OTHER);
+ is_signed, filter_type);
if (ret)
break;
diff --git a/mm/Kconfig b/mm/Kconfig
index 046c32686fc4..8585d06af429 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1067,10 +1067,14 @@ config ZONE_DEVICE
Device memory hotplug support allows for establishing pmem,
or other device driver discovered memory regions, in the
memmap. This allows pfn_to_page() lookups of otherwise
- "device-physical" addresses which is needed for using a DAX
- mapping in an O_DIRECT operation, among other things.
-
- If FS_DAX is enabled, then say Y.
+ "device-physical" addresses which is needed for DAX, PCI_P2PDMA, and
+ DEVICE_PRIVATE features among others.
+
+ Enabling this option will reduce the entropy of x86 KASLR memory
+ regions. For example - on a 46 bit system, the entropy goes down
+ from 16 bits to 15 bits. The actual reduction in entropy depends
+ on the physical address bits, on processor features, kernel config
+ (5 level page table) and physical memory present on the system.
#
# Helpers to mirror range of the CPU page tables of a process into device page
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index 19d661889cf7..c774f1e5c0a5 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -1282,12 +1282,13 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
err = damon_sysfs_scheme_set_access_pattern(scheme);
if (err)
return err;
+
err = damon_sysfs_scheme_set_quotas(scheme);
if (err)
- goto put_access_pattern_out;
+ goto rmdir_put_access_pattern_out;
err = damon_sysfs_scheme_set_watermarks(scheme);
if (err)
- goto put_quotas_access_pattern_out;
+ goto rmdir_put_quotas_access_pattern_out;
err = damon_sysfs_scheme_set_filters(scheme);
if (err)
goto put_watermarks_quotas_access_pattern_out;
@@ -1308,10 +1309,12 @@ static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme)
put_watermarks_quotas_access_pattern_out:
kobject_put(&scheme->watermarks->kobj);
scheme->watermarks = NULL;
-put_quotas_access_pattern_out:
+rmdir_put_quotas_access_pattern_out:
+ damon_sysfs_quotas_rm_dirs(scheme->quotas);
kobject_put(&scheme->quotas->kobj);
scheme->quotas = NULL;
-put_access_pattern_out:
+rmdir_put_access_pattern_out:
+ damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern);
kobject_put(&scheme->access_pattern->kobj);
scheme->access_pattern = NULL;
return err;
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 91893543d47c..acb6e57cd9cb 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -716,7 +716,7 @@ static int damon_sysfs_context_add_dirs(struct damon_sysfs_context *context)
err = damon_sysfs_context_set_targets(context);
if (err)
- goto put_attrs_out;
+ goto rmdir_put_attrs_out;
err = damon_sysfs_context_set_schemes(context);
if (err)
@@ -726,7 +726,8 @@ static int damon_sysfs_context_add_dirs(struct damon_sysfs_context *context)
put_targets_attrs_out:
kobject_put(&context->targets->kobj);
context->targets = NULL;
-put_attrs_out:
+rmdir_put_attrs_out:
+ damon_sysfs_attrs_rm_dirs(context->attrs);
kobject_put(&context->attrs->kobj);
context->attrs = NULL;
return err;
diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c
index 87318f9170f1..8b619191299d 100644
--- a/mm/kmsan/shadow.c
+++ b/mm/kmsan/shadow.c
@@ -210,7 +210,7 @@ void kmsan_free_page(struct page *page, unsigned int order)
return;
kmsan_enter_runtime();
kmsan_internal_poison_memory(page_address(page),
- page_size(page),
+ PAGE_SIZE << order,
GFP_KERNEL,
KMSAN_POISON_CHECK | KMSAN_POISON_FREE);
kmsan_leave_runtime();
diff --git a/mm/migrate.c b/mm/migrate.c
index 4ed470885217..0e291c022140 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1369,6 +1369,7 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio,
int page_was_mapped = 0;
struct anon_vma *anon_vma = NULL;
struct address_space *mapping = NULL;
+ enum ttu_flags ttu = 0;
if (folio_ref_count(src) == 1) {
/* page was freed from under us. So we are done. */
@@ -1410,8 +1411,6 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio,
goto put_anon;
if (folio_mapped(src)) {
- enum ttu_flags ttu = 0;
-
if (!folio_test_anon(src)) {
/*
* In shared mappings, try_to_unmap could potentially
@@ -1428,9 +1427,6 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio,
try_to_migrate(src, ttu);
page_was_mapped = 1;
-
- if (ttu & TTU_RMAP_LOCKED)
- i_mmap_unlock_write(mapping);
}
if (!folio_mapped(src))
@@ -1438,7 +1434,11 @@ static int unmap_and_move_huge_page(new_folio_t get_new_folio,
if (page_was_mapped)
remove_migration_ptes(src,
- rc == MIGRATEPAGE_SUCCESS ? dst : src, false);
+ rc == MIGRATEPAGE_SUCCESS ? dst : src,
+ ttu ? true : false);
+
+ if (ttu & TTU_RMAP_LOCKED)
+ i_mmap_unlock_write(mapping);
unlock_put_anon:
folio_unlock(dst);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 93cb65c6553e..6c042f7796e4 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -160,6 +160,33 @@ static DEFINE_MUTEX(pcp_batch_high_lock);
#define pcp_spin_unlock(ptr) \
pcpu_spin_unlock(lock, ptr)
+/*
+ * With the UP spinlock implementation, when we spin_lock(&pcp->lock) (for i.e.
+ * a potentially remote cpu drain) and get interrupted by an operation that
+ * attempts pcp_spin_trylock(), we can't rely on the trylock failure due to UP
+ * spinlock assumptions making the trylock a no-op. So we have to turn that
+ * spin_lock() to a spin_lock_irqsave(). This works because on UP there are no
+ * remote cpu's so we can only be locking the only existing local one.
+ */
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
+static inline void __flags_noop(unsigned long *flags) { }
+#define pcp_spin_lock_maybe_irqsave(ptr, flags) \
+({ \
+ __flags_noop(&(flags)); \
+ spin_lock(&(ptr)->lock); \
+})
+#define pcp_spin_unlock_maybe_irqrestore(ptr, flags) \
+({ \
+ spin_unlock(&(ptr)->lock); \
+ __flags_noop(&(flags)); \
+})
+#else
+#define pcp_spin_lock_maybe_irqsave(ptr, flags) \
+ spin_lock_irqsave(&(ptr)->lock, flags)
+#define pcp_spin_unlock_maybe_irqrestore(ptr, flags) \
+ spin_unlock_irqrestore(&(ptr)->lock, flags)
+#endif
+
#ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID
DEFINE_PER_CPU(int, numa_node);
EXPORT_PER_CPU_SYMBOL(numa_node);
@@ -2181,14 +2208,15 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
*/
void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp)
{
+ unsigned long UP_flags;
int to_drain, batch;
batch = READ_ONCE(pcp->batch);
to_drain = min(pcp->count, batch);
if (to_drain > 0) {
- spin_lock(&pcp->lock);
+ pcp_spin_lock_maybe_irqsave(pcp, UP_flags);
free_pcppages_bulk(zone, to_drain, pcp, 0);
- spin_unlock(&pcp->lock);
+ pcp_spin_unlock_maybe_irqrestore(pcp, UP_flags);
}
}
#endif
@@ -2199,10 +2227,11 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp)
static void drain_pages_zone(unsigned int cpu, struct zone *zone)
{
struct per_cpu_pages *pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu);
+ unsigned long UP_flags;
int count;
do {
- spin_lock(&pcp->lock);
+ pcp_spin_lock_maybe_irqsave(pcp, UP_flags);
count = pcp->count;
if (count) {
int to_drain = min(count,
@@ -2211,7 +2240,7 @@ static void drain_pages_zone(unsigned int cpu, struct zone *zone)
free_pcppages_bulk(zone, to_drain, pcp, 0);
count -= to_drain;
}
- spin_unlock(&pcp->lock);
+ pcp_spin_unlock_maybe_irqrestore(pcp, UP_flags);
} while (count);
}
@@ -5936,11 +5965,19 @@ static int percpu_pagelist_high_fraction_sysctl_handler(struct ctl_table *table,
int old_percpu_pagelist_high_fraction;
int ret;
+ /*
+ * Avoid using pcp_batch_high_lock for reads as the value is read
+ * atomically and a race with offlining is harmless.
+ */
+
+ if (!write)
+ return proc_dointvec_minmax(table, write, buffer, length, ppos);
+
mutex_lock(&pcp_batch_high_lock);
old_percpu_pagelist_high_fraction = percpu_pagelist_high_fraction;
ret = proc_dointvec_minmax(table, write, buffer, length, ppos);
- if (!write || ret < 0)
+ if (ret < 0)
goto out;
/* Sanity checking to avoid pcp imbalance */
diff --git a/mm/rmap.c b/mm/rmap.c
index 968b85a67b1a..b511dd811c30 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1579,14 +1579,8 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma,
flush_tlb_range(vma,
range.start, range.end);
/*
- * The ref count of the PMD page was
- * dropped which is part of the way map
- * counting is done for shared PMDs.
- * Return 'true' here. When there is
- * no other sharing, huge_pmd_unshare
- * returns false and we will unmap the
- * actual page and drop map count
- * to zero.
+ * The PMD table was unmapped,
+ * consequently unmapping the folio.
*/
page_vma_mapped_walk_done(&pvmw);
break;
@@ -1945,14 +1939,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
range.start, range.end);
/*
- * The ref count of the PMD page was
- * dropped which is part of the way map
- * counting is done for shared PMDs.
- * Return 'true' here. When there is
- * no other sharing, huge_pmd_unshare
- * returns false and we will unmap the
- * actual page and drop map count
- * to zero.
+ * The PMD table was unmapped,
+ * consequently unmapping the folio.
*/
page_vma_mapped_walk_done(&pvmw);
break;
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 0498601283f8..3a1c82b797a3 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -914,6 +914,11 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb)
if (__skb->gso_segs > GSO_MAX_SEGS)
return -EINVAL;
+
+ /* Currently GSO type is zero/unset. If this gets extended with
+ * a small list of accepted GSO types in future, the filter for
+ * an unset GSO type in bpf_clone_redirect() can be lifted.
+ */
skb_shinfo(skb)->gso_segs = __skb->gso_segs;
skb_shinfo(skb)->gso_size = __skb->gso_size;
skb_shinfo(skb)->hwtstamps.hwtstamp = __skb->hwtstamp;
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index a6d8cd9a5807..fa2970db2130 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -73,7 +73,7 @@ static inline int has_expired(const struct net_bridge *br,
{
return !test_bit(BR_FDB_STATIC, &fdb->flags) &&
!test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags) &&
- time_before_eq(fdb->updated + hold_time(br), jiffies);
+ time_before_eq(READ_ONCE(fdb->updated) + hold_time(br), jiffies);
}
static void fdb_rcu_free(struct rcu_head *head)
@@ -136,9 +136,9 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
if (nla_put_u32(skb, NDA_FLAGS_EXT, ext_flags))
goto nla_put_failure;
- ci.ndm_used = jiffies_to_clock_t(now - fdb->used);
+ ci.ndm_used = jiffies_to_clock_t(now - READ_ONCE(fdb->used));
ci.ndm_confirmed = 0;
- ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated);
+ ci.ndm_updated = jiffies_to_clock_t(now - READ_ONCE(fdb->updated));
ci.ndm_refcnt = 0;
if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
goto nla_put_failure;
@@ -534,7 +534,7 @@ void br_fdb_cleanup(struct work_struct *work)
*/
rcu_read_lock();
hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
- unsigned long this_timer = f->updated + delay;
+ unsigned long this_timer = READ_ONCE(f->updated) + delay;
if (test_bit(BR_FDB_STATIC, &f->flags) ||
test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags)) {
@@ -792,6 +792,7 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf,
{
struct net_bridge_fdb_entry *f;
struct __fdb_entry *fe = buf;
+ unsigned long delta;
int num = 0;
memset(buf, 0, maxnum*sizeof(struct __fdb_entry));
@@ -821,8 +822,11 @@ int br_fdb_fillbuf(struct net_bridge *br, void *buf,
fe->port_hi = f->dst->port_no >> 8;
fe->is_local = test_bit(BR_FDB_LOCAL, &f->flags);
- if (!test_bit(BR_FDB_STATIC, &f->flags))
- fe->ageing_timer_value = jiffies_delta_to_clock_t(jiffies - f->updated);
+ if (!test_bit(BR_FDB_STATIC, &f->flags)) {
+ delta = jiffies - READ_ONCE(f->updated);
+ fe->ageing_timer_value =
+ jiffies_delta_to_clock_t(delta);
+ }
++fe;
++num;
}
@@ -870,8 +874,8 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
unsigned long now = jiffies;
bool fdb_modified = false;
- if (now != fdb->updated) {
- fdb->updated = now;
+ if (now != READ_ONCE(fdb->updated)) {
+ WRITE_ONCE(fdb->updated, now);
fdb_modified = __fdb_mark_active(fdb);
}
@@ -1056,7 +1060,8 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
if (!(flags & NLM_F_CREATE))
return -ENOENT;
- fdb = fdb_create(br, source, addr, vid, 0);
+ fdb = fdb_create(br, source, addr, vid,
+ BIT(BR_FDB_ADDED_BY_USER));
if (!fdb)
return -ENOMEM;
@@ -1069,6 +1074,8 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
WRITE_ONCE(fdb->dst, source);
modified = true;
}
+
+ set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
}
if (fdb_to_nud(br, fdb) != state) {
@@ -1100,12 +1107,10 @@ static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
if (fdb_handle_notify(fdb, notify))
modified = true;
- set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
-
- fdb->used = jiffies;
+ WRITE_ONCE(fdb->used, jiffies);
if (modified) {
if (refresh)
- fdb->updated = jiffies;
+ WRITE_ONCE(fdb->updated, jiffies);
fdb_notify(br, fdb, RTM_NEWNEIGH, true);
}
@@ -1418,7 +1423,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
goto err_unlock;
}
- fdb->updated = jiffies;
+ WRITE_ONCE(fdb->updated, jiffies);
if (READ_ONCE(fdb->dst) != p) {
WRITE_ONCE(fdb->dst, p);
@@ -1427,7 +1432,7 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
if (test_and_set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) {
/* Refresh entry */
- fdb->used = jiffies;
+ WRITE_ONCE(fdb->used, jiffies);
} else {
modified = true;
}
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 951330c1a813..2d5b81ebbaa6 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -207,8 +207,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
if (test_bit(BR_FDB_LOCAL, &dst->flags))
return br_pass_frame_up(skb, false);
- if (now != dst->used)
- dst->used = now;
+ if (now != READ_ONCE(dst->used))
+ WRITE_ONCE(dst->used, now);
br_forward(dst->dst, skb, local_rcv, false);
} else {
if (!mcast_hit)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index f42805d9b38f..4a2d94e8717e 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -2013,10 +2013,19 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port,
void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
{
+ struct net_bridge *br = pmctx->port->br;
+ bool del = false;
+
#if IS_ENABLED(CONFIG_IPV6)
del_timer_sync(&pmctx->ip6_mc_router_timer);
#endif
del_timer_sync(&pmctx->ip4_mc_router_timer);
+
+ spin_lock_bh(&br->multicast_lock);
+ del |= br_ip6_multicast_rport_del(pmctx);
+ del |= br_ip4_multicast_rport_del(pmctx);
+ br_multicast_rport_del_notify(pmctx, del);
+ spin_unlock_bh(&br->multicast_lock);
}
int br_multicast_add_port(struct net_bridge_port *port)
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index 1186326b0f2e..6c37562a50f7 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -1699,8 +1699,16 @@ static int j1939_xtp_rx_rts_session_active(struct j1939_session *session,
j1939_session_timers_cancel(session);
j1939_session_cancel(session, J1939_XTP_ABORT_BUSY);
- if (session->transmission)
+ if (session->transmission) {
j1939_session_deactivate_activate_next(session);
+ } else if (session->state == J1939_SESSION_WAITING_ABORT) {
+ /* Force deactivation for the receiver.
+ * If we rely on the timer starting in j1939_session_cancel,
+ * a second RTS call here will cancel that timer and fail
+ * to restart it because the state is already WAITING_ABORT.
+ */
+ j1939_session_deactivate_activate_next(session);
+ }
return -EBUSY;
}
diff --git a/net/core/dev.c b/net/core/dev.c
index cf5b5a4cbfd7..8a7a5e16da00 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -481,15 +481,21 @@ static const unsigned short netdev_lock_type[] = {
ARPHRD_IEEE1394, ARPHRD_EUI64, ARPHRD_INFINIBAND, ARPHRD_SLIP,
ARPHRD_CSLIP, ARPHRD_SLIP6, ARPHRD_CSLIP6, ARPHRD_RSRVD,
ARPHRD_ADAPT, ARPHRD_ROSE, ARPHRD_X25, ARPHRD_HWX25,
+ ARPHRD_CAN, ARPHRD_MCTP,
ARPHRD_PPP, ARPHRD_CISCO, ARPHRD_LAPB, ARPHRD_DDCMP,
- ARPHRD_RAWHDLC, ARPHRD_TUNNEL, ARPHRD_TUNNEL6, ARPHRD_FRAD,
+ ARPHRD_RAWHDLC, ARPHRD_RAWIP,
+ ARPHRD_TUNNEL, ARPHRD_TUNNEL6, ARPHRD_FRAD,
ARPHRD_SKIP, ARPHRD_LOOPBACK, ARPHRD_LOCALTLK, ARPHRD_FDDI,
ARPHRD_BIF, ARPHRD_SIT, ARPHRD_IPDDP, ARPHRD_IPGRE,
ARPHRD_PIMREG, ARPHRD_HIPPI, ARPHRD_ASH, ARPHRD_ECONET,
ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL,
ARPHRD_FCFABRIC, ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM,
- ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, ARPHRD_PHONET_PIPE,
- ARPHRD_IEEE802154, ARPHRD_VOID, ARPHRD_NONE};
+ ARPHRD_IEEE80211_RADIOTAP,
+ ARPHRD_IEEE802154, ARPHRD_IEEE802154_MONITOR,
+ ARPHRD_PHONET, ARPHRD_PHONET_PIPE,
+ ARPHRD_CAIF, ARPHRD_IP6GRE, ARPHRD_NETLINK, ARPHRD_6LOWPAN,
+ ARPHRD_VSOCKMON,
+ ARPHRD_VOID, ARPHRD_NONE};
static const char *const netdev_lock_name[] = {
"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25",
@@ -498,15 +504,21 @@ static const char *const netdev_lock_name[] = {
"_xmit_IEEE1394", "_xmit_EUI64", "_xmit_INFINIBAND", "_xmit_SLIP",
"_xmit_CSLIP", "_xmit_SLIP6", "_xmit_CSLIP6", "_xmit_RSRVD",
"_xmit_ADAPT", "_xmit_ROSE", "_xmit_X25", "_xmit_HWX25",
+ "_xmit_CAN", "_xmit_MCTP",
"_xmit_PPP", "_xmit_CISCO", "_xmit_LAPB", "_xmit_DDCMP",
- "_xmit_RAWHDLC", "_xmit_TUNNEL", "_xmit_TUNNEL6", "_xmit_FRAD",
+ "_xmit_RAWHDLC", "_xmit_RAWIP",
+ "_xmit_TUNNEL", "_xmit_TUNNEL6", "_xmit_FRAD",
"_xmit_SKIP", "_xmit_LOOPBACK", "_xmit_LOCALTLK", "_xmit_FDDI",
"_xmit_BIF", "_xmit_SIT", "_xmit_IPDDP", "_xmit_IPGRE",
"_xmit_PIMREG", "_xmit_HIPPI", "_xmit_ASH", "_xmit_ECONET",
"_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL",
"_xmit_FCFABRIC", "_xmit_IEEE80211", "_xmit_IEEE80211_PRISM",
- "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", "_xmit_PHONET_PIPE",
- "_xmit_IEEE802154", "_xmit_VOID", "_xmit_NONE"};
+ "_xmit_IEEE80211_RADIOTAP",
+ "_xmit_IEEE802154", "_xmit_IEEE802154_MONITOR",
+ "_xmit_PHONET", "_xmit_PHONET_PIPE",
+ "_xmit_CAIF", "_xmit_IP6GRE", "_xmit_NETLINK", "_xmit_6LOWPAN",
+ "_xmit_VSOCKMON",
+ "_xmit_VOID", "_xmit_NONE"};
static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)];
static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)];
@@ -519,6 +531,7 @@ static inline unsigned short netdev_lock_pos(unsigned short dev_type)
if (netdev_lock_type[i] == dev_type)
return i;
/* the last key is used by default */
+ WARN_ONCE(1, "netdev_lock_pos() could not find dev_type=%u\n", dev_type);
return ARRAY_SIZE(netdev_lock_type) - 1;
}
diff --git a/net/core/filter.c b/net/core/filter.c
index da1a617b7db9..99e931bc9e9a 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2451,6 +2451,13 @@ BPF_CALL_3(bpf_clone_redirect, struct sk_buff *, skb, u32, ifindex, u64, flags)
if (unlikely(flags & (~(BPF_F_INGRESS) | BPF_F_REDIRECT_INTERNAL)))
return -EINVAL;
+ /* BPF test infra's convert___skb_to_skb() can create type-less
+ * GSO packets. gso_features_check() will detect this as a bad
+ * offload. However, lets not leak them out in the first place.
+ */
+ if (unlikely(skb_is_gso(skb) && !skb_shinfo(skb)->gso_type))
+ return -EBADMSG;
+
dev = dev_get_by_index_rcu(dev_net(skb->dev), ifindex);
if (unlikely(!dev))
return -EINVAL;
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index c9bf1a9a6c99..ea3082740936 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -158,7 +158,7 @@ unsigned int dsa_bridge_num_get(const struct net_device *bridge_dev, int max)
bridge_num = find_next_zero_bit(&dsa_fwd_offloading_bridges,
DSA_MAX_NUM_OFFLOADING_BRIDGES,
1);
- if (bridge_num >= max)
+ if (bridge_num > max)
return 0;
set_bit(bridge_num, &dsa_fwd_offloading_bridges);
diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
index 11e33a431267..028d2d3477d1 100644
--- a/net/ipv4/esp4_offload.c
+++ b/net/ipv4/esp4_offload.c
@@ -111,8 +111,8 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x,
struct sk_buff *skb,
netdev_features_t features)
{
- const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x,
- XFRM_MODE_SKB_CB(skb)->protocol);
+ struct xfrm_offload *xo = xfrm_offload(skb);
+ const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, xo->proto);
__be16 type = inner_mode->family == AF_INET6 ? htons(ETH_P_IPV6)
: htons(ETH_P_IP);
diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c
index 4e0a7d038e21..6df7a0c614d5 100644
--- a/net/ipv4/fou_core.c
+++ b/net/ipv4/fou_core.c
@@ -215,6 +215,9 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb)
return gue_control_message(skb, guehdr);
proto_ctype = guehdr->proto_ctype;
+ if (unlikely(!proto_ctype))
+ goto drop;
+
__skb_pull(skb, sizeof(struct udphdr) + hdrlen);
skb_reset_transport_header(skb);
diff --git a/net/ipv4/fou_nl.c b/net/ipv4/fou_nl.c
index 98b90107b5ab..bbd955f4c9d1 100644
--- a/net/ipv4/fou_nl.c
+++ b/net/ipv4/fou_nl.c
@@ -14,7 +14,7 @@
const struct nla_policy fou_nl_policy[FOU_ATTR_IFINDEX + 1] = {
[FOU_ATTR_PORT] = { .type = NLA_U16, },
[FOU_ATTR_AF] = { .type = NLA_U8, },
- [FOU_ATTR_IPPROTO] = { .type = NLA_U8, },
+ [FOU_ATTR_IPPROTO] = NLA_POLICY_MIN(NLA_U8, 1),
[FOU_ATTR_TYPE] = { .type = NLA_U8, },
[FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG, },
[FOU_ATTR_LOCAL_V4] = { .type = NLA_U32, },
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index f261e29adc7c..75d388dd5ac6 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -860,10 +860,17 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
const void *daddr, const void *saddr, unsigned int len)
{
struct ip_tunnel *t = netdev_priv(dev);
- struct iphdr *iph;
struct gre_base_hdr *greh;
+ struct iphdr *iph;
+ int needed;
+
+ needed = t->hlen + sizeof(*iph);
+ if (skb_headroom(skb) < needed &&
+ pskb_expand_head(skb, HH_DATA_ALIGN(needed - skb_headroom(skb)),
+ 0, GFP_ATOMIC))
+ return -needed;
- iph = skb_push(skb, t->hlen + sizeof(*iph));
+ iph = skb_push(skb, needed);
greh = (struct gre_base_hdr *)(iph+1);
greh->flags = gre_tnl_flags_to_gre_flags(t->parms.o_flags);
greh->protocol = htons(type);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 2737bb4751e4..4958452cd332 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3111,12 +3111,12 @@ static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
in6_ifa_hold(ifp);
read_unlock_bh(&idev->lock);
- ipv6_del_addr(ifp);
-
if (!(ifp->flags & IFA_F_TEMPORARY) &&
(ifp->flags & IFA_F_MANAGETEMPADDR))
delete_tempaddrs(idev, ifp);
+ ipv6_del_addr(ifp);
+
addrconf_verify_rtnl(net);
if (ipv6_addr_is_multicast(pfx)) {
ipv6_mc_config(net->ipv6.mc_autojoin_sk,
diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
index 438f9cbdca29..333d87557bf3 100644
--- a/net/ipv6/esp6_offload.c
+++ b/net/ipv6/esp6_offload.c
@@ -145,8 +145,8 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x,
struct sk_buff *skb,
netdev_features_t features)
{
- const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x,
- XFRM_MODE_SKB_CB(skb)->protocol);
+ struct xfrm_offload *xo = xfrm_offload(skb);
+ const struct xfrm_mode *inner_mode = xfrm_ip2inner_mode(x, xo->proto);
__be16 type = inner_mode->family == AF_INET ? htons(ETH_P_IP)
: htons(ETH_P_IPV6);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index e635ddd41aba..69cace90ece1 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -844,7 +844,7 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
skb_reset_network_header(skb);
- if (!pskb_inet_may_pull(skb)) {
+ if (skb_vlan_inet_prepare(skb, true)) {
DEV_STATS_INC(tunnel->dev, rx_length_errors);
DEV_STATS_INC(tunnel->dev, rx_errors);
goto drop;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index d8e5e2833ede..80ceb401ecf2 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1574,8 +1574,8 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)
memcpy(&n, ((u8 *)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
mtu = ntohl(n);
- if (in6_dev->ra_mtu != mtu) {
- in6_dev->ra_mtu = mtu;
+ if (READ_ONCE(in6_dev->ra_mtu) != mtu) {
+ WRITE_ONCE(in6_dev->ra_mtu, mtu);
send_ifinfo_notify = true;
}
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 70da78ab9520..e0ca08ebd16a 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1250,8 +1250,6 @@ static void l2tp_tunnel_del_work(struct work_struct *work)
{
struct l2tp_tunnel *tunnel = container_of(work, struct l2tp_tunnel,
del_work);
- struct sock *sk = tunnel->sock;
- struct socket *sock = sk->sk_socket;
l2tp_tunnel_closeall(tunnel);
@@ -1259,6 +1257,8 @@ static void l2tp_tunnel_del_work(struct work_struct *work)
* the sk API to release it here.
*/
if (tunnel->fd < 0) {
+ struct socket *sock = tunnel->sock->sk_socket;
+
if (sock) {
kernel_sock_shutdown(sock, SHUT_RDWR);
sock_release(sock);
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 0b270893ee14..89e4bf4aa652 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -752,7 +752,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
unsigned char *dptr;
ax25_cb *ax25s;
int ret;
- struct sk_buff *skbn;
+ struct sk_buff *nskb, *oskb;
/*
* Reject malformed packets early. Check that it contains at least 2
@@ -811,14 +811,16 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
/* We are going to change the netrom headers so we should get our
own skb, we also did not know until now how much header space
we had to reserve... - RXQ */
- if ((skbn=skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC)) == NULL) {
+ nskb = skb_copy_expand(skb, dev->hard_header_len, 0, GFP_ATOMIC);
+
+ if (!nskb) {
nr_node_unlock(nr_node);
nr_node_put(nr_node);
dev_put(dev);
return 0;
}
- kfree_skb(skb);
- skb=skbn;
+ oskb = skb;
+ skb = nskb;
skb->data[14]--;
dptr = skb_push(skb, 1);
@@ -837,6 +839,9 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
nr_node_unlock(nr_node);
nr_node_put(nr_node);
+ if (ret)
+ kfree_skb(oskb);
+
return ret;
}
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 972ae01a70f7..0faa6e097829 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -310,22 +310,23 @@ void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)
*/
int ovs_vport_get_upcall_stats(struct vport *vport, struct sk_buff *skb)
{
+ u64 tx_success = 0, tx_fail = 0;
struct nlattr *nla;
int i;
- __u64 tx_success = 0;
- __u64 tx_fail = 0;
-
for_each_possible_cpu(i) {
const struct vport_upcall_stats_percpu *stats;
+ u64 n_success, n_fail;
unsigned int start;
stats = per_cpu_ptr(vport->upcall_stats, i);
do {
start = u64_stats_fetch_begin(&stats->syncp);
- tx_success += u64_stats_read(&stats->n_success);
- tx_fail += u64_stats_read(&stats->n_fail);
+ n_success = u64_stats_read(&stats->n_success);
+ n_fail = u64_stats_read(&stats->n_fail);
} while (u64_stats_fetch_retry(&stats->syncp, start));
+ tx_success += n_success;
+ tx_fail += n_fail;
}
nla = nla_nest_start_noflag(skb, OVS_VPORT_ATTR_UPCALL_STATS);
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index 431921204f66..567a58d30df8 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -821,6 +821,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
/* could be stupid policy setup or mtu config
* so lets be conservative.. */
if ((action == TC_ACT_SHOT) || exceed_mtu) {
+drop:
qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats));
return TC_ACT_SHOT;
}
@@ -829,6 +830,8 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
skb_push(skb, skb->dev->hard_header_len);
ife_meta = ife_encode(skb, metalen);
+ if (!ife_meta)
+ goto drop;
spin_lock(&ife->tcf_lock);
@@ -844,8 +847,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
if (err < 0) {
/* too corrupt to keep around if overwritten */
spin_unlock(&ife->tcf_lock);
- qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats));
- return TC_ACT_SHOT;
+ goto drop;
}
skboff += err;
}
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 29847c28ffac..a17f7c31378e 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -373,7 +373,7 @@ static void qfq_rm_from_agg(struct qfq_sched *q, struct qfq_class *cl)
/* Deschedule class and remove it from its parent aggregate. */
static void qfq_deact_rm_from_agg(struct qfq_sched *q, struct qfq_class *cl)
{
- if (cl->qdisc->q.qlen > 0) /* class is active */
+ if (cl_is_active(cl)) /* class is active */
qfq_deactivate_class(q, cl);
qfq_rm_from_agg(q, cl);
@@ -532,8 +532,10 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
return 0;
destroy_class:
- qdisc_put(cl->qdisc);
- kfree(cl);
+ if (!existing) {
+ qdisc_put(cl->qdisc);
+ kfree(cl);
+ }
return err;
}
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 7721239c185f..0a7856e14a97 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -178,6 +178,11 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt,
if (m->dev == dev)
return -ELOOP;
+ if (sch->parent != TC_H_ROOT) {
+ NL_SET_ERR_MSG_MOD(extack, "teql can only be used as root");
+ return -EOPNOTSUPP;
+ }
+
q->m = m;
skb_queue_head_init(&q->q);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index cd18b22b2bba..e0e626dc7953 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -602,6 +602,11 @@ enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net,
sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT,
SCTP_PEER_INIT(initchunk));
+ /* SCTP-AUTH: generate the association shared keys so that
+ * we can potentially sign the COOKIE-ECHO.
+ */
+ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL());
+
/* Reset init error count upon receipt of INIT-ACK. */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
@@ -616,11 +621,6 @@ enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net,
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_COOKIE_ECHOED));
- /* SCTP-AUTH: generate the association shared keys so that
- * we can potentially sign the COOKIE-ECHO.
- */
- sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL());
-
/* 5.1 C) "A" shall then send the State Cookie received in the
* INIT ACK chunk in a COOKIE ECHO chunk, ...
*/
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index c57fe7ddcf73..4c374c36c29d 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -28,6 +28,7 @@
static void virtio_transport_cancel_close_work(struct vsock_sock *vsk,
bool cancel_timeout);
+static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs);
static const struct virtio_transport *
virtio_transport_get_ops(struct vsock_sock *vsk)
@@ -316,9 +317,7 @@ u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 credit)
return 0;
spin_lock_bh(&vvs->tx_lock);
- ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);
- if (ret > credit)
- ret = credit;
+ ret = min_t(u32, credit, virtio_transport_has_space(vvs));
vvs->tx_cnt += ret;
spin_unlock_bh(&vvs->tx_lock);
@@ -629,6 +628,15 @@ virtio_transport_seqpacket_dequeue(struct vsock_sock *vsk,
}
EXPORT_SYMBOL_GPL(virtio_transport_seqpacket_dequeue);
+static u32 virtio_transport_tx_buf_size(struct virtio_vsock_sock *vvs)
+{
+ /* The peer advertises its receive buffer via peer_buf_alloc, but we
+ * cap it to our local buf_alloc so a remote peer cannot force us to
+ * queue more data than our own buffer configuration allows.
+ */
+ return min(vvs->peer_buf_alloc, vvs->buf_alloc);
+}
+
int
virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk,
struct msghdr *msg,
@@ -638,7 +646,7 @@ virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk,
spin_lock_bh(&vvs->tx_lock);
- if (len > vvs->peer_buf_alloc) {
+ if (len > virtio_transport_tx_buf_size(vvs)) {
spin_unlock_bh(&vvs->tx_lock);
return -EMSGSIZE;
}
@@ -684,12 +692,16 @@ u32 virtio_transport_seqpacket_has_data(struct vsock_sock *vsk)
}
EXPORT_SYMBOL_GPL(virtio_transport_seqpacket_has_data);
-static s64 virtio_transport_has_space(struct vsock_sock *vsk)
+static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs)
{
- struct virtio_vsock_sock *vvs = vsk->trans;
s64 bytes;
- bytes = (s64)vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);
+ /* Use s64 arithmetic so if the peer shrinks peer_buf_alloc while
+ * we have bytes in flight (tx_cnt - peer_fwd_cnt), the subtraction
+ * does not underflow.
+ */
+ bytes = (s64)virtio_transport_tx_buf_size(vvs) -
+ (vvs->tx_cnt - vvs->peer_fwd_cnt);
if (bytes < 0)
bytes = 0;
@@ -702,7 +714,7 @@ s64 virtio_transport_stream_has_space(struct vsock_sock *vsk)
s64 bytes;
spin_lock_bh(&vvs->tx_lock);
- bytes = virtio_transport_has_space(vsk);
+ bytes = virtio_transport_has_space(vvs);
spin_unlock_bh(&vvs->tx_lock);
return bytes;
@@ -1301,7 +1313,7 @@ static bool virtio_transport_space_update(struct sock *sk,
spin_lock_bh(&vvs->tx_lock);
vvs->peer_buf_alloc = le32_to_cpu(hdr->buf_alloc);
vvs->peer_fwd_cnt = le32_to_cpu(hdr->fwd_cnt);
- space_available = virtio_transport_has_space(vsk);
+ space_available = virtio_transport_has_space(vvs);
spin_unlock_bh(&vvs->tx_lock);
return space_available;
}
diff --git a/scripts/kconfig/nconf-cfg.sh b/scripts/kconfig/nconf-cfg.sh
index f871a2160e36..59814eb3616c 100755
--- a/scripts/kconfig/nconf-cfg.sh
+++ b/scripts/kconfig/nconf-cfg.sh
@@ -4,8 +4,9 @@
cflags=$1
libs=$2
-PKG="ncursesw menuw panelw"
-PKG2="ncurses menu panel"
+# Keep library order for static linking (HOSTCC='cc -static')
+PKG="menuw panelw ncursesw"
+PKG2="menu panel ncurses"
if [ -n "$(command -v ${HOSTPKG_CONFIG})" ]; then
if ${HOSTPKG_CONFIG} --exists $PKG; then
@@ -26,19 +27,19 @@ fi
# find ncurses by pkg-config.)
if [ -f /usr/include/ncursesw/ncurses.h ]; then
echo -D_GNU_SOURCE -I/usr/include/ncursesw > ${cflags}
- echo -lncursesw -lmenuw -lpanelw > ${libs}
+ echo -lmenuw -lpanelw -lncursesw > ${libs}
exit 0
fi
if [ -f /usr/include/ncurses/ncurses.h ]; then
echo -D_GNU_SOURCE -I/usr/include/ncurses > ${cflags}
- echo -lncurses -lmenu -lpanel > ${libs}
+ echo -lmenu -lpanel -lncurses > ${libs}
exit 0
fi
if [ -f /usr/include/ncurses.h ]; then
echo -D_GNU_SOURCE > ${cflags}
- echo -lncurses -lmenu -lpanel > ${libs}
+ echo -lmenu -lpanel -lncurses > ${libs}
exit 0
fi
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 471de2d1b37a..23ecbd70ccf6 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1085,7 +1085,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
runtime->oss.params = 0;
runtime->oss.prepare = 1;
runtime->oss.buffer_used = 0;
- snd_pcm_runtime_buffer_set_silence(runtime);
+ err = snd_pcm_runtime_buffer_set_silence(runtime);
+ if (err < 0)
+ goto failure;
runtime->oss.period_frames = snd_pcm_alsa_frames(substream, oss_period_size);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index f37fd1e48740..23578307f126 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -705,13 +705,18 @@ static void snd_pcm_buffer_access_unlock(struct snd_pcm_runtime *runtime)
}
/* fill the PCM buffer with the current silence format; called from pcm_oss.c */
-void snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime)
+int snd_pcm_runtime_buffer_set_silence(struct snd_pcm_runtime *runtime)
{
- snd_pcm_buffer_access_lock(runtime);
+ int err;
+
+ err = snd_pcm_buffer_access_lock(runtime);
+ if (err < 0)
+ return err;
if (runtime->dma_area)
snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
bytes_to_samples(runtime, runtime->dma_bytes));
snd_pcm_buffer_access_unlock(runtime);
+ return 0;
}
EXPORT_SYMBOL_GPL(snd_pcm_runtime_buffer_set_silence);
diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c
index d074727c3e21..5922b9dc5890 100644
--- a/sound/pci/ctxfi/ctamixer.c
+++ b/sound/pci/ctxfi/ctamixer.c
@@ -205,6 +205,7 @@ static int amixer_rsc_init(struct amixer *amixer,
/* Set amixer specific operations */
amixer->rsc.ops = &amixer_basic_rsc_ops;
+ amixer->rsc.conj = 0;
amixer->ops = &amixer_ops;
amixer->input = NULL;
amixer->sum = NULL;
@@ -369,6 +370,7 @@ static int sum_rsc_init(struct sum *sum,
return err;
sum->rsc.ops = &sum_basic_rsc_ops;
+ sum->rsc.conj = 0;
return 0;
}
diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c
index 41342b340680..78d95b8be2f2 100644
--- a/sound/soc/codecs/tlv320adcx140.c
+++ b/sound/soc/codecs/tlv320adcx140.c
@@ -24,7 +24,6 @@
#include "tlv320adcx140.h"
struct adcx140_priv {
- struct snd_soc_component *component;
struct regulator *supply_areg;
struct gpio_desc *gpio_reset;
struct regmap *regmap;
@@ -702,7 +701,6 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state)
{
int pwr_ctrl = 0;
int ret = 0;
- struct snd_soc_component *component = adcx140->component;
if (power_state)
pwr_ctrl = ADCX140_PWR_CFG_ADC_PDZ | ADCX140_PWR_CFG_PLL_PDZ;
@@ -714,7 +712,7 @@ static void adcx140_pwr_ctrl(struct adcx140_priv *adcx140, bool power_state)
ret = regmap_write(adcx140->regmap, ADCX140_PHASE_CALIB,
adcx140->phase_calib_on ? 0x00 : 0x40);
if (ret)
- dev_err(component->dev, "%s: register write error %d\n",
+ dev_err(adcx140->dev, "%s: register write error %d\n",
__func__, ret);
}
@@ -730,7 +728,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream,
struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component);
u8 data = 0;
- switch (params_width(params)) {
+ switch (params_physical_width(params)) {
case 16:
data = ADCX140_16_BIT_WORD;
break;
@@ -745,7 +743,7 @@ static int adcx140_hw_params(struct snd_pcm_substream *substream,
break;
default:
dev_err(component->dev, "%s: Unsupported width %d\n",
- __func__, params_width(params));
+ __func__, params_physical_width(params));
return -EINVAL;
}
diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
index 53b828f68102..c1f1414aa512 100644
--- a/sound/soc/codecs/wsa881x.c
+++ b/sound/soc/codecs/wsa881x.c
@@ -680,8 +680,8 @@ struct wsa881x_priv {
* For backwards compatibility.
*/
unsigned int sd_n_val;
- int version;
int active_ports;
+ bool hw_init;
bool port_prepared[WSA881X_MAX_SWR_PORTS];
bool port_enable[WSA881X_MAX_SWR_PORTS];
};
@@ -691,7 +691,9 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x)
struct regmap *rm = wsa881x->regmap;
unsigned int val = 0;
- regmap_read(rm, WSA881X_CHIP_ID1, &wsa881x->version);
+ if (wsa881x->hw_init)
+ return;
+
regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0,
ARRAY_SIZE(wsa881x_rev_2_0));
@@ -729,6 +731,8 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x)
regmap_update_bits(rm, WSA881X_OTP_REG_28, 0x3F, 0x3A);
regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG1, 0xFF, 0xB2);
regmap_update_bits(rm, WSA881X_BONGO_RESRV_REG2, 0xFF, 0x05);
+
+ wsa881x->hw_init = true;
}
static int wsa881x_component_probe(struct snd_soc_component *comp)
@@ -1073,6 +1077,9 @@ static int wsa881x_update_status(struct sdw_slave *slave,
{
struct wsa881x_priv *wsa881x = dev_get_drvdata(&slave->dev);
+ if (status == SDW_SLAVE_UNATTACHED)
+ wsa881x->hw_init = false;
+
if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
wsa881x_init(wsa881x);
diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c
index 1831d4487ba9..8d712781018a 100644
--- a/sound/soc/codecs/wsa883x.c
+++ b/sound/soc/codecs/wsa883x.c
@@ -444,6 +444,7 @@ struct wsa883x_priv {
int active_ports;
int dev_mode;
int comp_offset;
+ bool hw_init;
};
enum {
@@ -1003,6 +1004,9 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x)
struct regmap *regmap = wsa883x->regmap;
int variant, version, ret;
+ if (wsa883x->hw_init)
+ return 0;
+
ret = regmap_read(regmap, WSA883X_OTP_REG_0, &variant);
if (ret)
return ret;
@@ -1046,6 +1050,8 @@ static int wsa883x_init(struct wsa883x_priv *wsa883x)
wsa883x->comp_offset);
}
+ wsa883x->hw_init = true;
+
return 0;
}
@@ -1054,6 +1060,9 @@ static int wsa883x_update_status(struct sdw_slave *slave,
{
struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev);
+ if (status == SDW_SLAVE_UNATTACHED)
+ wsa883x->hw_init = false;
+
if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
return wsa883x_init(wsa883x);
diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c
index 1cd52fab7b40..7228a1418f2a 100644
--- a/sound/soc/codecs/wsa884x.c
+++ b/sound/soc/codecs/wsa884x.c
@@ -1482,7 +1482,7 @@ static void wsa884x_init(struct wsa884x_priv *wsa884x)
wsa884x_set_gain_parameters(wsa884x);
- wsa884x->hw_init = false;
+ wsa884x->hw_init = true;
}
static int wsa884x_update_status(struct sdw_slave *slave,
@@ -1884,7 +1884,6 @@ static int wsa884x_probe(struct sdw_slave *pdev,
/* Start in cache-only until device is enumerated */
regcache_cache_only(wsa884x->regmap, true);
- wsa884x->hw_init = true;
pm_runtime_set_autosuspend_delay(dev, 3000);
pm_runtime_use_autosuspend(dev);
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index e19d962fab87..ab39d86bd08d 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1807,11 +1807,10 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer,
range = (cval->max - cval->min) / cval->res;
/*
- * Are there devices with volume range more than 255? I use a bit more
- * to be sure. 384 is a resolution magic number found on Logitech
- * devices. It will definitively catch all buggy Logitech devices.
+ * There are definitely devices with a range of ~20,000, so let's be
+ * conservative and allow for a bit more.
*/
- if (range > 384) {
+ if (range > 65535) {
usb_audio_warn(mixer->chip,
"Warning! Unlikely big volume range (=%u), cval->res is probably wrong.",
range);
@@ -2939,10 +2938,23 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
{
+ struct usb_mixer_elem_list *list, *next;
+ int id;
+
/* kill pending URBs */
snd_usb_mixer_disconnect(mixer);
- kfree(mixer->id_elems);
+ /* Unregister controls first, snd_ctl_remove() frees the element */
+ if (mixer->id_elems) {
+ for (id = 0; id < MAX_ID_ELEMS; id++) {
+ for (list = mixer->id_elems[id]; list; list = next) {
+ next = list->next_id_elem;
+ if (list->kctl)
+ snd_ctl_remove(mixer->chip->card, list->kctl);
+ }
+ }
+ kfree(mixer->id_elems);
+ }
if (mixer->urb) {
kfree(mixer->urb->transfer_buffer);
usb_free_urb(mixer->urb);
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 316f1abefd51..6112c3fb8ba6 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -1408,11 +1408,16 @@ static int scarlett2_usb_get_config(
err = scarlett2_usb_get(mixer, config_item->offset, buf, size);
if (err < 0)
return err;
- if (size == 2) {
+ if (config_item->size == 16) {
u16 *buf_16 = buf;
for (i = 0; i < count; i++, buf_16++)
*buf_16 = le16_to_cpu(*(__le16 *)buf_16);
+ } else if (config_item->size == 32) {
+ u32 *buf_32 = (u32 *)buf;
+
+ for (i = 0; i < count; i++, buf_32++)
+ *buf_32 = le32_to_cpu(*(__le32 *)buf_32);
}
return 0;
}
diff --git a/tools/net/ynl/ynl-regen.sh b/tools/net/ynl/ynl-regen.sh
index bdba24066cf1..88bd42496cac 100755
--- a/tools/net/ynl/ynl-regen.sh
+++ b/tools/net/ynl/ynl-regen.sh
@@ -21,7 +21,7 @@ files=$(git grep --files-with-matches '^/\* YNL-GEN \(kernel\|uapi\|user\)')
for f in $files; do
# params: 0 1 2 3
# $YAML YNL-GEN kernel $mode
- params=( $(git grep -B1 -h '/\* YNL-GEN' $f | sed 's@/\*\(.*\)\*/@\1@') )
+ params=( $(git grep --no-line-number -B1 -h '/\* YNL-GEN' $f | sed 's@/\*\(.*\)\*/@\1@') )
args=$(sed -n 's@/\* YNL-ARG \(.*\) \*/@\1@p' $f)
if [ $f -nt ${params[0]} -a -z "$force" ]; then
diff --git a/tools/testing/selftests/bpf/prog_tests/perf_link.c b/tools/testing/selftests/bpf/prog_tests/perf_link.c
index 3a25f1c743a1..d940ff87fa08 100644
--- a/tools/testing/selftests/bpf/prog_tests/perf_link.c
+++ b/tools/testing/selftests/bpf/prog_tests/perf_link.c
@@ -4,8 +4,12 @@
#include <pthread.h>
#include <sched.h>
#include <test_progs.h>
+#include "testing_helpers.h"
#include "test_perf_link.skel.h"
+#define BURN_TIMEOUT_MS 100
+#define BURN_TIMEOUT_NS BURN_TIMEOUT_MS * 1000000
+
static void burn_cpu(void)
{
volatile int j = 0;
@@ -32,6 +36,7 @@ void serial_test_perf_link(void)
int run_cnt_before, run_cnt_after;
struct bpf_link_info info;
__u32 info_len = sizeof(info);
+ __u64 timeout_time_ns;
/* create perf event */
memset(&attr, 0, sizeof(attr));
@@ -63,8 +68,14 @@ void serial_test_perf_link(void)
ASSERT_GT(info.prog_id, 0, "link_prog_id");
/* ensure we get at least one perf_event prog execution */
- burn_cpu();
- ASSERT_GT(skel->bss->run_cnt, 0, "run_cnt");
+ timeout_time_ns = get_time_ns() + BURN_TIMEOUT_NS;
+ while (true) {
+ burn_cpu();
+ if (skel->bss->run_cnt > 0)
+ break;
+ if (!ASSERT_LT(get_time_ns(), timeout_time_ns, "run_cnt_timeout"))
+ break;
+ }
/* perf_event is still active, but we close link and BPF program
* shouldn't be executed anymore
diff --git a/tools/testing/selftests/net/amt.sh b/tools/testing/selftests/net/amt.sh
index 7e7ed6c558da..ea40b469a8c1 100755
--- a/tools/testing/selftests/net/amt.sh
+++ b/tools/testing/selftests/net/amt.sh
@@ -73,6 +73,8 @@
# +------------------------+
#==============================================================================
+source lib.sh
+
readonly LISTENER=$(mktemp -u listener-XXXXXXXX)
readonly GATEWAY=$(mktemp -u gateway-XXXXXXXX)
readonly RELAY=$(mktemp -u relay-XXXXXXXX)
@@ -240,14 +242,15 @@ test_ipv6_forward()
send_mcast4()
{
- sleep 2
+ sleep 5
+ wait_local_port_listen ${LISTENER} 4000 udp
ip netns exec "${SOURCE}" bash -c \
'printf "%s %128s" 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' &
}
send_mcast6()
{
- sleep 2
+ wait_local_port_listen ${LISTENER} 6000 udp
ip netns exec "${SOURCE}" bash -c \
'printf "%s %128s" 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' &
}
diff --git a/tools/testing/selftests/net/fib-onlink-tests.sh b/tools/testing/selftests/net/fib-onlink-tests.sh
index c287b90b8af8..c01be076b210 100755
--- a/tools/testing/selftests/net/fib-onlink-tests.sh
+++ b/tools/testing/selftests/net/fib-onlink-tests.sh
@@ -3,6 +3,7 @@
# IPv4 and IPv6 onlink tests
+source lib.sh
PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
VERBOSE=0
@@ -74,9 +75,6 @@ TEST_NET4IN6[2]=10.2.1.254
# mcast address
MCAST6=ff02::1
-
-PEER_NS=bart
-PEER_CMD="ip netns exec ${PEER_NS}"
VRF=lisa
VRF_TABLE=1101
PBR_TABLE=101
@@ -122,7 +120,7 @@ log_subsection()
run_cmd()
{
- local cmd="$*"
+ local cmd="$1"
local out
local rc
@@ -147,7 +145,7 @@ get_linklocal()
local pfx
local addr
- addr=$(${pfx} ip -6 -br addr show dev ${dev} | \
+ addr=$(${pfx} ${IP} -6 -br addr show dev ${dev} | \
awk '{
for (i = 3; i <= NF; ++i) {
if ($i ~ /^fe80/)
@@ -175,59 +173,48 @@ setup()
set -e
- # create namespace
- ip netns add ${PEER_NS}
- ip -netns ${PEER_NS} li set lo up
+ # create namespaces
+ setup_ns ns1
+ IP="ip -netns $ns1"
+ setup_ns ns2
# add vrf table
- ip li add ${VRF} type vrf table ${VRF_TABLE}
- ip li set ${VRF} up
- ip ro add table ${VRF_TABLE} unreachable default metric 8192
- ip -6 ro add table ${VRF_TABLE} unreachable default metric 8192
+ ${IP} li add ${VRF} type vrf table ${VRF_TABLE}
+ ${IP} li set ${VRF} up
+ ${IP} ro add table ${VRF_TABLE} unreachable default metric 8192
+ ${IP} -6 ro add table ${VRF_TABLE} unreachable default metric 8192
# create test interfaces
- ip li add ${NETIFS[p1]} type veth peer name ${NETIFS[p2]}
- ip li add ${NETIFS[p3]} type veth peer name ${NETIFS[p4]}
- ip li add ${NETIFS[p5]} type veth peer name ${NETIFS[p6]}
- ip li add ${NETIFS[p7]} type veth peer name ${NETIFS[p8]}
+ ${IP} li add ${NETIFS[p1]} type veth peer name ${NETIFS[p2]}
+ ${IP} li add ${NETIFS[p3]} type veth peer name ${NETIFS[p4]}
+ ${IP} li add ${NETIFS[p5]} type veth peer name ${NETIFS[p6]}
+ ${IP} li add ${NETIFS[p7]} type veth peer name ${NETIFS[p8]}
# enslave vrf interfaces
for n in 5 7; do
- ip li set ${NETIFS[p${n}]} vrf ${VRF}
+ ${IP} li set ${NETIFS[p${n}]} vrf ${VRF}
done
# add addresses
for n in 1 3 5 7; do
- ip li set ${NETIFS[p${n}]} up
- ip addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
- ip addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
+ ${IP} li set ${NETIFS[p${n}]} up
+ ${IP} addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
+ ${IP} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
done
# move peer interfaces to namespace and add addresses
for n in 2 4 6 8; do
- ip li set ${NETIFS[p${n}]} netns ${PEER_NS} up
- ip -netns ${PEER_NS} addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
- ip -netns ${PEER_NS} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
+ ${IP} li set ${NETIFS[p${n}]} netns ${ns2} up
+ ip -netns $ns2 addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
+ ip -netns $ns2 addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
done
- ip -6 ro add default via ${V6ADDRS[p3]/::[0-9]/::64}
- ip -6 ro add table ${VRF_TABLE} default via ${V6ADDRS[p7]/::[0-9]/::64}
+ ${IP} -6 ro add default via ${V6ADDRS[p3]/::[0-9]/::64}
+ ${IP} -6 ro add table ${VRF_TABLE} default via ${V6ADDRS[p7]/::[0-9]/::64}
set +e
}
-cleanup()
-{
- # make sure we start from a clean slate
- ip netns del ${PEER_NS} 2>/dev/null
- for n in 1 3 5 7; do
- ip link del ${NETIFS[p${n}]} 2>/dev/null
- done
- ip link del ${VRF} 2>/dev/null
- ip ro flush table ${VRF_TABLE}
- ip -6 ro flush table ${VRF_TABLE}
-}
-
################################################################################
# IPv4 tests
#
@@ -244,7 +231,7 @@ run_ip()
# dev arg may be empty
[ -n "${dev}" ] && dev="dev ${dev}"
- run_cmd ip ro add table "${table}" "${prefix}"/32 via "${gw}" "${dev}" onlink
+ run_cmd "${IP} ro add table ${table} ${prefix}/32 via ${gw} ${dev} onlink"
log_test $? ${exp_rc} "${desc}"
}
@@ -260,8 +247,8 @@ run_ip_mpath()
# dev arg may be empty
[ -n "${dev}" ] && dev="dev ${dev}"
- run_cmd ip ro add table "${table}" "${prefix}"/32 \
- nexthop via ${nh1} nexthop via ${nh2}
+ run_cmd "${IP} ro add table ${table} ${prefix}/32 \
+ nexthop via ${nh1} nexthop via ${nh2}"
log_test $? ${exp_rc} "${desc}"
}
@@ -342,7 +329,7 @@ run_ip6()
# dev arg may be empty
[ -n "${dev}" ] && dev="dev ${dev}"
- run_cmd ip -6 ro add table "${table}" "${prefix}"/128 via "${gw}" "${dev}" onlink
+ run_cmd "${IP} -6 ro add table ${table} ${prefix}/128 via ${gw} ${dev} onlink"
log_test $? ${exp_rc} "${desc}"
}
@@ -356,8 +343,8 @@ run_ip6_mpath()
local exp_rc="$6"
local desc="$7"
- run_cmd ip -6 ro add table "${table}" "${prefix}"/128 "${opts}" \
- nexthop via ${nh1} nexthop via ${nh2}
+ run_cmd "${IP} -6 ro add table ${table} ${prefix}/128 ${opts} \
+ nexthop via ${nh1} nexthop via ${nh2}"
log_test $? ${exp_rc} "${desc}"
}
@@ -494,10 +481,9 @@ do
esac
done
-cleanup
setup
run_onlink_tests
-cleanup
+cleanup_ns ${ns1} ${ns2}
if [ "$TESTS" != "none" ]; then
printf "\nTests passed: %3d\n" ${nsuccess}
diff --git a/tools/testing/selftests/net/toeplitz.c b/tools/testing/selftests/net/toeplitz.c
index 9ba03164d73a..5099157f01b9 100644
--- a/tools/testing/selftests/net/toeplitz.c
+++ b/tools/testing/selftests/net/toeplitz.c
@@ -473,8 +473,8 @@ static void parse_rps_bitmap(const char *arg)
bitmap = strtoul(arg, NULL, 0);
- if (bitmap & ~(RPS_MAX_CPUS - 1))
- error(1, 0, "rps bitmap 0x%lx out of bounds 0..%lu",
+ if (bitmap & ~((1UL << RPS_MAX_CPUS) - 1))
+ error(1, 0, "rps bitmap 0x%lx out of bounds, max cpu %lu",
bitmap, RPS_MAX_CPUS - 1);
for (i = 0; i < RPS_MAX_CPUS; i++)
diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
index c9f6cca4feb4..edc08a4433fd 100644
--- a/tools/testing/selftests/ptp/testptp.c
+++ b/tools/testing/selftests/ptp/testptp.c
@@ -121,6 +121,7 @@ static void usage(char *progname)
" -d name device to open\n"
" -e val read 'val' external time stamp events\n"
" -f val adjust the ptp clock frequency by 'val' ppb\n"
+ " -F chan Enable single channel mask and keep device open for debugfs verification.\n"
" -g get the ptp clock time\n"
" -h prints this message\n"
" -i val index for event/trigger\n"
@@ -139,12 +140,14 @@ static void usage(char *progname)
" -H val set output phase to 'val' nanoseconds (requires -p)\n"
" -w val set output pulse width to 'val' nanoseconds (requires -p)\n"
" -P val enable or disable (val=1|0) the system clock PPS\n"
+ " -r open the ptp clock in readonly mode\n"
" -s set the ptp clock time from the system time\n"
" -S set the system time from the ptp clock time\n"
" -t val shift the ptp clock time by 'val' seconds\n"
" -T val set the ptp clock time to 'val' seconds\n"
" -x val get an extended ptp clock time with the desired number of samples (up to %d)\n"
" -X get a ptp clock cross timestamp\n"
+ " -y val pre/post tstamp timebase to use {realtime|monotonic|monotonic-raw}\n"
" -z test combinations of rising/falling external time stamp flags\n",
progname, PTP_MAX_SAMPLES);
}
@@ -186,7 +189,10 @@ int main(int argc, char *argv[])
int pin_index = -1, pin_func;
int pps = -1;
int seconds = 0;
+ int readonly = 0;
int settime = 0;
+ int channel = -1;
+ clockid_t ext_clockid = CLOCK_REALTIME;
int64_t t1, t2, tp;
int64_t interval, offset;
@@ -196,7 +202,7 @@ int main(int argc, char *argv[])
progname = strrchr(argv[0], '/');
progname = progname ? 1+progname : argv[0];
- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
+ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xy:z"))) {
switch (c) {
case 'c':
capabilities = 1;
@@ -210,6 +216,9 @@ int main(int argc, char *argv[])
case 'f':
adjfreq = atoi(optarg);
break;
+ case 'F':
+ channel = atoi(optarg);
+ break;
case 'g':
gettime = 1;
break;
@@ -245,6 +254,9 @@ int main(int argc, char *argv[])
case 'P':
pps = atoi(optarg);
break;
+ case 'r':
+ readonly = 1;
+ break;
case 's':
settime = 1;
break;
@@ -273,6 +285,21 @@ int main(int argc, char *argv[])
case 'X':
getcross = 1;
break;
+ case 'y':
+ if (!strcasecmp(optarg, "realtime"))
+ ext_clockid = CLOCK_REALTIME;
+ else if (!strcasecmp(optarg, "monotonic"))
+ ext_clockid = CLOCK_MONOTONIC;
+ else if (!strcasecmp(optarg, "monotonic-raw"))
+ ext_clockid = CLOCK_MONOTONIC_RAW;
+ else {
+ fprintf(stderr,
+ "type needs to be realtime, monotonic or monotonic-raw; was given %s\n",
+ optarg);
+ return -1;
+ }
+ break;
+
case 'z':
flagtest = 1;
break;
@@ -286,7 +313,7 @@ int main(int argc, char *argv[])
}
}
- fd = open(device, O_RDWR);
+ fd = open(device, readonly ? O_RDONLY : O_RDWR);
if (fd < 0) {
fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
return -1;
@@ -414,14 +441,16 @@ int main(int argc, char *argv[])
}
if (extts) {
- memset(&extts_request, 0, sizeof(extts_request));
- extts_request.index = index;
- extts_request.flags = PTP_ENABLE_FEATURE;
- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
- perror("PTP_EXTTS_REQUEST");
- extts = 0;
- } else {
- puts("external time stamp request okay");
+ if (!readonly) {
+ memset(&extts_request, 0, sizeof(extts_request));
+ extts_request.index = index;
+ extts_request.flags = PTP_ENABLE_FEATURE;
+ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+ perror("PTP_EXTTS_REQUEST");
+ extts = 0;
+ } else {
+ puts("external time stamp request okay");
+ }
}
for (; extts; extts--) {
cnt = read(fd, &event, sizeof(event));
@@ -433,10 +462,12 @@ int main(int argc, char *argv[])
event.t.sec, event.t.nsec);
fflush(stdout);
}
- /* Disable the feature again. */
- extts_request.flags = 0;
- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
- perror("PTP_EXTTS_REQUEST");
+ if (!readonly) {
+ /* Disable the feature again. */
+ extts_request.flags = 0;
+ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+ perror("PTP_EXTTS_REQUEST");
+ }
}
}
@@ -561,6 +592,7 @@ int main(int argc, char *argv[])
}
soe->n_samples = getextended;
+ soe->clockid = ext_clockid;
if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, soe)) {
perror("PTP_SYS_OFFSET_EXTENDED");
@@ -569,12 +601,46 @@ int main(int argc, char *argv[])
getextended);
for (i = 0; i < getextended; i++) {
- printf("sample #%2d: system time before: %lld.%09u\n",
- i, soe->ts[i][0].sec, soe->ts[i][0].nsec);
+ switch (ext_clockid) {
+ case CLOCK_REALTIME:
+ printf("sample #%2d: real time before: %lld.%09u\n",
+ i, soe->ts[i][0].sec,
+ soe->ts[i][0].nsec);
+ break;
+ case CLOCK_MONOTONIC:
+ printf("sample #%2d: monotonic time before: %lld.%09u\n",
+ i, soe->ts[i][0].sec,
+ soe->ts[i][0].nsec);
+ break;
+ case CLOCK_MONOTONIC_RAW:
+ printf("sample #%2d: monotonic-raw time before: %lld.%09u\n",
+ i, soe->ts[i][0].sec,
+ soe->ts[i][0].nsec);
+ break;
+ default:
+ break;
+ }
printf(" phc time: %lld.%09u\n",
soe->ts[i][1].sec, soe->ts[i][1].nsec);
- printf(" system time after: %lld.%09u\n",
- soe->ts[i][2].sec, soe->ts[i][2].nsec);
+ switch (ext_clockid) {
+ case CLOCK_REALTIME:
+ printf(" real time after: %lld.%09u\n",
+ soe->ts[i][2].sec,
+ soe->ts[i][2].nsec);
+ break;
+ case CLOCK_MONOTONIC:
+ printf(" monotonic time after: %lld.%09u\n",
+ soe->ts[i][2].sec,
+ soe->ts[i][2].nsec);
+ break;
+ case CLOCK_MONOTONIC_RAW:
+ printf(" monotonic-raw time after: %lld.%09u\n",
+ soe->ts[i][2].sec,
+ soe->ts[i][2].nsec);
+ break;
+ default:
+ break;
+ }
}
}
@@ -604,6 +670,18 @@ int main(int argc, char *argv[])
free(xts);
}
+ if (channel >= 0) {
+ if (ioctl(fd, PTP_MASK_CLEAR_ALL)) {
+ perror("PTP_MASK_CLEAR_ALL");
+ } else if (ioctl(fd, PTP_MASK_EN_SINGLE, (unsigned int *)&channel)) {
+ perror("PTP_MASK_EN_SINGLE");
+ } else {
+ printf("Channel %d exclusively enabled. Check on debugfs.\n", channel);
+ printf("Press any key to continue\n.");
+ getchar();
+ }
+ }
+
close(fd);
return 0;
}
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 01b636d3039a..751fe7c6632e 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -360,6 +360,18 @@ void run_tests(const struct test_case *test_cases,
printf("ok\n");
}
+
+ printf("All tests have been executed. Waiting other peer...");
+ fflush(stdout);
+
+ /*
+ * Final full barrier, to ensure that all tests have been run and
+ * that even the last one has been successful on both sides.
+ */
+ control_writeln("COMPLETED");
+ control_expectln("COMPLETED");
+
+ printf("ok\n");
}
void list_tests(const struct test_case *test_cases)
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index 5dc7767039f6..793d688cd4da 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -396,6 +396,7 @@ static void test_stream_msg_peek_server(const struct test_opts *opts)
static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
{
+ unsigned long long sock_buf_size;
unsigned long curr_hash;
size_t max_msg_size;
int page_size;
@@ -408,6 +409,16 @@ static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)
exit(EXIT_FAILURE);
}
+ sock_buf_size = SOCK_BUF_SIZE;
+
+ setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_MAX_SIZE,
+ sock_buf_size,
+ "setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)");
+
+ setsockopt_ull_check(fd, AF_VSOCK, SO_VM_SOCKETS_BUFFER_SIZE,
+ sock_buf_size,
+ "setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)");
+
/* Wait, until receiver sets buffer size. */
control_expectln("SRVREADY");
Powered by blists - more mailing lists