From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id C32C015806E for ; Mon, 5 Jun 2023 11:47:57 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 02216E08FC; Mon, 5 Jun 2023 11:47:57 +0000 (UTC) Received: from smtp.gentoo.org (mail.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id B936EE08FC for ; Mon, 5 Jun 2023 11:47:56 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 9E792340ECC for ; Mon, 5 Jun 2023 11:47:55 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 2B0EBA5C for ; Mon, 5 Jun 2023 11:47:54 +0000 (UTC) From: "Mike Pagano" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" Message-ID: <1685965664.c25f4b52eeb6d16c5291a77e8e382fbddce0c5b4.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:6.3 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1005_linux-6.3.6.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: c25f4b52eeb6d16c5291a77e8e382fbddce0c5b4 X-VCS-Branch: 6.3 Date: Mon, 5 Jun 2023 11:47:54 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 31202843-3d7c-4b5a-afb5-18fc23858f72 X-Archives-Hash: 1b8fd5abd2b93153db14423a85c0e195 commit: c25f4b52eeb6d16c5291a77e8e382fbddce0c5b4 Author: Mike Pagano gentoo org> AuthorDate: Mon Jun 5 11:47:44 2023 +0000 Commit: Mike Pagano gentoo org> CommitDate: Mon Jun 5 11:47:44 2023 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c25f4b52 Linux patch 6.3.6 Signed-off-by: Mike Pagano gentoo.org> 0000_README | 4 + 1005_linux-6.3.6.patch | 2266 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2270 insertions(+) diff --git a/0000_README b/0000_README index 66dc0900..210d6768 100644 --- a/0000_README +++ b/0000_README @@ -63,6 +63,10 @@ Patch: 1004_linux-6.3.5.patch From: https://www.kernel.org Desc: Linux 6.3.5 +Patch: 1005_linux-6.3.6.patch +From: https://www.kernel.org +Desc: Linux 6.3.6 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1005_linux-6.3.6.patch b/1005_linux-6.3.6.patch new file mode 100644 index 00000000..b9df57e3 --- /dev/null +++ b/1005_linux-6.3.6.patch @@ -0,0 +1,2266 @@ +diff --git a/Makefile b/Makefile +index d710ff6a3d566..1dffadbf1f87f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 6 + PATCHLEVEL = 3 +-SUBLEVEL = 5 ++SUBLEVEL = 6 + EXTRAVERSION = + NAME = Hurr durr I'ma ninja sloth + +diff --git a/arch/arm/boot/dts/imx6ull-dhcor-som.dtsi b/arch/arm/boot/dts/imx6ull-dhcor-som.dtsi +index 5882c7565f649..32a6022625d97 100644 +--- a/arch/arm/boot/dts/imx6ull-dhcor-som.dtsi ++++ b/arch/arm/boot/dts/imx6ull-dhcor-som.dtsi +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include "imx6ull.dtsi" + + / { +@@ -84,16 +85,20 @@ + + regulators { + vdd_soc_in_1v4: buck1 { ++ regulator-allowed-modes = ; /* PFM */ + regulator-always-on; + regulator-boot-on; ++ regulator-initial-mode = ; + regulator-max-microvolt = <1400000>; + regulator-min-microvolt = <1400000>; + regulator-name = "vdd_soc_in_1v4"; + }; + + vcc_3v3: buck2 { ++ regulator-allowed-modes = ; /* PWM */ + regulator-always-on; + regulator-boot-on; ++ regulator-initial-mode = ; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_3v3"; +@@ -106,8 +111,10 @@ + * the voltage is set to 1.5V. + */ + vcc_ddr_1v35: buck3 { ++ regulator-allowed-modes = ; /* PWM */ + regulator-always-on; + regulator-boot-on; ++ regulator-initial-mode = ; + regulator-max-microvolt = <1500000>; + regulator-min-microvolt = <1500000>; + regulator-name = "vcc_ddr_1v35"; +diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c +index 9eb968e14d31f..a80d7c62bdfe6 100644 +--- a/block/blk-mq-tag.c ++++ b/block/blk-mq-tag.c +@@ -41,16 +41,20 @@ void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) + { + unsigned int users; + ++ /* ++ * calling test_bit() prior to test_and_set_bit() is intentional, ++ * it avoids dirtying the cacheline if the queue is already active. ++ */ + if (blk_mq_is_shared_tags(hctx->flags)) { + struct request_queue *q = hctx->queue; + +- if (test_bit(QUEUE_FLAG_HCTX_ACTIVE, &q->queue_flags)) ++ if (test_bit(QUEUE_FLAG_HCTX_ACTIVE, &q->queue_flags) || ++ test_and_set_bit(QUEUE_FLAG_HCTX_ACTIVE, &q->queue_flags)) + return; +- set_bit(QUEUE_FLAG_HCTX_ACTIVE, &q->queue_flags); + } else { +- if (test_bit(BLK_MQ_S_TAG_ACTIVE, &hctx->state)) ++ if (test_bit(BLK_MQ_S_TAG_ACTIVE, &hctx->state) || ++ test_and_set_bit(BLK_MQ_S_TAG_ACTIVE, &hctx->state)) + return; +- set_bit(BLK_MQ_S_TAG_ACTIVE, &hctx->state); + } + + users = atomic_inc_return(&hctx->tags->active_queues); +diff --git a/block/blk-wbt.c b/block/blk-wbt.c +index e49a486845327..9ec2a2f1eda38 100644 +--- a/block/blk-wbt.c ++++ b/block/blk-wbt.c +@@ -730,14 +730,16 @@ void wbt_enable_default(struct gendisk *disk) + { + struct request_queue *q = disk->queue; + struct rq_qos *rqos; +- bool disable_flag = q->elevator && +- test_bit(ELEVATOR_FLAG_DISABLE_WBT, &q->elevator->flags); ++ bool enable = IS_ENABLED(CONFIG_BLK_WBT_MQ); ++ ++ if (q->elevator && ++ test_bit(ELEVATOR_FLAG_DISABLE_WBT, &q->elevator->flags)) ++ enable = false; + + /* Throttling already enabled? */ + rqos = wbt_rq_qos(q); + if (rqos) { +- if (!disable_flag && +- RQWB(rqos)->enable_state == WBT_STATE_OFF_DEFAULT) ++ if (enable && RQWB(rqos)->enable_state == WBT_STATE_OFF_DEFAULT) + RQWB(rqos)->enable_state = WBT_STATE_ON_DEFAULT; + return; + } +@@ -746,7 +748,7 @@ void wbt_enable_default(struct gendisk *disk) + if (!blk_queue_registered(q)) + return; + +- if (queue_is_mq(q) && !disable_flag) ++ if (queue_is_mq(q) && enable) + wbt_init(disk); + } + EXPORT_SYMBOL_GPL(wbt_enable_default); +diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c +index 8dd46fad151eb..a7eb25066c274 100644 +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -422,9 +422,8 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy) + return 0; + } + +-static int amd_pstate_target(struct cpufreq_policy *policy, +- unsigned int target_freq, +- unsigned int relation) ++static int amd_pstate_update_freq(struct cpufreq_policy *policy, ++ unsigned int target_freq, bool fast_switch) + { + struct cpufreq_freqs freqs; + struct amd_cpudata *cpudata = policy->driver_data; +@@ -443,26 +442,50 @@ static int amd_pstate_target(struct cpufreq_policy *policy, + des_perf = DIV_ROUND_CLOSEST(target_freq * cap_perf, + cpudata->max_freq); + +- cpufreq_freq_transition_begin(policy, &freqs); +- amd_pstate_update(cpudata, min_perf, des_perf, +- max_perf, false); +- cpufreq_freq_transition_end(policy, &freqs, false); ++ WARN_ON(fast_switch && !policy->fast_switch_enabled); ++ /* ++ * If fast_switch is desired, then there aren't any registered ++ * transition notifiers. See comment for ++ * cpufreq_enable_fast_switch(). ++ */ ++ if (!fast_switch) ++ cpufreq_freq_transition_begin(policy, &freqs); ++ ++ amd_pstate_update(cpudata, min_perf, des_perf, max_perf, fast_switch); ++ ++ if (!fast_switch) ++ cpufreq_freq_transition_end(policy, &freqs, false); + + return 0; + } + ++static int amd_pstate_target(struct cpufreq_policy *policy, ++ unsigned int target_freq, ++ unsigned int relation) ++{ ++ return amd_pstate_update_freq(policy, target_freq, false); ++} ++ ++static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy, ++ unsigned int target_freq) ++{ ++ return amd_pstate_update_freq(policy, target_freq, true); ++} ++ + static void amd_pstate_adjust_perf(unsigned int cpu, + unsigned long _min_perf, + unsigned long target_perf, + unsigned long capacity) + { + unsigned long max_perf, min_perf, des_perf, +- cap_perf, lowest_nonlinear_perf; ++ cap_perf, lowest_nonlinear_perf, max_freq; + struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); + struct amd_cpudata *cpudata = policy->driver_data; ++ unsigned int target_freq; + + cap_perf = READ_ONCE(cpudata->highest_perf); + lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); ++ max_freq = READ_ONCE(cpudata->max_freq); + + des_perf = cap_perf; + if (target_perf < capacity) +@@ -479,6 +502,10 @@ static void amd_pstate_adjust_perf(unsigned int cpu, + if (max_perf < min_perf) + max_perf = min_perf; + ++ des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf); ++ target_freq = div_u64(des_perf * max_freq, max_perf); ++ policy->cur = target_freq; ++ + amd_pstate_update(cpudata, min_perf, des_perf, max_perf, true); + cpufreq_cpu_put(policy); + } +@@ -692,6 +719,7 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) + + freq_qos_remove_request(&cpudata->req[1]); + freq_qos_remove_request(&cpudata->req[0]); ++ policy->fast_switch_possible = false; + kfree(cpudata); + + return 0; +@@ -996,7 +1024,6 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) + policy->policy = CPUFREQ_POLICY_POWERSAVE; + + if (boot_cpu_has(X86_FEATURE_CPPC)) { +- policy->fast_switch_possible = true; + ret = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &value); + if (ret) + return ret; +@@ -1019,7 +1046,6 @@ free_cpudata1: + static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) + { + pr_debug("CPU %d exiting\n", policy->cpu); +- policy->fast_switch_possible = false; + return 0; + } + +@@ -1226,6 +1252,7 @@ static struct cpufreq_driver amd_pstate_driver = { + .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS, + .verify = amd_pstate_verify, + .target = amd_pstate_target, ++ .fast_switch = amd_pstate_fast_switch, + .init = amd_pstate_cpu_init, + .exit = amd_pstate_cpu_exit, + .suspend = amd_pstate_cpu_suspend, +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index 4d1f9c5b5029a..27cbf457416d2 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -751,11 +751,10 @@ struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport, + + parent_port = parent_dport ? parent_dport->port : NULL; + if (IS_ERR(port)) { +- dev_dbg(uport, "Failed to add %s%s%s%s: %ld\n", +- dev_name(&port->dev), +- parent_port ? " to " : "", ++ dev_dbg(uport, "Failed to add%s%s%s: %ld\n", ++ parent_port ? " port to " : "", + parent_port ? dev_name(&parent_port->dev) : "", +- parent_port ? "" : " (root port)", ++ parent_port ? "" : " root port", + PTR_ERR(port)); + } else { + dev_dbg(uport, "%s added%s%s%s\n", +diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c +index 02774baa90078..e234091386671 100644 +--- a/drivers/firmware/arm_ffa/driver.c ++++ b/drivers/firmware/arm_ffa/driver.c +@@ -193,7 +193,8 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3, + int idx, count, flags = 0, sz, buf_sz; + ffa_value_t partition_info; + +- if (!buffer || !num_partitions) /* Just get the count for now */ ++ if (drv_info->version > FFA_VERSION_1_0 && ++ (!buffer || !num_partitions)) /* Just get the count for now */ + flags = PARTITION_INFO_GET_RETURN_COUNT_ONLY; + + mutex_lock(&drv_info->rx_lock); +diff --git a/drivers/firmware/arm_scmi/raw_mode.c b/drivers/firmware/arm_scmi/raw_mode.c +index d40df099fd515..6971dcf72fb99 100644 +--- a/drivers/firmware/arm_scmi/raw_mode.c ++++ b/drivers/firmware/arm_scmi/raw_mode.c +@@ -1066,7 +1066,7 @@ static int scmi_xfer_raw_worker_init(struct scmi_raw_mode_info *raw) + + raw->wait_wq = alloc_workqueue("scmi-raw-wait-wq-%d", + WQ_UNBOUND | WQ_FREEZABLE | +- WQ_HIGHPRI, WQ_SYSFS, raw->id); ++ WQ_HIGHPRI | WQ_SYSFS, 0, raw->id); + if (!raw->wait_wq) + return -ENOMEM; + +diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +index badbe05823180..14b655411aa0a 100644 +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -879,7 +879,7 @@ config GPIO_F7188X + help + This option enables support for GPIOs found on Fintek Super-I/O + chips F71869, F71869A, F71882FG, F71889F and F81866. +- As well as Nuvoton Super-I/O chip NCT6116D. ++ As well as Nuvoton Super-I/O chip NCT6126D. + + To compile this driver as a module, choose M here: the module will + be called f7188x-gpio. +diff --git a/drivers/gpio/gpio-f7188x.c b/drivers/gpio/gpio-f7188x.c +index 9effa7769bef5..f54ca5a1775ea 100644 +--- a/drivers/gpio/gpio-f7188x.c ++++ b/drivers/gpio/gpio-f7188x.c +@@ -48,7 +48,7 @@ + /* + * Nuvoton devices. + */ +-#define SIO_NCT6116D_ID 0xD283 /* NCT6116D chipset ID */ ++#define SIO_NCT6126D_ID 0xD283 /* NCT6126D chipset ID */ + + #define SIO_LD_GPIO_NUVOTON 0x07 /* GPIO logical device */ + +@@ -62,7 +62,7 @@ enum chips { + f81866, + f81804, + f81865, +- nct6116d, ++ nct6126d, + }; + + static const char * const f7188x_names[] = { +@@ -74,7 +74,7 @@ static const char * const f7188x_names[] = { + "f81866", + "f81804", + "f81865", +- "nct6116d", ++ "nct6126d", + }; + + struct f7188x_sio { +@@ -187,8 +187,8 @@ static int f7188x_gpio_set_config(struct gpio_chip *chip, unsigned offset, + /* Output mode register (0:open drain 1:push-pull). */ + #define f7188x_gpio_out_mode(base) ((base) + 3) + +-#define f7188x_gpio_dir_invert(type) ((type) == nct6116d) +-#define f7188x_gpio_data_single(type) ((type) == nct6116d) ++#define f7188x_gpio_dir_invert(type) ((type) == nct6126d) ++#define f7188x_gpio_data_single(type) ((type) == nct6126d) + + static struct f7188x_gpio_bank f71869_gpio_bank[] = { + F7188X_GPIO_BANK(0, 6, 0xF0, DRVNAME "-0"), +@@ -274,7 +274,7 @@ static struct f7188x_gpio_bank f81865_gpio_bank[] = { + F7188X_GPIO_BANK(60, 5, 0x90, DRVNAME "-6"), + }; + +-static struct f7188x_gpio_bank nct6116d_gpio_bank[] = { ++static struct f7188x_gpio_bank nct6126d_gpio_bank[] = { + F7188X_GPIO_BANK(0, 8, 0xE0, DRVNAME "-0"), + F7188X_GPIO_BANK(10, 8, 0xE4, DRVNAME "-1"), + F7188X_GPIO_BANK(20, 8, 0xE8, DRVNAME "-2"), +@@ -282,7 +282,7 @@ static struct f7188x_gpio_bank nct6116d_gpio_bank[] = { + F7188X_GPIO_BANK(40, 8, 0xF0, DRVNAME "-4"), + F7188X_GPIO_BANK(50, 8, 0xF4, DRVNAME "-5"), + F7188X_GPIO_BANK(60, 8, 0xF8, DRVNAME "-6"), +- F7188X_GPIO_BANK(70, 1, 0xFC, DRVNAME "-7"), ++ F7188X_GPIO_BANK(70, 8, 0xFC, DRVNAME "-7"), + }; + + static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +@@ -490,9 +490,9 @@ static int f7188x_gpio_probe(struct platform_device *pdev) + data->nr_bank = ARRAY_SIZE(f81865_gpio_bank); + data->bank = f81865_gpio_bank; + break; +- case nct6116d: +- data->nr_bank = ARRAY_SIZE(nct6116d_gpio_bank); +- data->bank = nct6116d_gpio_bank; ++ case nct6126d: ++ data->nr_bank = ARRAY_SIZE(nct6126d_gpio_bank); ++ data->bank = nct6126d_gpio_bank; + break; + default: + return -ENODEV; +@@ -559,9 +559,9 @@ static int __init f7188x_find(int addr, struct f7188x_sio *sio) + case SIO_F81865_ID: + sio->type = f81865; + break; +- case SIO_NCT6116D_ID: ++ case SIO_NCT6126D_ID: + sio->device = SIO_LD_GPIO_NUVOTON; +- sio->type = nct6116d; ++ sio->type = nct6126d; + break; + default: + pr_info("Unsupported Fintek device 0x%04x\n", devid); +@@ -569,7 +569,7 @@ static int __init f7188x_find(int addr, struct f7188x_sio *sio) + } + + /* double check manufacturer where possible */ +- if (sio->type != nct6116d) { ++ if (sio->type != nct6126d) { + manid = superio_inw(addr, SIO_FINTEK_MANID); + if (manid != SIO_FINTEK_ID) { + pr_debug("Not a Fintek device at 0x%08x\n", addr); +@@ -581,7 +581,7 @@ static int __init f7188x_find(int addr, struct f7188x_sio *sio) + err = 0; + + pr_info("Found %s at %#x\n", f7188x_names[sio->type], (unsigned int)addr); +- if (sio->type != nct6116d) ++ if (sio->type != nct6126d) + pr_info(" revision %d\n", superio_inb(addr, SIO_FINTEK_DEVREV)); + + err: +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 19bd23044b017..4472214fcd43a 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -193,6 +193,8 @@ static int gpiochip_find_base(int ngpio) + break; + /* nope, check the space right after the chip */ + base = gdev->base + gdev->ngpio; ++ if (base < GPIO_DYNAMIC_BASE) ++ base = GPIO_DYNAMIC_BASE; + } + + if (gpio_is_valid(base)) { +diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c +index 254559abedfba..379050d228941 100644 +--- a/drivers/gpu/drm/i915/display/intel_ddi.c ++++ b/drivers/gpu/drm/i915/display/intel_ddi.c +@@ -2731,9 +2731,6 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, + const struct drm_connector_state *old_conn_state) + { + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); +- struct intel_digital_port *dig_port = enc_to_dig_port(encoder); +- enum phy phy = intel_port_to_phy(dev_priv, encoder->port); +- bool is_tc_port = intel_phy_is_tc(dev_priv, phy); + struct intel_crtc *slave_crtc; + + if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) { +@@ -2783,6 +2780,17 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, + else + intel_ddi_post_disable_dp(state, encoder, old_crtc_state, + old_conn_state); ++} ++ ++static void intel_ddi_post_pll_disable(struct intel_atomic_state *state, ++ struct intel_encoder *encoder, ++ const struct intel_crtc_state *old_crtc_state, ++ const struct drm_connector_state *old_conn_state) ++{ ++ struct drm_i915_private *i915 = to_i915(encoder->base.dev); ++ struct intel_digital_port *dig_port = enc_to_dig_port(encoder); ++ enum phy phy = intel_port_to_phy(i915, encoder->port); ++ bool is_tc_port = intel_phy_is_tc(i915, phy); + + main_link_aux_power_domain_put(dig_port, old_crtc_state); + +@@ -4381,6 +4389,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) + encoder->pre_pll_enable = intel_ddi_pre_pll_enable; + encoder->pre_enable = intel_ddi_pre_enable; + encoder->disable = intel_disable_ddi; ++ encoder->post_pll_disable = intel_ddi_post_pll_disable; + encoder->post_disable = intel_ddi_post_disable; + encoder->update_pipe = intel_ddi_update_pipe; + encoder->get_hw_state = intel_ddi_get_hw_state; +diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c +index 2bef50ab0ad19..c84b581c61c6b 100644 +--- a/drivers/gpu/drm/i915/display/intel_display.c ++++ b/drivers/gpu/drm/i915/display/intel_display.c +@@ -2000,6 +2000,8 @@ static void ilk_crtc_disable(struct intel_atomic_state *state, + + intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); + intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); ++ ++ intel_disable_shared_dpll(old_crtc_state); + } + + static void hsw_crtc_disable(struct intel_atomic_state *state, +@@ -2018,7 +2020,19 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, + intel_encoders_post_disable(state, crtc); + } + +- intel_dmc_disable_pipe(i915, crtc->pipe); ++ intel_disable_shared_dpll(old_crtc_state); ++ ++ if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) { ++ struct intel_crtc *slave_crtc; ++ ++ intel_encoders_post_pll_disable(state, crtc); ++ ++ intel_dmc_disable_pipe(i915, crtc->pipe); ++ ++ for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc, ++ intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) ++ intel_dmc_disable_pipe(i915, slave_crtc->pipe); ++ } + } + + static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) +@@ -7140,7 +7154,6 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, + dev_priv->display.funcs.display->crtc_disable(state, crtc); + crtc->active = false; + intel_fbc_disable(crtc); +- intel_disable_shared_dpll(old_crtc_state); + + if (!new_crtc_state->hw.active) + intel_initial_watermarks(state, crtc); +diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c +index 7c9b328bc2d73..a93018ce0e312 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c ++++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c +@@ -623,6 +623,20 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, + intel_dp->active_mst_links); + } + ++static void intel_mst_post_pll_disable_dp(struct intel_atomic_state *state, ++ struct intel_encoder *encoder, ++ const struct intel_crtc_state *old_crtc_state, ++ const struct drm_connector_state *old_conn_state) ++{ ++ struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); ++ struct intel_digital_port *dig_port = intel_mst->primary; ++ struct intel_dp *intel_dp = &dig_port->dp; ++ ++ if (intel_dp->active_mst_links == 0 && ++ dig_port->base.post_pll_disable) ++ dig_port->base.post_pll_disable(state, encoder, old_crtc_state, old_conn_state); ++} ++ + static void intel_mst_pre_pll_enable_dp(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config, +@@ -1146,6 +1160,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe + intel_encoder->compute_config_late = intel_dp_mst_compute_config_late; + intel_encoder->disable = intel_mst_disable_dp; + intel_encoder->post_disable = intel_mst_post_disable_dp; ++ intel_encoder->post_pll_disable = intel_mst_post_pll_disable_dp; + intel_encoder->update_pipe = intel_ddi_update_pipe; + intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp; + intel_encoder->pre_enable = intel_mst_pre_enable_dp; +diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c +index 52cdbd4fc2fa0..48b726e408057 100644 +--- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c ++++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c +@@ -96,7 +96,6 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, + + intel_fbc_disable(crtc); + intel_update_watermarks(i915); +- intel_disable_shared_dpll(crtc_state); + + intel_display_power_put_all_in_set(i915, &crtc->enabled_power_domains); + +diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c +index 711f451b69469..89e8ed214ea49 100644 +--- a/drivers/hwtracing/coresight/coresight-etm-perf.c ++++ b/drivers/hwtracing/coresight/coresight-etm-perf.c +@@ -402,6 +402,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, + trace_id = coresight_trace_id_get_cpu_id(cpu); + if (!IS_VALID_CS_TRACE_ID(trace_id)) { + cpumask_clear_cpu(cpu, mask); ++ coresight_release_path(path); + continue; + } + +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 577d94821b3e7..38e5b5abe067c 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -3834,6 +3834,11 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep, + index = fec_enet_get_bd_index(last_bdp, &txq->bd); + txq->tx_skbuff[index] = NULL; + ++ /* Make sure the updates to rest of the descriptor are performed before ++ * transferring ownership. ++ */ ++ dma_wmb(); ++ + /* Send it on its way. Tell FEC it's ready, interrupt when done, + * it's the last BD of the frame, and to put the CRC on the end. + */ +@@ -3843,8 +3848,14 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep, + /* If this was the last BD in the ring, start at the beginning again. */ + bdp = fec_enet_get_nextdesc(last_bdp, &txq->bd); + ++ /* Make sure the update to bdp are performed before txq->bd.cur. */ ++ dma_wmb(); ++ + txq->bd.cur = bdp; + ++ /* Trigger transmission start */ ++ writel(0, txq->bd.reg_desc_active); ++ + return 0; + } + +@@ -3873,12 +3884,6 @@ static int fec_enet_xdp_xmit(struct net_device *dev, + sent_frames++; + } + +- /* Make sure the update to bdp and tx_skbuff are performed. */ +- wmb(); +- +- /* Trigger transmission start */ +- writel(0, txq->bd.reg_desc_active); +- + __netif_tx_unlock(nq); + + return sent_frames; +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile +index 8d4e25cc54ea3..78755dfeaccea 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile ++++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile +@@ -69,7 +69,7 @@ mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += en/tc/sample.o + # + mlx5_core-$(CONFIG_MLX5_ESWITCH) += eswitch.o eswitch_offloads.o eswitch_offloads_termtbl.o \ + ecpf.o rdma.o esw/legacy.o \ +- esw/debugfs.o esw/devlink_port.o esw/vporttbl.o esw/qos.o ++ esw/devlink_port.o esw/vporttbl.o esw/qos.o + + mlx5_core-$(CONFIG_MLX5_ESWITCH) += esw/acl/helper.o \ + esw/acl/egress_lgcy.o esw/acl/egress_ofld.o \ +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 2b1094e5b0c9d..53acd9a8a4c35 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -5793,22 +5793,43 @@ bool mlx5e_tc_update_skb_nic(struct mlx5_cqe64 *cqe, struct sk_buff *skb) + 0, NULL); + } + ++static struct mapping_ctx * ++mlx5e_get_priv_obj_mapping(struct mlx5e_priv *priv) ++{ ++ struct mlx5e_tc_table *tc; ++ struct mlx5_eswitch *esw; ++ struct mapping_ctx *ctx; ++ ++ if (is_mdev_switchdev_mode(priv->mdev)) { ++ esw = priv->mdev->priv.eswitch; ++ ctx = esw->offloads.reg_c0_obj_pool; ++ } else { ++ tc = mlx5e_fs_get_tc(priv->fs); ++ ctx = tc->mapping; ++ } ++ ++ return ctx; ++} ++ + int mlx5e_tc_action_miss_mapping_get(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr, + u64 act_miss_cookie, u32 *act_miss_mapping) + { +- struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; + struct mlx5_mapped_obj mapped_obj = {}; ++ struct mlx5_eswitch *esw; + struct mapping_ctx *ctx; + int err; + +- ctx = esw->offloads.reg_c0_obj_pool; +- ++ ctx = mlx5e_get_priv_obj_mapping(priv); + mapped_obj.type = MLX5_MAPPED_OBJ_ACT_MISS; + mapped_obj.act_miss_cookie = act_miss_cookie; + err = mapping_add(ctx, &mapped_obj, act_miss_mapping); + if (err) + return err; + ++ if (!is_mdev_switchdev_mode(priv->mdev)) ++ return 0; ++ ++ esw = priv->mdev->priv.eswitch; + attr->act_id_restore_rule = esw_add_restore_rule(esw, *act_miss_mapping); + if (IS_ERR(attr->act_id_restore_rule)) + goto err_rule; +@@ -5823,10 +5844,9 @@ err_rule: + void mlx5e_tc_action_miss_mapping_put(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr, + u32 act_miss_mapping) + { +- struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; +- struct mapping_ctx *ctx; ++ struct mapping_ctx *ctx = mlx5e_get_priv_obj_mapping(priv); + +- ctx = esw->offloads.reg_c0_obj_pool; +- mlx5_del_flow_rules(attr->act_id_restore_rule); ++ if (is_mdev_switchdev_mode(priv->mdev)) ++ mlx5_del_flow_rules(attr->act_id_restore_rule); + mapping_remove(ctx, act_miss_mapping); + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/debugfs.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/debugfs.c +deleted file mode 100644 +index 3d0bbcca1cb99..0000000000000 +--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/debugfs.c ++++ /dev/null +@@ -1,198 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +-/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ +- +-#include +-#include "eswitch.h" +- +-enum vnic_diag_counter { +- MLX5_VNIC_DIAG_TOTAL_Q_UNDER_PROCESSOR_HANDLE, +- MLX5_VNIC_DIAG_SEND_QUEUE_PRIORITY_UPDATE_FLOW, +- MLX5_VNIC_DIAG_COMP_EQ_OVERRUN, +- MLX5_VNIC_DIAG_ASYNC_EQ_OVERRUN, +- MLX5_VNIC_DIAG_CQ_OVERRUN, +- MLX5_VNIC_DIAG_INVALID_COMMAND, +- MLX5_VNIC_DIAG_QOUTA_EXCEEDED_COMMAND, +- MLX5_VNIC_DIAG_RX_STEERING_DISCARD, +-}; +- +-static int mlx5_esw_query_vnic_diag(struct mlx5_vport *vport, enum vnic_diag_counter counter, +- u64 *val) +-{ +- u32 out[MLX5_ST_SZ_DW(query_vnic_env_out)] = {}; +- u32 in[MLX5_ST_SZ_DW(query_vnic_env_in)] = {}; +- struct mlx5_core_dev *dev = vport->dev; +- u16 vport_num = vport->vport; +- void *vnic_diag_out; +- int err; +- +- MLX5_SET(query_vnic_env_in, in, opcode, MLX5_CMD_OP_QUERY_VNIC_ENV); +- MLX5_SET(query_vnic_env_in, in, vport_number, vport_num); +- if (!mlx5_esw_is_manager_vport(dev->priv.eswitch, vport_num)) +- MLX5_SET(query_vnic_env_in, in, other_vport, 1); +- +- err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); +- if (err) +- return err; +- +- vnic_diag_out = MLX5_ADDR_OF(query_vnic_env_out, out, vport_env); +- switch (counter) { +- case MLX5_VNIC_DIAG_TOTAL_Q_UNDER_PROCESSOR_HANDLE: +- *val = MLX5_GET(vnic_diagnostic_statistics, vnic_diag_out, total_error_queues); +- break; +- case MLX5_VNIC_DIAG_SEND_QUEUE_PRIORITY_UPDATE_FLOW: +- *val = MLX5_GET(vnic_diagnostic_statistics, vnic_diag_out, +- send_queue_priority_update_flow); +- break; +- case MLX5_VNIC_DIAG_COMP_EQ_OVERRUN: +- *val = MLX5_GET(vnic_diagnostic_statistics, vnic_diag_out, comp_eq_overrun); +- break; +- case MLX5_VNIC_DIAG_ASYNC_EQ_OVERRUN: +- *val = MLX5_GET(vnic_diagnostic_statistics, vnic_diag_out, async_eq_overrun); +- break; +- case MLX5_VNIC_DIAG_CQ_OVERRUN: +- *val = MLX5_GET(vnic_diagnostic_statistics, vnic_diag_out, cq_overrun); +- break; +- case MLX5_VNIC_DIAG_INVALID_COMMAND: +- *val = MLX5_GET(vnic_diagnostic_statistics, vnic_diag_out, invalid_command); +- break; +- case MLX5_VNIC_DIAG_QOUTA_EXCEEDED_COMMAND: +- *val = MLX5_GET(vnic_diagnostic_statistics, vnic_diag_out, quota_exceeded_command); +- break; +- case MLX5_VNIC_DIAG_RX_STEERING_DISCARD: +- *val = MLX5_GET64(vnic_diagnostic_statistics, vnic_diag_out, +- nic_receive_steering_discard); +- break; +- } +- +- return 0; +-} +- +-static int __show_vnic_diag(struct seq_file *file, struct mlx5_vport *vport, +- enum vnic_diag_counter type) +-{ +- u64 val = 0; +- int ret; +- +- ret = mlx5_esw_query_vnic_diag(vport, type, &val); +- if (ret) +- return ret; +- +- seq_printf(file, "%llu\n", val); +- return 0; +-} +- +-static int total_q_under_processor_handle_show(struct seq_file *file, void *priv) +-{ +- return __show_vnic_diag(file, file->private, MLX5_VNIC_DIAG_TOTAL_Q_UNDER_PROCESSOR_HANDLE); +-} +- +-static int send_queue_priority_update_flow_show(struct seq_file *file, void *priv) +-{ +- return __show_vnic_diag(file, file->private, +- MLX5_VNIC_DIAG_SEND_QUEUE_PRIORITY_UPDATE_FLOW); +-} +- +-static int comp_eq_overrun_show(struct seq_file *file, void *priv) +-{ +- return __show_vnic_diag(file, file->private, MLX5_VNIC_DIAG_COMP_EQ_OVERRUN); +-} +- +-static int async_eq_overrun_show(struct seq_file *file, void *priv) +-{ +- return __show_vnic_diag(file, file->private, MLX5_VNIC_DIAG_ASYNC_EQ_OVERRUN); +-} +- +-static int cq_overrun_show(struct seq_file *file, void *priv) +-{ +- return __show_vnic_diag(file, file->private, MLX5_VNIC_DIAG_CQ_OVERRUN); +-} +- +-static int invalid_command_show(struct seq_file *file, void *priv) +-{ +- return __show_vnic_diag(file, file->private, MLX5_VNIC_DIAG_INVALID_COMMAND); +-} +- +-static int quota_exceeded_command_show(struct seq_file *file, void *priv) +-{ +- return __show_vnic_diag(file, file->private, MLX5_VNIC_DIAG_QOUTA_EXCEEDED_COMMAND); +-} +- +-static int rx_steering_discard_show(struct seq_file *file, void *priv) +-{ +- return __show_vnic_diag(file, file->private, MLX5_VNIC_DIAG_RX_STEERING_DISCARD); +-} +- +-DEFINE_SHOW_ATTRIBUTE(total_q_under_processor_handle); +-DEFINE_SHOW_ATTRIBUTE(send_queue_priority_update_flow); +-DEFINE_SHOW_ATTRIBUTE(comp_eq_overrun); +-DEFINE_SHOW_ATTRIBUTE(async_eq_overrun); +-DEFINE_SHOW_ATTRIBUTE(cq_overrun); +-DEFINE_SHOW_ATTRIBUTE(invalid_command); +-DEFINE_SHOW_ATTRIBUTE(quota_exceeded_command); +-DEFINE_SHOW_ATTRIBUTE(rx_steering_discard); +- +-void mlx5_esw_vport_debugfs_destroy(struct mlx5_eswitch *esw, u16 vport_num) +-{ +- struct mlx5_vport *vport = mlx5_eswitch_get_vport(esw, vport_num); +- +- debugfs_remove_recursive(vport->dbgfs); +- vport->dbgfs = NULL; +-} +- +-/* vnic diag dir name is "pf", "ecpf" or "{vf/sf}_xxxx" */ +-#define VNIC_DIAG_DIR_NAME_MAX_LEN 8 +- +-void mlx5_esw_vport_debugfs_create(struct mlx5_eswitch *esw, u16 vport_num, bool is_sf, u16 sf_num) +-{ +- struct mlx5_vport *vport = mlx5_eswitch_get_vport(esw, vport_num); +- struct dentry *vnic_diag; +- char dir_name[VNIC_DIAG_DIR_NAME_MAX_LEN]; +- int err; +- +- if (!MLX5_CAP_GEN(esw->dev, vport_group_manager)) +- return; +- +- if (vport_num == MLX5_VPORT_PF) { +- strcpy(dir_name, "pf"); +- } else if (vport_num == MLX5_VPORT_ECPF) { +- strcpy(dir_name, "ecpf"); +- } else { +- err = snprintf(dir_name, VNIC_DIAG_DIR_NAME_MAX_LEN, "%s_%d", is_sf ? "sf" : "vf", +- is_sf ? sf_num : vport_num - MLX5_VPORT_FIRST_VF); +- if (WARN_ON(err < 0)) +- return; +- } +- +- vport->dbgfs = debugfs_create_dir(dir_name, esw->dbgfs); +- vnic_diag = debugfs_create_dir("vnic_diag", vport->dbgfs); +- +- if (MLX5_CAP_GEN(esw->dev, vnic_env_queue_counters)) { +- debugfs_create_file("total_q_under_processor_handle", 0444, vnic_diag, vport, +- &total_q_under_processor_handle_fops); +- debugfs_create_file("send_queue_priority_update_flow", 0444, vnic_diag, vport, +- &send_queue_priority_update_flow_fops); +- } +- +- if (MLX5_CAP_GEN(esw->dev, eq_overrun_count)) { +- debugfs_create_file("comp_eq_overrun", 0444, vnic_diag, vport, +- &comp_eq_overrun_fops); +- debugfs_create_file("async_eq_overrun", 0444, vnic_diag, vport, +- &async_eq_overrun_fops); +- } +- +- if (MLX5_CAP_GEN(esw->dev, vnic_env_cq_overrun)) +- debugfs_create_file("cq_overrun", 0444, vnic_diag, vport, &cq_overrun_fops); +- +- if (MLX5_CAP_GEN(esw->dev, invalid_command_count)) +- debugfs_create_file("invalid_command", 0444, vnic_diag, vport, +- &invalid_command_fops); +- +- if (MLX5_CAP_GEN(esw->dev, quota_exceeded_count)) +- debugfs_create_file("quota_exceeded_command", 0444, vnic_diag, vport, +- "a_exceeded_command_fops); +- +- if (MLX5_CAP_GEN(esw->dev, nic_receive_steering_discard)) +- debugfs_create_file("rx_steering_discard", 0444, vnic_diag, vport, +- &rx_steering_discard_fops); +- +-} +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +index 19fed514fc173..bb2720a23a501 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +@@ -36,7 +36,6 @@ + #include + #include + #include +-#include + #include "esw/acl/lgcy.h" + #include "esw/legacy.h" + #include "esw/qos.h" +@@ -1056,7 +1055,6 @@ int mlx5_eswitch_load_vport(struct mlx5_eswitch *esw, u16 vport_num, + if (err) + return err; + +- mlx5_esw_vport_debugfs_create(esw, vport_num, false, 0); + err = esw_offloads_load_rep(esw, vport_num); + if (err) + goto err_rep; +@@ -1064,7 +1062,6 @@ int mlx5_eswitch_load_vport(struct mlx5_eswitch *esw, u16 vport_num, + return err; + + err_rep: +- mlx5_esw_vport_debugfs_destroy(esw, vport_num); + mlx5_esw_vport_disable(esw, vport_num); + return err; + } +@@ -1072,7 +1069,6 @@ err_rep: + void mlx5_eswitch_unload_vport(struct mlx5_eswitch *esw, u16 vport_num) + { + esw_offloads_unload_rep(esw, vport_num); +- mlx5_esw_vport_debugfs_destroy(esw, vport_num); + mlx5_esw_vport_disable(esw, vport_num); + } + +@@ -1672,7 +1668,6 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) + dev->priv.eswitch = esw; + BLOCKING_INIT_NOTIFIER_HEAD(&esw->n_head); + +- esw->dbgfs = debugfs_create_dir("esw", mlx5_debugfs_get_dev_root(esw->dev)); + esw_info(dev, + "Total vports %d, per vport: max uc(%d) max mc(%d)\n", + esw->total_vports, +@@ -1696,7 +1691,6 @@ void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) + + esw_info(esw->dev, "cleanup\n"); + +- debugfs_remove_recursive(esw->dbgfs); + esw->dev->priv.eswitch = NULL; + destroy_workqueue(esw->work_queue); + WARN_ON(refcount_read(&esw->qos.refcnt)); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +index c8c12d1672f99..5fd971cee6fdc 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +@@ -195,7 +195,6 @@ struct mlx5_vport { + enum mlx5_eswitch_vport_event enabled_events; + int index; + struct devlink_port *dl_port; +- struct dentry *dbgfs; + }; + + struct mlx5_esw_indir_table; +@@ -342,7 +341,7 @@ struct mlx5_eswitch { + u32 large_group_num; + } params; + struct blocking_notifier_head n_head; +- struct dentry *dbgfs; ++ bool paired[MLX5_MAX_PORTS]; + }; + + void esw_offloads_disable(struct mlx5_eswitch *esw); +@@ -705,9 +704,6 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_ + void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_eswitch *esw, u16 vport_num); + struct devlink_port *mlx5_esw_offloads_devlink_port(struct mlx5_eswitch *esw, u16 vport_num); + +-void mlx5_esw_vport_debugfs_create(struct mlx5_eswitch *esw, u16 vport_num, bool is_sf, u16 sf_num); +-void mlx5_esw_vport_debugfs_destroy(struct mlx5_eswitch *esw, u16 vport_num); +- + int mlx5_esw_devlink_sf_port_register(struct mlx5_eswitch *esw, struct devlink_port *dl_port, + u16 vport_num, u32 controller, u32 sfnum); + void mlx5_esw_devlink_sf_port_unregister(struct mlx5_eswitch *esw, u16 vport_num); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index 590df9bf39a56..a60c9f292e10c 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -2744,6 +2744,9 @@ static int mlx5_esw_offloads_devcom_event(int event, + mlx5_eswitch_vport_match_metadata_enabled(peer_esw)) + break; + ++ if (esw->paired[mlx5_get_dev_index(peer_esw->dev)]) ++ break; ++ + err = mlx5_esw_offloads_set_ns_peer(esw, peer_esw, true); + if (err) + goto err_out; +@@ -2755,14 +2758,18 @@ static int mlx5_esw_offloads_devcom_event(int event, + if (err) + goto err_pair; + ++ esw->paired[mlx5_get_dev_index(peer_esw->dev)] = true; ++ peer_esw->paired[mlx5_get_dev_index(esw->dev)] = true; + mlx5_devcom_set_paired(devcom, MLX5_DEVCOM_ESW_OFFLOADS, true); + break; + + case ESW_OFFLOADS_DEVCOM_UNPAIR: +- if (!mlx5_devcom_is_paired(devcom, MLX5_DEVCOM_ESW_OFFLOADS)) ++ if (!esw->paired[mlx5_get_dev_index(peer_esw->dev)]) + break; + + mlx5_devcom_set_paired(devcom, MLX5_DEVCOM_ESW_OFFLOADS, false); ++ esw->paired[mlx5_get_dev_index(peer_esw->dev)] = false; ++ peer_esw->paired[mlx5_get_dev_index(esw->dev)] = false; + mlx5_esw_offloads_unpair(peer_esw); + mlx5_esw_offloads_unpair(esw); + mlx5_esw_offloads_set_ns_peer(esw, peer_esw, false); +@@ -3777,14 +3784,12 @@ int mlx5_esw_offloads_sf_vport_enable(struct mlx5_eswitch *esw, struct devlink_p + if (err) + goto devlink_err; + +- mlx5_esw_vport_debugfs_create(esw, vport_num, true, sfnum); + err = mlx5_esw_offloads_rep_load(esw, vport_num); + if (err) + goto rep_err; + return 0; + + rep_err: +- mlx5_esw_vport_debugfs_destroy(esw, vport_num); + mlx5_esw_devlink_sf_port_unregister(esw, vport_num); + devlink_err: + mlx5_esw_vport_disable(esw, vport_num); +@@ -3794,7 +3799,6 @@ devlink_err: + void mlx5_esw_offloads_sf_vport_disable(struct mlx5_eswitch *esw, u16 vport_num) + { + mlx5_esw_offloads_rep_unload(esw, vport_num); +- mlx5_esw_vport_debugfs_destroy(esw, vport_num); + mlx5_esw_devlink_sf_port_unregister(esw, vport_num); + mlx5_esw_vport_disable(esw, vport_num); + } +diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h +index a50235fdf7d99..055e4ca5b3b5c 100644 +--- a/drivers/net/phy/mscc/mscc.h ++++ b/drivers/net/phy/mscc/mscc.h +@@ -179,6 +179,7 @@ enum rgmii_clock_delay { + #define VSC8502_RGMII_CNTL 20 + #define VSC8502_RGMII_RX_DELAY_MASK 0x0070 + #define VSC8502_RGMII_TX_DELAY_MASK 0x0007 ++#define VSC8502_RGMII_RX_CLK_DISABLE 0x0800 + + #define MSCC_PHY_WOL_LOWER_MAC_ADDR 21 + #define MSCC_PHY_WOL_MID_MAC_ADDR 22 +diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c +index bd81a4b041e52..adc8cd6f2d95a 100644 +--- a/drivers/net/phy/mscc/mscc_main.c ++++ b/drivers/net/phy/mscc/mscc_main.c +@@ -519,14 +519,27 @@ out_unlock: + * * 2.0 ns (which causes the data to be sampled at exactly half way between + * clock transitions at 1000 Mbps) if delays should be enabled + */ +-static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl, +- u16 rgmii_rx_delay_mask, +- u16 rgmii_tx_delay_mask) ++static int vsc85xx_update_rgmii_cntl(struct phy_device *phydev, u32 rgmii_cntl, ++ u16 rgmii_rx_delay_mask, ++ u16 rgmii_tx_delay_mask) + { + u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1; + u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1; + u16 reg_val = 0; +- int rc; ++ u16 mask = 0; ++ int rc = 0; ++ ++ /* For traffic to pass, the VSC8502 family needs the RX_CLK disable bit ++ * to be unset for all PHY modes, so do that as part of the paged ++ * register modification. ++ * For some family members (like VSC8530/31/40/41) this bit is reserved ++ * and read-only, and the RX clock is enabled by default. ++ */ ++ if (rgmii_cntl == VSC8502_RGMII_CNTL) ++ mask |= VSC8502_RGMII_RX_CLK_DISABLE; ++ ++ if (phy_interface_is_rgmii(phydev)) ++ mask |= rgmii_rx_delay_mask | rgmii_tx_delay_mask; + + mutex_lock(&phydev->lock); + +@@ -537,10 +550,9 @@ static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl, + phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) + reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos; + +- rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2, +- rgmii_cntl, +- rgmii_rx_delay_mask | rgmii_tx_delay_mask, +- reg_val); ++ if (mask) ++ rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2, ++ rgmii_cntl, mask, reg_val); + + mutex_unlock(&phydev->lock); + +@@ -549,19 +561,11 @@ static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl, + + static int vsc85xx_default_config(struct phy_device *phydev) + { +- int rc; +- + phydev->mdix_ctrl = ETH_TP_MDI_AUTO; + +- if (phy_interface_mode_is_rgmii(phydev->interface)) { +- rc = vsc85xx_rgmii_set_skews(phydev, VSC8502_RGMII_CNTL, +- VSC8502_RGMII_RX_DELAY_MASK, +- VSC8502_RGMII_TX_DELAY_MASK); +- if (rc) +- return rc; +- } +- +- return 0; ++ return vsc85xx_update_rgmii_cntl(phydev, VSC8502_RGMII_CNTL, ++ VSC8502_RGMII_RX_DELAY_MASK, ++ VSC8502_RGMII_TX_DELAY_MASK); + } + + static int vsc85xx_get_tunable(struct phy_device *phydev, +@@ -1758,13 +1762,11 @@ static int vsc8584_config_init(struct phy_device *phydev) + if (ret) + return ret; + +- if (phy_interface_is_rgmii(phydev)) { +- ret = vsc85xx_rgmii_set_skews(phydev, VSC8572_RGMII_CNTL, +- VSC8572_RGMII_RX_DELAY_MASK, +- VSC8572_RGMII_TX_DELAY_MASK); +- if (ret) +- return ret; +- } ++ ret = vsc85xx_update_rgmii_cntl(phydev, VSC8572_RGMII_CNTL, ++ VSC8572_RGMII_RX_DELAY_MASK, ++ VSC8572_RGMII_TX_DELAY_MASK); ++ if (ret) ++ return ret; + + ret = genphy_soft_reset(phydev); + if (ret) +diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c +index 0acc0b6221290..dc9803e1a4b9b 100644 +--- a/drivers/platform/x86/amd/pmf/core.c ++++ b/drivers/platform/x86/amd/pmf/core.c +@@ -245,24 +245,29 @@ static const struct pci_device_id pmf_pci_ids[] = { + { } + }; + +-int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) ++static void amd_pmf_set_dram_addr(struct amd_pmf_dev *dev) + { + u64 phys_addr; + u32 hi, low; + +- INIT_DELAYED_WORK(&dev->work_buffer, amd_pmf_get_metrics); ++ phys_addr = virt_to_phys(dev->buf); ++ hi = phys_addr >> 32; ++ low = phys_addr & GENMASK(31, 0); ++ ++ amd_pmf_send_cmd(dev, SET_DRAM_ADDR_HIGH, 0, hi, NULL); ++ amd_pmf_send_cmd(dev, SET_DRAM_ADDR_LOW, 0, low, NULL); ++} + ++int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) ++{ + /* Get Metrics Table Address */ + dev->buf = kzalloc(sizeof(dev->m_table), GFP_KERNEL); + if (!dev->buf) + return -ENOMEM; + +- phys_addr = virt_to_phys(dev->buf); +- hi = phys_addr >> 32; +- low = phys_addr & GENMASK(31, 0); ++ INIT_DELAYED_WORK(&dev->work_buffer, amd_pmf_get_metrics); + +- amd_pmf_send_cmd(dev, SET_DRAM_ADDR_HIGH, 0, hi, NULL); +- amd_pmf_send_cmd(dev, SET_DRAM_ADDR_LOW, 0, low, NULL); ++ amd_pmf_set_dram_addr(dev); + + /* + * Start collecting the metrics data after a small delay +@@ -273,6 +278,18 @@ int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev) + return 0; + } + ++static int amd_pmf_resume_handler(struct device *dev) ++{ ++ struct amd_pmf_dev *pdev = dev_get_drvdata(dev); ++ ++ if (pdev->buf) ++ amd_pmf_set_dram_addr(pdev); ++ ++ return 0; ++} ++ ++static DEFINE_SIMPLE_DEV_PM_OPS(amd_pmf_pm, NULL, amd_pmf_resume_handler); ++ + static void amd_pmf_init_features(struct amd_pmf_dev *dev) + { + int ret; +@@ -414,6 +431,7 @@ static struct platform_driver amd_pmf_driver = { + .name = "amd-pmf", + .acpi_match_table = amd_pmf_acpi_ids, + .dev_groups = amd_pmf_driver_groups, ++ .pm = pm_sleep_ptr(&amd_pmf_pm), + }, + .probe = amd_pmf_probe, + .remove = amd_pmf_remove, +diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c +index 73f744a3155d4..ea33693b69779 100644 +--- a/drivers/power/supply/rt9467-charger.c ++++ b/drivers/power/supply/rt9467-charger.c +@@ -1023,7 +1023,7 @@ static int rt9467_request_interrupt(struct rt9467_chg_data *data) + for (i = 0; i < num_chg_irqs; i++) { + virq = regmap_irq_get_virq(data->irq_chip_data, chg_irqs[i].hwirq); + if (virq <= 0) +- return dev_err_probe(dev, virq, "Failed to get (%s) irq\n", ++ return dev_err_probe(dev, -EINVAL, "Failed to get (%s) irq\n", + chg_irqs[i].name); + + ret = devm_request_threaded_irq(dev, virq, NULL, chg_irqs[i].handler, +diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c +index babb039bcb431..b106faf21a723 100644 +--- a/drivers/spi/spi-geni-qcom.c ++++ b/drivers/spi/spi-geni-qcom.c +@@ -294,6 +294,8 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag) + mas->cs_flag = set_flag; + /* set xfer_mode to FIFO to complete cs_done in isr */ + mas->cur_xfer_mode = GENI_SE_FIFO; ++ geni_se_select_mode(se, mas->cur_xfer_mode); ++ + reinit_completion(&mas->cs_done); + if (set_flag) + geni_se_setup_m_cmd(se, SPI_CS_ASSERT, 0); +diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c +index 493c31de0edb9..0620dbe5cca0c 100644 +--- a/drivers/vfio/vfio_iommu_type1.c ++++ b/drivers/vfio/vfio_iommu_type1.c +@@ -860,6 +860,11 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data, + if (ret) + goto pin_unwind; + ++ if (!pfn_valid(phys_pfn)) { ++ ret = -EINVAL; ++ goto pin_unwind; ++ } ++ + ret = vfio_add_to_pfn_list(dma, iova, phys_pfn); + if (ret) { + if (put_pfn(phys_pfn, dma->prot) && do_accounting) +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index dbcaac8b69665..4a882f9ba1f1f 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1577,6 +1577,16 @@ static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from) + to->l4_hash = from->l4_hash; + }; + ++static inline int skb_cmp_decrypted(const struct sk_buff *skb1, ++ const struct sk_buff *skb2) ++{ ++#ifdef CONFIG_TLS_DEVICE ++ return skb2->decrypted - skb1->decrypted; ++#else ++ return 0; ++#endif ++} ++ + static inline void skb_copy_decrypted(struct sk_buff *to, + const struct sk_buff *from) + { +diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h +index 84f787416a54d..054d7911bfc9f 100644 +--- a/include/linux/skmsg.h ++++ b/include/linux/skmsg.h +@@ -71,7 +71,6 @@ struct sk_psock_link { + }; + + struct sk_psock_work_state { +- struct sk_buff *skb; + u32 len; + u32 off; + }; +@@ -105,7 +104,7 @@ struct sk_psock { + struct proto *sk_proto; + struct mutex work_mutex; + struct sk_psock_work_state work_state; +- struct work_struct work; ++ struct delayed_work work; + struct rcu_work rwork; + }; + +diff --git a/include/net/tcp.h b/include/net/tcp.h +index db9f828e9d1ee..76bf0a11bdc77 100644 +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -1467,6 +1467,8 @@ static inline void tcp_adjust_rcv_ssthresh(struct sock *sk) + } + + void tcp_cleanup_rbuf(struct sock *sk, int copied); ++void __tcp_cleanup_rbuf(struct sock *sk, int copied); ++ + + /* We provision sk_rcvbuf around 200% of sk_rcvlowat. + * If 87.5 % (7/8) of the space has been consumed, we want to override +@@ -2323,6 +2325,14 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore); + void tcp_bpf_clone(const struct sock *sk, struct sock *newsk); + #endif /* CONFIG_BPF_SYSCALL */ + ++#ifdef CONFIG_INET ++void tcp_eat_skb(struct sock *sk, struct sk_buff *skb); ++#else ++static inline void tcp_eat_skb(struct sock *sk, struct sk_buff *skb) ++{ ++} ++#endif ++ + int tcp_bpf_sendmsg_redir(struct sock *sk, bool ingress, + struct sk_msg *msg, u32 bytes, int flags); + #endif /* CONFIG_NET_SOCK_MSG */ +diff --git a/include/net/tls.h b/include/net/tls.h +index 154949c7b0c88..c36bf4c50027e 100644 +--- a/include/net/tls.h ++++ b/include/net/tls.h +@@ -124,6 +124,7 @@ struct tls_strparser { + u32 mark : 8; + u32 stopped : 1; + u32 copy_mode : 1; ++ u32 mixed_decrypted : 1; + u32 msg_ready : 1; + + struct strp_msg stm; +diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c +index 0c85e06f7ea7f..ee146430d9984 100644 +--- a/kernel/bpf/offload.c ++++ b/kernel/bpf/offload.c +@@ -853,4 +853,4 @@ static int __init bpf_offload_init(void) + return rhashtable_init(&offdevs, &offdevs_params); + } + +-late_initcall(bpf_offload_init); ++core_initcall(bpf_offload_init); +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index f597fe0db9f8f..1d249d839819d 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -987,6 +987,34 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, + + BT_DBG("cmd %x arg %lx", cmd, arg); + ++ /* Make sure the cmd is valid before doing anything */ ++ switch (cmd) { ++ case HCIGETDEVLIST: ++ case HCIGETDEVINFO: ++ case HCIGETCONNLIST: ++ case HCIDEVUP: ++ case HCIDEVDOWN: ++ case HCIDEVRESET: ++ case HCIDEVRESTAT: ++ case HCISETSCAN: ++ case HCISETAUTH: ++ case HCISETENCRYPT: ++ case HCISETPTYPE: ++ case HCISETLINKPOL: ++ case HCISETLINKMODE: ++ case HCISETACLMTU: ++ case HCISETSCOMTU: ++ case HCIINQUIRY: ++ case HCISETRAW: ++ case HCIGETCONNINFO: ++ case HCIGETAUTHINFO: ++ case HCIBLOCKADDR: ++ case HCIUNBLOCKADDR: ++ break; ++ default: ++ return -ENOIOCTLCMD; ++ } ++ + lock_sock(sk); + + if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) { +diff --git a/net/core/skmsg.c b/net/core/skmsg.c +index f81883759d381..a9060e1f0e437 100644 +--- a/net/core/skmsg.c ++++ b/net/core/skmsg.c +@@ -481,8 +481,6 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, + msg_rx = sk_psock_peek_msg(psock); + } + out: +- if (psock->work_state.skb && copied > 0) +- schedule_work(&psock->work); + return copied; + } + EXPORT_SYMBOL_GPL(sk_msg_recvmsg); +@@ -624,42 +622,33 @@ static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb, + + static void sk_psock_skb_state(struct sk_psock *psock, + struct sk_psock_work_state *state, +- struct sk_buff *skb, + int len, int off) + { + spin_lock_bh(&psock->ingress_lock); + if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) { +- state->skb = skb; + state->len = len; + state->off = off; +- } else { +- sock_drop(psock->sk, skb); + } + spin_unlock_bh(&psock->ingress_lock); + } + + static void sk_psock_backlog(struct work_struct *work) + { +- struct sk_psock *psock = container_of(work, struct sk_psock, work); ++ struct delayed_work *dwork = to_delayed_work(work); ++ struct sk_psock *psock = container_of(dwork, struct sk_psock, work); + struct sk_psock_work_state *state = &psock->work_state; + struct sk_buff *skb = NULL; ++ u32 len = 0, off = 0; + bool ingress; +- u32 len, off; + int ret; + + mutex_lock(&psock->work_mutex); +- if (unlikely(state->skb)) { +- spin_lock_bh(&psock->ingress_lock); +- skb = state->skb; ++ if (unlikely(state->len)) { + len = state->len; + off = state->off; +- state->skb = NULL; +- spin_unlock_bh(&psock->ingress_lock); + } +- if (skb) +- goto start; + +- while ((skb = skb_dequeue(&psock->ingress_skb))) { ++ while ((skb = skb_peek(&psock->ingress_skb))) { + len = skb->len; + off = 0; + if (skb_bpf_strparser(skb)) { +@@ -668,7 +657,6 @@ static void sk_psock_backlog(struct work_struct *work) + off = stm->offset; + len = stm->full_len; + } +-start: + ingress = skb_bpf_ingress(skb); + skb_bpf_redirect_clear(skb); + do { +@@ -678,22 +666,28 @@ start: + len, ingress); + if (ret <= 0) { + if (ret == -EAGAIN) { +- sk_psock_skb_state(psock, state, skb, +- len, off); ++ sk_psock_skb_state(psock, state, len, off); ++ ++ /* Delay slightly to prioritize any ++ * other work that might be here. ++ */ ++ if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) ++ schedule_delayed_work(&psock->work, 1); + goto end; + } + /* Hard errors break pipe and stop xmit. */ + sk_psock_report_error(psock, ret ? -ret : EPIPE); + sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED); +- sock_drop(psock->sk, skb); + goto end; + } + off += ret; + len -= ret; + } while (len); + +- if (!ingress) ++ skb = skb_dequeue(&psock->ingress_skb); ++ if (!ingress) { + kfree_skb(skb); ++ } + } + end: + mutex_unlock(&psock->work_mutex); +@@ -734,7 +728,7 @@ struct sk_psock *sk_psock_init(struct sock *sk, int node) + INIT_LIST_HEAD(&psock->link); + spin_lock_init(&psock->link_lock); + +- INIT_WORK(&psock->work, sk_psock_backlog); ++ INIT_DELAYED_WORK(&psock->work, sk_psock_backlog); + mutex_init(&psock->work_mutex); + INIT_LIST_HEAD(&psock->ingress_msg); + spin_lock_init(&psock->ingress_lock); +@@ -786,11 +780,6 @@ static void __sk_psock_zap_ingress(struct sk_psock *psock) + skb_bpf_redirect_clear(skb); + sock_drop(psock->sk, skb); + } +- kfree_skb(psock->work_state.skb); +- /* We null the skb here to ensure that calls to sk_psock_backlog +- * do not pick up the free'd skb. +- */ +- psock->work_state.skb = NULL; + __sk_psock_purge_ingress_msg(psock); + } + +@@ -809,7 +798,6 @@ void sk_psock_stop(struct sk_psock *psock) + spin_lock_bh(&psock->ingress_lock); + sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED); + sk_psock_cork_free(psock); +- __sk_psock_zap_ingress(psock); + spin_unlock_bh(&psock->ingress_lock); + } + +@@ -823,7 +811,8 @@ static void sk_psock_destroy(struct work_struct *work) + + sk_psock_done_strp(psock); + +- cancel_work_sync(&psock->work); ++ cancel_delayed_work_sync(&psock->work); ++ __sk_psock_zap_ingress(psock); + mutex_destroy(&psock->work_mutex); + + psock_progs_drop(&psock->progs); +@@ -938,7 +927,7 @@ static int sk_psock_skb_redirect(struct sk_psock *from, struct sk_buff *skb) + } + + skb_queue_tail(&psock_other->ingress_skb, skb); +- schedule_work(&psock_other->work); ++ schedule_delayed_work(&psock_other->work, 0); + spin_unlock_bh(&psock_other->ingress_lock); + return 0; + } +@@ -990,10 +979,8 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb, + err = -EIO; + sk_other = psock->sk; + if (sock_flag(sk_other, SOCK_DEAD) || +- !sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) { +- skb_bpf_redirect_clear(skb); ++ !sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) + goto out_free; +- } + + skb_bpf_set_ingress(skb); + +@@ -1018,22 +1005,23 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb, + spin_lock_bh(&psock->ingress_lock); + if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) { + skb_queue_tail(&psock->ingress_skb, skb); +- schedule_work(&psock->work); ++ schedule_delayed_work(&psock->work, 0); + err = 0; + } + spin_unlock_bh(&psock->ingress_lock); +- if (err < 0) { +- skb_bpf_redirect_clear(skb); ++ if (err < 0) + goto out_free; +- } + } + break; + case __SK_REDIRECT: ++ tcp_eat_skb(psock->sk, skb); + err = sk_psock_skb_redirect(psock, skb); + break; + case __SK_DROP: + default: + out_free: ++ skb_bpf_redirect_clear(skb); ++ tcp_eat_skb(psock->sk, skb); + sock_drop(psock->sk, skb); + } + +@@ -1049,7 +1037,7 @@ static void sk_psock_write_space(struct sock *sk) + psock = sk_psock(sk); + if (likely(psock)) { + if (sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) +- schedule_work(&psock->work); ++ schedule_delayed_work(&psock->work, 0); + write_space = psock->saved_write_space; + } + rcu_read_unlock(); +@@ -1078,8 +1066,7 @@ static void sk_psock_strp_read(struct strparser *strp, struct sk_buff *skb) + skb_dst_drop(skb); + skb_bpf_redirect_clear(skb); + ret = bpf_prog_run_pin_on_cpu(prog, skb); +- if (ret == SK_PASS) +- skb_bpf_set_strparser(skb); ++ skb_bpf_set_strparser(skb); + ret = sk_psock_map_verd(ret, skb_bpf_redirect_fetch(skb)); + skb->sk = NULL; + } +@@ -1183,12 +1170,11 @@ static int sk_psock_verdict_recv(struct sock *sk, struct sk_buff *skb) + int ret = __SK_DROP; + int len = skb->len; + +- skb_get(skb); +- + rcu_read_lock(); + psock = sk_psock(sk); + if (unlikely(!psock)) { + len = 0; ++ tcp_eat_skb(sk, skb); + sock_drop(sk, skb); + goto out; + } +@@ -1212,12 +1198,21 @@ out: + static void sk_psock_verdict_data_ready(struct sock *sk) + { + struct socket *sock = sk->sk_socket; ++ int copied; + + trace_sk_data_ready(sk); + + if (unlikely(!sock || !sock->ops || !sock->ops->read_skb)) + return; +- sock->ops->read_skb(sk, sk_psock_verdict_recv); ++ copied = sock->ops->read_skb(sk, sk_psock_verdict_recv); ++ if (copied >= 0) { ++ struct sk_psock *psock; ++ ++ rcu_read_lock(); ++ psock = sk_psock(sk); ++ psock->saved_data_ready(sk); ++ rcu_read_unlock(); ++ } + } + + void sk_psock_start_verdict(struct sock *sk, struct sk_psock *psock) +diff --git a/net/core/sock_map.c b/net/core/sock_map.c +index a055139f410e2..08851511294c0 100644 +--- a/net/core/sock_map.c ++++ b/net/core/sock_map.c +@@ -1624,9 +1624,10 @@ void sock_map_close(struct sock *sk, long timeout) + rcu_read_unlock(); + sk_psock_stop(psock); + release_sock(sk); +- cancel_work_sync(&psock->work); ++ cancel_delayed_work_sync(&psock->work); + sk_psock_put(sk, psock); + } ++ + /* Make sure we do not recurse. This is a bug. + * Leak the socket instead of crashing on a stack overflow. + */ +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 6c7c666554ced..ed63ee8f0d7e3 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -1570,7 +1570,7 @@ static int tcp_peek_sndq(struct sock *sk, struct msghdr *msg, int len) + * calculation of whether or not we must ACK for the sake of + * a window update. + */ +-static void __tcp_cleanup_rbuf(struct sock *sk, int copied) ++void __tcp_cleanup_rbuf(struct sock *sk, int copied) + { + struct tcp_sock *tp = tcp_sk(sk); + bool time_to_ack = false; +@@ -1772,7 +1772,6 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) + WARN_ON_ONCE(!skb_set_owner_sk_safe(skb, sk)); + tcp_flags = TCP_SKB_CB(skb)->tcp_flags; + used = recv_actor(sk, skb); +- consume_skb(skb); + if (used < 0) { + if (!copied) + copied = used; +@@ -1786,14 +1785,6 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) + break; + } + } +- WRITE_ONCE(tp->copied_seq, seq); +- +- tcp_rcv_space_adjust(sk); +- +- /* Clean up data we have read: This will do ACK frames. */ +- if (copied > 0) +- __tcp_cleanup_rbuf(sk, copied); +- + return copied; + } + EXPORT_SYMBOL(tcp_read_skb); +diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c +index 2e9547467edbe..5f93918c063c7 100644 +--- a/net/ipv4/tcp_bpf.c ++++ b/net/ipv4/tcp_bpf.c +@@ -11,6 +11,24 @@ + #include + #include + ++void tcp_eat_skb(struct sock *sk, struct sk_buff *skb) ++{ ++ struct tcp_sock *tcp; ++ int copied; ++ ++ if (!skb || !skb->len || !sk_is_tcp(sk)) ++ return; ++ ++ if (skb_bpf_strparser(skb)) ++ return; ++ ++ tcp = tcp_sk(sk); ++ copied = tcp->copied_seq + skb->len; ++ WRITE_ONCE(tcp->copied_seq, copied); ++ tcp_rcv_space_adjust(sk); ++ __tcp_cleanup_rbuf(sk, skb->len); ++} ++ + static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock, + struct sk_msg *msg, u32 apply_bytes, int flags) + { +@@ -174,14 +192,34 @@ static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock, + return ret; + } + ++static bool is_next_msg_fin(struct sk_psock *psock) ++{ ++ struct scatterlist *sge; ++ struct sk_msg *msg_rx; ++ int i; ++ ++ msg_rx = sk_psock_peek_msg(psock); ++ i = msg_rx->sg.start; ++ sge = sk_msg_elem(msg_rx, i); ++ if (!sge->length) { ++ struct sk_buff *skb = msg_rx->skb; ++ ++ if (skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) ++ return true; ++ } ++ return false; ++} ++ + static int tcp_bpf_recvmsg_parser(struct sock *sk, + struct msghdr *msg, + size_t len, + int flags, + int *addr_len) + { ++ struct tcp_sock *tcp = tcp_sk(sk); ++ u32 seq = tcp->copied_seq; + struct sk_psock *psock; +- int copied; ++ int copied = 0; + + if (unlikely(flags & MSG_ERRQUEUE)) + return inet_recv_error(sk, msg, len, addr_len); +@@ -194,8 +232,43 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk, + return tcp_recvmsg(sk, msg, len, flags, addr_len); + + lock_sock(sk); ++ ++ /* We may have received data on the sk_receive_queue pre-accept and ++ * then we can not use read_skb in this context because we haven't ++ * assigned a sk_socket yet so have no link to the ops. The work-around ++ * is to check the sk_receive_queue and in these cases read skbs off ++ * queue again. The read_skb hook is not running at this point because ++ * of lock_sock so we avoid having multiple runners in read_skb. ++ */ ++ if (unlikely(!skb_queue_empty(&sk->sk_receive_queue))) { ++ tcp_data_ready(sk); ++ /* This handles the ENOMEM errors if we both receive data ++ * pre accept and are already under memory pressure. At least ++ * let user know to retry. ++ */ ++ if (unlikely(!skb_queue_empty(&sk->sk_receive_queue))) { ++ copied = -EAGAIN; ++ goto out; ++ } ++ } ++ + msg_bytes_ready: + copied = sk_msg_recvmsg(sk, psock, msg, len, flags); ++ /* The typical case for EFAULT is the socket was gracefully ++ * shutdown with a FIN pkt. So check here the other case is ++ * some error on copy_page_to_iter which would be unexpected. ++ * On fin return correct return code to zero. ++ */ ++ if (copied == -EFAULT) { ++ bool is_fin = is_next_msg_fin(psock); ++ ++ if (is_fin) { ++ copied = 0; ++ seq++; ++ goto out; ++ } ++ } ++ seq += copied; + if (!copied) { + long timeo; + int data; +@@ -233,6 +306,10 @@ msg_bytes_ready: + copied = -EAGAIN; + } + out: ++ WRITE_ONCE(tcp->copied_seq, seq); ++ tcp_rcv_space_adjust(sk); ++ if (copied > 0) ++ __tcp_cleanup_rbuf(sk, copied); + release_sock(sk); + sk_psock_put(sk, psock); + return copied; +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index c605d171eb2d9..8aaae82e78aeb 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1813,7 +1813,7 @@ EXPORT_SYMBOL(__skb_recv_udp); + int udp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) + { + struct sk_buff *skb; +- int err, copied; ++ int err; + + try_again: + skb = skb_recv_udp(sk, MSG_DONTWAIT, &err); +@@ -1832,10 +1832,7 @@ try_again: + } + + WARN_ON_ONCE(!skb_set_owner_sk_safe(skb, sk)); +- copied = recv_actor(sk, skb); +- kfree_skb(skb); +- +- return copied; ++ return recv_actor(sk, skb); + } + EXPORT_SYMBOL(udp_read_skb); + +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 6f3b23a6653cc..d40544cd61a6c 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -1559,9 +1559,6 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { + + static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data) + { +- if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) +- return 0; +- + return ctnetlink_filter_match(ct, data); + } + +@@ -1631,11 +1628,6 @@ static int ctnetlink_del_conntrack(struct sk_buff *skb, + + ct = nf_ct_tuplehash_to_ctrack(h); + +- if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) { +- nf_ct_put(ct); +- return -EBUSY; +- } +- + if (cda[CTA_ID]) { + __be32 id = nla_get_be32(cda[CTA_ID]); + +diff --git a/net/tls/tls.h b/net/tls/tls.h +index 804c3880d0288..0672acab27731 100644 +--- a/net/tls/tls.h ++++ b/net/tls/tls.h +@@ -167,6 +167,11 @@ static inline bool tls_strp_msg_ready(struct tls_sw_context_rx *ctx) + return ctx->strp.msg_ready; + } + ++static inline bool tls_strp_msg_mixed_decrypted(struct tls_sw_context_rx *ctx) ++{ ++ return ctx->strp.mixed_decrypted; ++} ++ + #ifdef CONFIG_TLS_DEVICE + int tls_device_init(void); + void tls_device_cleanup(void); +diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c +index a7cc4f9faac28..bf69c9d6d06c0 100644 +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -1007,20 +1007,14 @@ int tls_device_decrypted(struct sock *sk, struct tls_context *tls_ctx) + struct tls_sw_context_rx *sw_ctx = tls_sw_ctx_rx(tls_ctx); + struct sk_buff *skb = tls_strp_msg(sw_ctx); + struct strp_msg *rxm = strp_msg(skb); +- int is_decrypted = skb->decrypted; +- int is_encrypted = !is_decrypted; +- struct sk_buff *skb_iter; +- int left; +- +- left = rxm->full_len - skb->len; +- /* Check if all the data is decrypted already */ +- skb_iter = skb_shinfo(skb)->frag_list; +- while (skb_iter && left > 0) { +- is_decrypted &= skb_iter->decrypted; +- is_encrypted &= !skb_iter->decrypted; +- +- left -= skb_iter->len; +- skb_iter = skb_iter->next; ++ int is_decrypted, is_encrypted; ++ ++ if (!tls_strp_msg_mixed_decrypted(sw_ctx)) { ++ is_decrypted = skb->decrypted; ++ is_encrypted = !is_decrypted; ++ } else { ++ is_decrypted = 0; ++ is_encrypted = 0; + } + + trace_tls_device_decrypted(sk, tcp_sk(sk)->copied_seq - rxm->full_len, +diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c +index 955ac3e0bf4d3..da95abbb7ea32 100644 +--- a/net/tls/tls_strp.c ++++ b/net/tls/tls_strp.c +@@ -29,34 +29,50 @@ static void tls_strp_anchor_free(struct tls_strparser *strp) + struct skb_shared_info *shinfo = skb_shinfo(strp->anchor); + + DEBUG_NET_WARN_ON_ONCE(atomic_read(&shinfo->dataref) != 1); +- shinfo->frag_list = NULL; ++ if (!strp->copy_mode) ++ shinfo->frag_list = NULL; + consume_skb(strp->anchor); + strp->anchor = NULL; + } + +-/* Create a new skb with the contents of input copied to its page frags */ +-static struct sk_buff *tls_strp_msg_make_copy(struct tls_strparser *strp) ++static struct sk_buff * ++tls_strp_skb_copy(struct tls_strparser *strp, struct sk_buff *in_skb, ++ int offset, int len) + { +- struct strp_msg *rxm; + struct sk_buff *skb; +- int i, err, offset; ++ int i, err; + +- skb = alloc_skb_with_frags(0, strp->stm.full_len, TLS_PAGE_ORDER, ++ skb = alloc_skb_with_frags(0, len, TLS_PAGE_ORDER, + &err, strp->sk->sk_allocation); + if (!skb) + return NULL; + +- offset = strp->stm.offset; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + +- WARN_ON_ONCE(skb_copy_bits(strp->anchor, offset, ++ WARN_ON_ONCE(skb_copy_bits(in_skb, offset, + skb_frag_address(frag), + skb_frag_size(frag))); + offset += skb_frag_size(frag); + } + +- skb_copy_header(skb, strp->anchor); ++ skb->len = len; ++ skb->data_len = len; ++ skb_copy_header(skb, in_skb); ++ return skb; ++} ++ ++/* Create a new skb with the contents of input copied to its page frags */ ++static struct sk_buff *tls_strp_msg_make_copy(struct tls_strparser *strp) ++{ ++ struct strp_msg *rxm; ++ struct sk_buff *skb; ++ ++ skb = tls_strp_skb_copy(strp, strp->anchor, strp->stm.offset, ++ strp->stm.full_len); ++ if (!skb) ++ return NULL; ++ + rxm = strp_msg(skb); + rxm->offset = 0; + return skb; +@@ -180,22 +196,22 @@ static void tls_strp_flush_anchor_copy(struct tls_strparser *strp) + for (i = 0; i < shinfo->nr_frags; i++) + __skb_frag_unref(&shinfo->frags[i], false); + shinfo->nr_frags = 0; ++ if (strp->copy_mode) { ++ kfree_skb_list(shinfo->frag_list); ++ shinfo->frag_list = NULL; ++ } + strp->copy_mode = 0; ++ strp->mixed_decrypted = 0; + } + +-static int tls_strp_copyin(read_descriptor_t *desc, struct sk_buff *in_skb, +- unsigned int offset, size_t in_len) ++static int tls_strp_copyin_frag(struct tls_strparser *strp, struct sk_buff *skb, ++ struct sk_buff *in_skb, unsigned int offset, ++ size_t in_len) + { +- struct tls_strparser *strp = (struct tls_strparser *)desc->arg.data; +- struct sk_buff *skb; +- skb_frag_t *frag; + size_t len, chunk; ++ skb_frag_t *frag; + int sz; + +- if (strp->msg_ready) +- return 0; +- +- skb = strp->anchor; + frag = &skb_shinfo(skb)->frags[skb->len / PAGE_SIZE]; + + len = in_len; +@@ -208,19 +224,26 @@ static int tls_strp_copyin(read_descriptor_t *desc, struct sk_buff *in_skb, + skb_frag_size(frag), + chunk)); + +- sz = tls_rx_msg_size(strp, strp->anchor); +- if (sz < 0) { +- desc->error = sz; +- return 0; +- } +- +- /* We may have over-read, sz == 0 is guaranteed under-read */ +- if (sz > 0) +- chunk = min_t(size_t, chunk, sz - skb->len); +- + skb->len += chunk; + skb->data_len += chunk; + skb_frag_size_add(frag, chunk); ++ ++ sz = tls_rx_msg_size(strp, skb); ++ if (sz < 0) ++ return sz; ++ ++ /* We may have over-read, sz == 0 is guaranteed under-read */ ++ if (unlikely(sz && sz < skb->len)) { ++ int over = skb->len - sz; ++ ++ WARN_ON_ONCE(over > chunk); ++ skb->len -= over; ++ skb->data_len -= over; ++ skb_frag_size_add(frag, -over); ++ ++ chunk -= over; ++ } ++ + frag++; + len -= chunk; + offset += chunk; +@@ -247,15 +270,99 @@ static int tls_strp_copyin(read_descriptor_t *desc, struct sk_buff *in_skb, + offset += chunk; + } + +- if (strp->stm.full_len == skb->len) { ++read_done: ++ return in_len - len; ++} ++ ++static int tls_strp_copyin_skb(struct tls_strparser *strp, struct sk_buff *skb, ++ struct sk_buff *in_skb, unsigned int offset, ++ size_t in_len) ++{ ++ struct sk_buff *nskb, *first, *last; ++ struct skb_shared_info *shinfo; ++ size_t chunk; ++ int sz; ++ ++ if (strp->stm.full_len) ++ chunk = strp->stm.full_len - skb->len; ++ else ++ chunk = TLS_MAX_PAYLOAD_SIZE + PAGE_SIZE; ++ chunk = min(chunk, in_len); ++ ++ nskb = tls_strp_skb_copy(strp, in_skb, offset, chunk); ++ if (!nskb) ++ return -ENOMEM; ++ ++ shinfo = skb_shinfo(skb); ++ if (!shinfo->frag_list) { ++ shinfo->frag_list = nskb; ++ nskb->prev = nskb; ++ } else { ++ first = shinfo->frag_list; ++ last = first->prev; ++ last->next = nskb; ++ first->prev = nskb; ++ } ++ ++ skb->len += chunk; ++ skb->data_len += chunk; ++ ++ if (!strp->stm.full_len) { ++ sz = tls_rx_msg_size(strp, skb); ++ if (sz < 0) ++ return sz; ++ ++ /* We may have over-read, sz == 0 is guaranteed under-read */ ++ if (unlikely(sz && sz < skb->len)) { ++ int over = skb->len - sz; ++ ++ WARN_ON_ONCE(over > chunk); ++ skb->len -= over; ++ skb->data_len -= over; ++ __pskb_trim(nskb, nskb->len - over); ++ ++ chunk -= over; ++ } ++ ++ strp->stm.full_len = sz; ++ } ++ ++ return chunk; ++} ++ ++static int tls_strp_copyin(read_descriptor_t *desc, struct sk_buff *in_skb, ++ unsigned int offset, size_t in_len) ++{ ++ struct tls_strparser *strp = (struct tls_strparser *)desc->arg.data; ++ struct sk_buff *skb; ++ int ret; ++ ++ if (strp->msg_ready) ++ return 0; ++ ++ skb = strp->anchor; ++ if (!skb->len) ++ skb_copy_decrypted(skb, in_skb); ++ else ++ strp->mixed_decrypted |= !!skb_cmp_decrypted(skb, in_skb); ++ ++ if (IS_ENABLED(CONFIG_TLS_DEVICE) && strp->mixed_decrypted) ++ ret = tls_strp_copyin_skb(strp, skb, in_skb, offset, in_len); ++ else ++ ret = tls_strp_copyin_frag(strp, skb, in_skb, offset, in_len); ++ if (ret < 0) { ++ desc->error = ret; ++ ret = 0; ++ } ++ ++ if (strp->stm.full_len && strp->stm.full_len == skb->len) { + desc->count = 0; + + strp->msg_ready = 1; + tls_rx_msg_ready(strp); + } + +-read_done: +- return in_len - len; ++ return ret; + } + + static int tls_strp_read_copyin(struct tls_strparser *strp) +@@ -315,15 +422,19 @@ static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort) + return 0; + } + +-static bool tls_strp_check_no_dup(struct tls_strparser *strp) ++static bool tls_strp_check_queue_ok(struct tls_strparser *strp) + { + unsigned int len = strp->stm.offset + strp->stm.full_len; +- struct sk_buff *skb; ++ struct sk_buff *first, *skb; + u32 seq; + +- skb = skb_shinfo(strp->anchor)->frag_list; +- seq = TCP_SKB_CB(skb)->seq; ++ first = skb_shinfo(strp->anchor)->frag_list; ++ skb = first; ++ seq = TCP_SKB_CB(first)->seq; + ++ /* Make sure there's no duplicate data in the queue, ++ * and the decrypted status matches. ++ */ + while (skb->len < len) { + seq += skb->len; + len -= skb->len; +@@ -331,6 +442,8 @@ static bool tls_strp_check_no_dup(struct tls_strparser *strp) + + if (TCP_SKB_CB(skb)->seq != seq) + return false; ++ if (skb_cmp_decrypted(first, skb)) ++ return false; + } + + return true; +@@ -411,7 +524,7 @@ static int tls_strp_read_sock(struct tls_strparser *strp) + return tls_strp_read_copy(strp, true); + } + +- if (!tls_strp_check_no_dup(strp)) ++ if (!tls_strp_check_queue_ok(strp)) + return tls_strp_read_copy(strp, false); + + strp->msg_ready = 1; +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index 635b8bf6b937c..6e6a7c37d685c 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -2304,10 +2304,14 @@ static void tls_data_ready(struct sock *sk) + struct tls_context *tls_ctx = tls_get_ctx(sk); + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx); + struct sk_psock *psock; ++ gfp_t alloc_save; + + trace_sk_data_ready(sk); + ++ alloc_save = sk->sk_allocation; ++ sk->sk_allocation = GFP_ATOMIC; + tls_strp_data_ready(&ctx->strp); ++ sk->sk_allocation = alloc_save; + + psock = sk_psock_get(sk); + if (psock) { +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 29c6083a37daf..9383afe3e570b 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2553,7 +2553,7 @@ static int unix_read_skb(struct sock *sk, skb_read_actor_t recv_actor) + { + struct unix_sock *u = unix_sk(sk); + struct sk_buff *skb; +- int err, copied; ++ int err; + + mutex_lock(&u->iolock); + skb = skb_recv_datagram(sk, MSG_DONTWAIT, &err); +@@ -2561,10 +2561,7 @@ static int unix_read_skb(struct sock *sk, skb_read_actor_t recv_actor) + if (!skb) + return err; + +- copied = recv_actor(sk, skb); +- kfree_skb(skb); +- +- return copied; ++ return recv_actor(sk, skb); + } + + /* +diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c +index a8b14b784f8a5..3dfa2e9816db0 100644 +--- a/sound/soc/intel/avs/control.c ++++ b/sound/soc/intel/avs/control.c +@@ -21,17 +21,25 @@ static struct avs_dev *avs_get_kcontrol_adev(struct snd_kcontrol *kcontrol) + return to_avs_dev(w->dapm->component->dev); + } + +-static struct avs_path_module *avs_get_kcontrol_module(struct avs_dev *adev, u32 id) ++static struct avs_path_module *avs_get_volume_module(struct avs_dev *adev, u32 id) + { + struct avs_path *path; + struct avs_path_pipeline *ppl; + struct avs_path_module *mod; + +- list_for_each_entry(path, &adev->path_list, node) +- list_for_each_entry(ppl, &path->ppl_list, node) +- list_for_each_entry(mod, &ppl->mod_list, node) +- if (mod->template->ctl_id && mod->template->ctl_id == id) ++ spin_lock(&adev->path_list_lock); ++ list_for_each_entry(path, &adev->path_list, node) { ++ list_for_each_entry(ppl, &path->ppl_list, node) { ++ list_for_each_entry(mod, &ppl->mod_list, node) { ++ if (guid_equal(&mod->template->cfg_ext->type, &AVS_PEAKVOL_MOD_UUID) ++ && mod->template->ctl_id == id) { ++ spin_unlock(&adev->path_list_lock); + return mod; ++ } ++ } ++ } ++ } ++ spin_unlock(&adev->path_list_lock); + + return NULL; + } +@@ -49,7 +57,7 @@ int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va + /* prevent access to modules while path is being constructed */ + mutex_lock(&adev->path_mutex); + +- active_module = avs_get_kcontrol_module(adev, ctl_data->id); ++ active_module = avs_get_volume_module(adev, ctl_data->id); + if (active_module) { + ret = avs_ipc_peakvol_get_volume(adev, active_module->module_id, + active_module->instance_id, &dspvols, +@@ -89,7 +97,7 @@ int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va + changed = 1; + } + +- active_module = avs_get_kcontrol_module(adev, ctl_data->id); ++ active_module = avs_get_volume_module(adev, ctl_data->id); + if (active_module) { + dspvol.channel_id = AVS_ALL_CHANNELS_MASK; + dspvol.target_volume = *volume; +diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile +index b677dcd0b77af..ad01c9e1ff12b 100644 +--- a/tools/testing/selftests/bpf/Makefile ++++ b/tools/testing/selftests/bpf/Makefile +@@ -197,7 +197,7 @@ $(OUTPUT)/urandom_read: urandom_read.c urandom_read_aux.c $(OUTPUT)/liburandom_r + + $(OUTPUT)/sign-file: ../../../../scripts/sign-file.c + $(call msg,SIGN-FILE,,$@) +- $(Q)$(CC) $(shell $(HOSTPKG_CONFIG)--cflags libcrypto 2> /dev/null) \ ++ $(Q)$(CC) $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) \ + $< -o $@ \ + $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) +