From fb823a032db3029b701f3aafa391371a92e735c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Pe=C4=8Dovnik?= Date: Sat, 12 Jun 2021 10:06:37 +0200 Subject: [PATCH] Patches adjustments for Jetson, XU4 and Meson64 legacy (#2895) * Move Jetson patches to right location, add upstream patch Also add upstream patch for sunxi * Add upstream patches for Odroidxu4 current * Add meson64 upstream patches --- config/kernel/linux-jetson-nano-legacy.config | 3 +- config/kernel/linux-meson64-legacy.config | 2 +- config/kernel/linux-odroidxu4-current.config | 2 +- .../jetson-nano-4.9}/packages-legacy.patch | 0 .../jetson-nano-4.9/patch-4.9.140-141.patch | 1182 +++ .../meson64-4.9/patch-4.9.270-271.patch | 2522 ++++++ .../meson64-4.9/patch-4.9.271-272.patch | 925 +++ .../odroidxu4-5.4/patch-5.4.123-124.patch | 5657 ++++++++++++++ .../odroidxu4-5.4/patch-5.4.124-125.patch | 3019 ++++++++ .../archive/sunxi-5.12/patch-5.12.9-10.patch | 6796 +++++++++++++++++ patch/kernel/jetson-nano-legacy | 1 + 11 files changed, 20106 insertions(+), 3 deletions(-) rename patch/kernel/{jetson-nano-legacy => archive/jetson-nano-4.9}/packages-legacy.patch (100%) create mode 100644 patch/kernel/archive/jetson-nano-4.9/patch-4.9.140-141.patch create mode 100644 patch/kernel/archive/meson64-4.9/patch-4.9.270-271.patch create mode 100644 patch/kernel/archive/meson64-4.9/patch-4.9.271-272.patch create mode 100644 patch/kernel/archive/odroidxu4-5.4/patch-5.4.123-124.patch create mode 100644 patch/kernel/archive/odroidxu4-5.4/patch-5.4.124-125.patch create mode 100644 patch/kernel/archive/sunxi-5.12/patch-5.12.9-10.patch create mode 120000 patch/kernel/jetson-nano-legacy diff --git a/config/kernel/linux-jetson-nano-legacy.config b/config/kernel/linux-jetson-nano-legacy.config index 21e0f12f9f..8a65339dfe 100644 --- a/config/kernel/linux-jetson-nano-legacy.config +++ b/config/kernel/linux-jetson-nano-legacy.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 4.9.140 Kernel Configuration +# Linux/arm64 4.9.141 Kernel Configuration # CONFIG_ARM64=y CONFIG_64BIT=y @@ -1278,6 +1278,7 @@ CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y CONFIG_BT_HCIUART_INTEL=y CONFIG_BT_HCIUART_BCM=y CONFIG_BT_HCIUART_QCA=y diff --git a/config/kernel/linux-meson64-legacy.config b/config/kernel/linux-meson64-legacy.config index b43539ac4b..afd6119594 100644 --- a/config/kernel/linux-meson64-legacy.config +++ b/config/kernel/linux-meson64-legacy.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 4.9.260 Kernel Configuration +# Linux/arm64 4.9.272 Kernel Configuration # CONFIG_ARM64=y CONFIG_64BIT=y diff --git a/config/kernel/linux-odroidxu4-current.config b/config/kernel/linux-odroidxu4-current.config index e63ed62eda..ff854f233d 100644 --- a/config/kernel/linux-odroidxu4-current.config +++ b/config/kernel/linux-odroidxu4-current.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 5.4.121 Kernel Configuration +# Linux/arm 5.4.125 Kernel Configuration # # diff --git a/patch/kernel/jetson-nano-legacy/packages-legacy.patch b/patch/kernel/archive/jetson-nano-4.9/packages-legacy.patch similarity index 100% rename from patch/kernel/jetson-nano-legacy/packages-legacy.patch rename to patch/kernel/archive/jetson-nano-4.9/packages-legacy.patch diff --git a/patch/kernel/archive/jetson-nano-4.9/patch-4.9.140-141.patch b/patch/kernel/archive/jetson-nano-4.9/patch-4.9.140-141.patch new file mode 100644 index 0000000000..4c2356f1b2 --- /dev/null +++ b/patch/kernel/archive/jetson-nano-4.9/patch-4.9.140-141.patch @@ -0,0 +1,1182 @@ +diff --git a/Makefile b/Makefile +index a9aed2326233..8eba73521a7f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 9 +-SUBLEVEL = 140 ++SUBLEVEL = 141 + EXTRAVERSION = + NAME = Roaring Lionus + +diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h +index 0d551576eb57..4724b8f0b625 100644 +--- a/arch/arm64/include/asm/percpu.h ++++ b/arch/arm64/include/asm/percpu.h +@@ -92,6 +92,7 @@ static inline unsigned long __percpu_##op(void *ptr, \ + : [val] "Ir" (val)); \ + break; \ + default: \ ++ ret = 0; \ + BUILD_BUG(); \ + } \ + \ +@@ -121,6 +122,7 @@ static inline unsigned long __percpu_read(void *ptr, int size) + ret = ACCESS_ONCE(*(u64 *)ptr); + break; + default: ++ ret = 0; + BUILD_BUG(); + } + +@@ -190,6 +192,7 @@ static inline unsigned long __percpu_xchg(void *ptr, unsigned long val, + : [val] "r" (val)); + break; + default: ++ ret = 0; + BUILD_BUG(); + } + +diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c +index 23025d645160..0a99d4515065 100644 +--- a/arch/um/os-Linux/skas/process.c ++++ b/arch/um/os-Linux/skas/process.c +@@ -578,6 +578,11 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) + fatal_sigsegv(); + } + longjmp(*switch_buf, 1); ++ ++ /* unreachable */ ++ printk(UM_KERN_ERR "impossible long jump!"); ++ fatal_sigsegv(); ++ return 0; + } + + void initial_thread_cb_skas(void (*proc)(void *), void *arg) +diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c +index 03250e1f1103..d92eacaef231 100644 +--- a/drivers/acpi/acpi_platform.c ++++ b/drivers/acpi/acpi_platform.c +@@ -30,6 +30,7 @@ static const struct acpi_device_id forbidden_id_list[] = { + {"PNP0200", 0}, /* AT DMA Controller */ + {"ACPI0009", 0}, /* IOxAPIC */ + {"ACPI000A", 0}, /* IOAPIC */ ++ {"SMB0001", 0}, /* ACPI SMBUS virtual device */ + {"", 0}, + }; + +diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c +index ce8fc680785b..396e358c2cee 100644 +--- a/drivers/acpi/acpi_watchdog.c ++++ b/drivers/acpi/acpi_watchdog.c +@@ -17,18 +17,77 @@ + + #include "internal.h" + ++#ifdef CONFIG_RTC_MC146818_LIB ++#include ++ ++/* ++ * There are several systems where the WDAT table is accessing RTC SRAM to ++ * store persistent information. This does not work well with the Linux RTC ++ * driver so on those systems we skip WDAT driver and prefer iTCO_wdt ++ * instead. ++ * ++ * See also https://bugzilla.kernel.org/show_bug.cgi?id=199033. ++ */ ++static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) ++{ ++ const struct acpi_wdat_entry *entries; ++ int i; ++ ++ entries = (struct acpi_wdat_entry *)(wdat + 1); ++ for (i = 0; i < wdat->entries; i++) { ++ const struct acpi_generic_address *gas; ++ ++ gas = &entries[i].register_region; ++ if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { ++ switch (gas->address) { ++ case RTC_PORT(0): ++ case RTC_PORT(1): ++ case RTC_PORT(2): ++ case RTC_PORT(3): ++ return true; ++ } ++ } ++ } ++ ++ return false; ++} ++#else ++static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) ++{ ++ return false; ++} ++#endif ++ ++static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) ++{ ++ const struct acpi_table_wdat *wdat = NULL; ++ acpi_status status; ++ ++ if (acpi_disabled) ++ return NULL; ++ ++ status = acpi_get_table(ACPI_SIG_WDAT, 0, ++ (struct acpi_table_header **)&wdat); ++ if (ACPI_FAILURE(status)) { ++ /* It is fine if there is no WDAT */ ++ return NULL; ++ } ++ ++ if (acpi_watchdog_uses_rtc(wdat)) { ++ pr_info("Skipping WDAT on this system because it uses RTC SRAM\n"); ++ return NULL; ++ } ++ ++ return wdat; ++} ++ + /** + * Returns true if this system should prefer ACPI based watchdog instead of + * the native one (which are typically the same hardware). + */ + bool acpi_has_watchdog(void) + { +- struct acpi_table_header hdr; +- +- if (acpi_disabled) +- return false; +- +- return ACPI_SUCCESS(acpi_get_table_header(ACPI_SIG_WDAT, 0, &hdr)); ++ return !!acpi_watchdog_get_wdat(); + } + EXPORT_SYMBOL_GPL(acpi_has_watchdog); + +@@ -41,12 +100,10 @@ void __init acpi_watchdog_init(void) + struct platform_device *pdev; + struct resource *resources; + size_t nresources = 0; +- acpi_status status; + int i; + +- status = acpi_get_table(ACPI_SIG_WDAT, 0, +- (struct acpi_table_header **)&wdat); +- if (ACPI_FAILURE(status)) { ++ wdat = acpi_watchdog_get_wdat(); ++ if (!wdat) { + /* It is fine if there is no WDAT */ + return; + } +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index b7c0b69a02f5..d64a53d3270a 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -1223,6 +1223,11 @@ static struct attribute_group zram_disk_attr_group = { + .attrs = zram_disk_attrs, + }; + ++static const struct attribute_group *zram_disk_attr_groups[] = { ++ &zram_disk_attr_group, ++ NULL, ++}; ++ + /* + * Allocate and initialize new zram device. the function returns + * '>= 0' device_id upon success, and negative value otherwise. +@@ -1303,24 +1308,15 @@ static int zram_add(void) + zram->disk->queue->limits.discard_zeroes_data = 0; + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, zram->disk->queue); + ++ disk_to_dev(zram->disk)->groups = zram_disk_attr_groups; + add_disk(zram->disk); + +- ret = sysfs_create_group(&disk_to_dev(zram->disk)->kobj, +- &zram_disk_attr_group); +- if (ret < 0) { +- pr_err("Error creating sysfs group for device %d\n", +- device_id); +- goto out_free_disk; +- } + strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor)); + zram->meta = NULL; + + pr_info("Added device: %s\n", zram->disk->disk_name); + return device_id; + +-out_free_disk: +- del_gendisk(zram->disk); +- put_disk(zram->disk); + out_free_queue: + blk_cleanup_queue(queue); + out_free_idr: +@@ -1348,16 +1344,6 @@ static int zram_remove(struct zram *zram) + zram->claim = true; + mutex_unlock(&bdev->bd_mutex); + +- /* +- * Remove sysfs first, so no one will perform a disksize +- * store while we destroy the devices. This also helps during +- * hot_remove -- zram_reset_device() is the last holder of +- * ->init_lock, no later/concurrent disksize_store() or any +- * other sysfs handlers are possible. +- */ +- sysfs_remove_group(&disk_to_dev(zram->disk)->kobj, +- &zram_disk_attr_group); +- + /* Make sure all the pending I/O are finished */ + fsync_bdev(bdev); + zram_reset_device(zram); +diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig +index 4a9493a4159f..3cc9bff9d99d 100644 +--- a/drivers/bluetooth/Kconfig ++++ b/drivers/bluetooth/Kconfig +@@ -125,7 +125,6 @@ config BT_HCIUART_LL + config BT_HCIUART_3WIRE + bool "Three-wire UART (H5) protocol support" + depends on BT_HCIUART +- depends on BT_HCIUART_SERDEV + help + The HCI Three-wire UART Transport Layer makes it possible to + user the Bluetooth HCI over a serial port interface. The HCI +diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c +index 20724abd38bd..7df6b5b1e7ee 100644 +--- a/drivers/clk/clk-fixed-factor.c ++++ b/drivers/clk/clk-fixed-factor.c +@@ -210,6 +210,7 @@ static int of_fixed_factor_clk_remove(struct platform_device *pdev) + { + struct clk *clk = platform_get_drvdata(pdev); + ++ of_clk_del_provider(pdev->dev.of_node); + clk_unregister_fixed_factor(clk); + + return 0; +diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c +index b5c46b3f8764..6d6475c32ee5 100644 +--- a/drivers/clk/clk-fixed-rate.c ++++ b/drivers/clk/clk-fixed-rate.c +@@ -200,6 +200,7 @@ static int of_fixed_clk_remove(struct platform_device *pdev) + { + struct clk *clk = platform_get_drvdata(pdev); + ++ of_clk_del_provider(pdev->dev.of_node); + clk_unregister_fixed_rate(clk); + + return 0; +diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c +index 07fb667e258f..13c09a740840 100644 +--- a/drivers/clk/samsung/clk-exynos5420.c ++++ b/drivers/clk/samsung/clk-exynos5420.c +@@ -280,6 +280,7 @@ static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = { + { .offset = GATE_BUS_TOP, .value = 0xffffffff, }, + { .offset = GATE_BUS_DISP1, .value = 0xffffffff, }, + { .offset = GATE_IP_PERIC, .value = 0xffffffff, }, ++ { .offset = GATE_IP_PERIS, .value = 0xffffffff, }, + }; + + static int exynos5420_clk_suspend(void) +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index 83d2f43b5a2f..c93dcfedc219 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -116,6 +116,9 @@ static const struct edid_quirk { + /* SDC panel of Lenovo B50-80 reports 8 bpc, but is a 6 bpc panel */ + { "SDC", 0x3652, EDID_QUIRK_FORCE_6BPC }, + ++ /* BOE model 0x0771 reports 8 bpc, but is a 6 bpc panel */ ++ { "BOE", 0x0771, EDID_QUIRK_FORCE_6BPC }, ++ + /* Belinea 10 15 55 */ + { "MAX", 1516, EDID_QUIRK_PREFER_LARGE_60 }, + { "MAX", 0x77e, EDID_QUIRK_PREFER_LARGE_60 }, +diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c +index 7f8ff39ed44b..d02ee5304217 100644 +--- a/drivers/hid/uhid.c ++++ b/drivers/hid/uhid.c +@@ -12,6 +12,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -24,6 +25,7 @@ + #include + #include + #include ++#include + + #define UHID_NAME "uhid" + #define UHID_BUFSIZE 32 +@@ -721,6 +723,17 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer, + + switch (uhid->input_buf.type) { + case UHID_CREATE: ++ /* ++ * 'struct uhid_create_req' contains a __user pointer which is ++ * copied from, so it's unsafe to allow this with elevated ++ * privileges (e.g. from a setuid binary) or via kernel_write(). ++ */ ++ if (file->f_cred != current_cred() || uaccess_kernel()) { ++ pr_err_once("UHID_CREATE from different security context by process %d (%s), this is not allowed.\n", ++ task_tgid_vnr(current), current->comm); ++ ret = -EACCES; ++ goto unlock; ++ } + ret = uhid_dev_create(uhid, &uhid->input_buf); + break; + case UHID_CREATE2: +diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c +index 6d2e6605751c..18b3c8f258bf 100644 +--- a/drivers/hwmon/ibmpowernv.c ++++ b/drivers/hwmon/ibmpowernv.c +@@ -114,7 +114,7 @@ static ssize_t show_label(struct device *dev, struct device_attribute *devattr, + return sprintf(buf, "%s\n", sdata->label); + } + +-static int __init get_logical_cpu(int hwcpu) ++static int get_logical_cpu(int hwcpu) + { + int cpu; + +@@ -125,9 +125,8 @@ static int __init get_logical_cpu(int hwcpu) + return -ENOENT; + } + +-static void __init make_sensor_label(struct device_node *np, +- struct sensor_data *sdata, +- const char *label) ++static void make_sensor_label(struct device_node *np, ++ struct sensor_data *sdata, const char *label) + { + u32 id; + size_t n; +diff --git a/drivers/misc/sgi-gru/grukdump.c b/drivers/misc/sgi-gru/grukdump.c +index 313da3150262..1540a7785e14 100644 +--- a/drivers/misc/sgi-gru/grukdump.c ++++ b/drivers/misc/sgi-gru/grukdump.c +@@ -27,6 +27,9 @@ + #include + #include + #include ++ ++#include ++ + #include "gru.h" + #include "grutables.h" + #include "gruhandles.h" +@@ -196,6 +199,7 @@ int gru_dump_chiplet_request(unsigned long arg) + /* Currently, only dump by gid is implemented */ + if (req.gid >= gru_max_gids) + return -EINVAL; ++ req.gid = array_index_nospec(req.gid, gru_max_gids); + + gru = GID_TO_GRU(req.gid); + ubuf = req.buf; +diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp.h b/drivers/net/ethernet/qlogic/qed/qed_sp.h +index b2c08e4d2a9b..bae7b7f9b1cf 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_sp.h ++++ b/drivers/net/ethernet/qlogic/qed/qed_sp.h +@@ -132,6 +132,9 @@ struct qed_spq_entry { + enum spq_mode comp_mode; + struct qed_spq_comp_cb comp_cb; + struct qed_spq_comp_done comp_done; /* SPQ_MODE_EBLOCK */ ++ ++ /* Posted entry for unlimited list entry in EBLOCK mode */ ++ struct qed_spq_entry *post_ent; + }; + + struct qed_eq { +diff --git a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c +index 2888eb0628f8..ac69ff3f7c5c 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_sp_commands.c +@@ -56,7 +56,7 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn, + + case QED_SPQ_MODE_BLOCK: + if (!p_data->p_comp_data) +- return -EINVAL; ++ goto err; + + p_ent->comp_cb.cookie = p_data->p_comp_data->cookie; + break; +@@ -71,7 +71,7 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn, + default: + DP_NOTICE(p_hwfn, "Unknown SPQE completion mode %d\n", + p_ent->comp_mode); +- return -EINVAL; ++ goto err; + } + + DP_VERBOSE(p_hwfn, QED_MSG_SPQ, +@@ -85,6 +85,18 @@ int qed_sp_init_request(struct qed_hwfn *p_hwfn, + memset(&p_ent->ramrod, 0, sizeof(p_ent->ramrod)); + + return 0; ++ ++err: ++ /* qed_spq_get_entry() can either get an entry from the free_pool, ++ * or, if no entries are left, allocate a new entry and add it to ++ * the unlimited_pending list. ++ */ ++ if (p_ent->queue == &p_hwfn->p_spq->unlimited_pending) ++ kfree(p_ent); ++ else ++ qed_spq_return_entry(p_hwfn, p_ent); ++ ++ return -EINVAL; + } + + static enum tunnel_clss qed_tunn_get_clss_type(u8 type) +diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c +index 9fbaf9429fd0..80c8c7f0d932 100644 +--- a/drivers/net/ethernet/qlogic/qed/qed_spq.c ++++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c +@@ -595,6 +595,8 @@ static int qed_spq_add_entry(struct qed_hwfn *p_hwfn, + /* EBLOCK responsible to free the allocated p_ent */ + if (p_ent->comp_mode != QED_SPQ_MODE_EBLOCK) + kfree(p_ent); ++ else ++ p_ent->post_ent = p_en2; + + p_ent = p_en2; + } +@@ -678,6 +680,25 @@ static int qed_spq_pend_post(struct qed_hwfn *p_hwfn) + SPQ_HIGH_PRI_RESERVE_DEFAULT); + } + ++/* Avoid overriding of SPQ entries when getting out-of-order completions, by ++ * marking the completions in a bitmap and increasing the chain consumer only ++ * for the first successive completed entries. ++ */ ++static void qed_spq_comp_bmap_update(struct qed_hwfn *p_hwfn, __le16 echo) ++{ ++ u16 pos = le16_to_cpu(echo) % SPQ_RING_SIZE; ++ struct qed_spq *p_spq = p_hwfn->p_spq; ++ ++ __set_bit(pos, p_spq->p_comp_bitmap); ++ while (test_bit(p_spq->comp_bitmap_idx, ++ p_spq->p_comp_bitmap)) { ++ __clear_bit(p_spq->comp_bitmap_idx, ++ p_spq->p_comp_bitmap); ++ p_spq->comp_bitmap_idx++; ++ qed_chain_return_produced(&p_spq->chain); ++ } ++} ++ + int qed_spq_post(struct qed_hwfn *p_hwfn, + struct qed_spq_entry *p_ent, u8 *fw_return_code) + { +@@ -728,11 +749,12 @@ int qed_spq_post(struct qed_hwfn *p_hwfn, + rc = qed_spq_block(p_hwfn, p_ent, fw_return_code); + + if (p_ent->queue == &p_spq->unlimited_pending) { +- /* This is an allocated p_ent which does not need to +- * return to pool. +- */ ++ struct qed_spq_entry *p_post_ent = p_ent->post_ent; ++ + kfree(p_ent); +- return rc; ++ ++ /* Return the entry which was actually posted */ ++ p_ent = p_post_ent; + } + + if (rc) +@@ -746,7 +768,7 @@ int qed_spq_post(struct qed_hwfn *p_hwfn, + spq_post_fail2: + spin_lock_bh(&p_spq->lock); + list_del(&p_ent->list); +- qed_chain_return_produced(&p_spq->chain); ++ qed_spq_comp_bmap_update(p_hwfn, p_ent->elem.hdr.echo); + + spq_post_fail: + /* return to the free pool */ +@@ -778,25 +800,8 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn, + spin_lock_bh(&p_spq->lock); + list_for_each_entry_safe(p_ent, tmp, &p_spq->completion_pending, list) { + if (p_ent->elem.hdr.echo == echo) { +- u16 pos = le16_to_cpu(echo) % SPQ_RING_SIZE; +- + list_del(&p_ent->list); +- +- /* Avoid overriding of SPQ entries when getting +- * out-of-order completions, by marking the completions +- * in a bitmap and increasing the chain consumer only +- * for the first successive completed entries. +- */ +- __set_bit(pos, p_spq->p_comp_bitmap); +- +- while (test_bit(p_spq->comp_bitmap_idx, +- p_spq->p_comp_bitmap)) { +- __clear_bit(p_spq->comp_bitmap_idx, +- p_spq->p_comp_bitmap); +- p_spq->comp_bitmap_idx++; +- qed_chain_return_produced(&p_spq->chain); +- } +- ++ qed_spq_comp_bmap_update(p_hwfn, echo); + p_spq->comp_count++; + found = p_ent; + break; +@@ -835,11 +840,9 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn, + QED_MSG_SPQ, + "Got a completion without a callback function\n"); + +- if ((found->comp_mode != QED_SPQ_MODE_EBLOCK) || +- (found->queue == &p_spq->unlimited_pending)) ++ if (found->comp_mode != QED_SPQ_MODE_EBLOCK) + /* EBLOCK is responsible for returning its own entry into the +- * free list, unless it originally added the entry into the +- * unlimited pending list. ++ * free list. + */ + qed_spq_return_entry(p_hwfn, found); + +diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c +index 2acdb0d6ea89..a0533e4e52d7 100644 +--- a/drivers/platform/x86/acerhdf.c ++++ b/drivers/platform/x86/acerhdf.c +@@ -233,6 +233,7 @@ static const struct bios_settings bios_tbl[] = { + {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0}, ++ {"Gateway", "LT31", "v1.3307", 0x55, 0x58, {0x9e, 0x00}, 0}, + /* Packard Bell */ + {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00}, 0}, + {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0}, +diff --git a/drivers/platform/x86/intel_telemetry_debugfs.c b/drivers/platform/x86/intel_telemetry_debugfs.c +index ef29f18b1951..4069433a0ec6 100644 +--- a/drivers/platform/x86/intel_telemetry_debugfs.c ++++ b/drivers/platform/x86/intel_telemetry_debugfs.c +@@ -953,12 +953,16 @@ static int __init telemetry_debugfs_init(void) + debugfs_conf = (struct telemetry_debugfs_conf *)id->driver_data; + + err = telemetry_pltconfig_valid(); +- if (err < 0) ++ if (err < 0) { ++ pr_info("Invalid pltconfig, ensure IPC1 device is enabled in BIOS\n"); + return -ENODEV; ++ } + + err = telemetry_debugfs_check_evts(); +- if (err < 0) ++ if (err < 0) { ++ pr_info("telemetry_debugfs_check_evts failed\n"); + return -EINVAL; ++ } + + + #ifdef CONFIG_PM_SLEEP +diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c +index efefe075557f..6e6ba1baf9c4 100644 +--- a/drivers/s390/net/qeth_l3_main.c ++++ b/drivers/s390/net/qeth_l3_main.c +@@ -363,9 +363,6 @@ static void qeth_l3_clear_ip_htable(struct qeth_card *card, int recover) + + QETH_CARD_TEXT(card, 4, "clearip"); + +- if (recover && card->options.sniffer) +- return; +- + spin_lock_bh(&card->ip_lock); + + hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) { +@@ -823,6 +820,8 @@ static int qeth_l3_register_addr_entry(struct qeth_card *card, + int rc = 0; + int cnt = 3; + ++ if (card->options.sniffer) ++ return 0; + + if (addr->proto == QETH_PROT_IPV4) { + QETH_CARD_TEXT(card, 2, "setaddr4"); +@@ -858,6 +857,9 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *card, + { + int rc = 0; + ++ if (card->options.sniffer) ++ return 0; ++ + if (addr->proto == QETH_PROT_IPV4) { + QETH_CARD_TEXT(card, 2, "deladdr4"); + QETH_CARD_HEX(card, 3, &addr->u.a4.addr, sizeof(int)); +diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c +index cfbfef08c94a..e6b20716e8e0 100644 +--- a/drivers/uio/uio.c ++++ b/drivers/uio/uio.c +@@ -850,6 +850,8 @@ int __uio_register_device(struct module *owner, + if (ret) + goto err_uio_dev_add_attributes; + ++ info->uio_dev = idev; ++ + if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) { + /* + * Note that we deliberately don't use devm_request_irq +@@ -861,11 +863,12 @@ int __uio_register_device(struct module *owner, + */ + ret = request_irq(info->irq, uio_interrupt, + info->irq_flags, info->name, idev); +- if (ret) ++ if (ret) { ++ info->uio_dev = NULL; + goto err_request_irq; ++ } + } + +- info->uio_dev = idev; + return 0; + + err_request_irq: +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index dbe44e890c99..cd4f96354fa8 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1659,6 +1659,9 @@ static const struct usb_device_id acm_ids[] = { + { USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, ++ { USB_DEVICE(0x0572, 0x1349), /* Hiro (Conexant) USB MODEM H50228 */ ++ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ ++ }, + { USB_DEVICE(0x20df, 0x0001), /* Simtec Electronics Entropy Key */ + .driver_info = QUIRK_CONTROL_LINE_STATE, }, + { USB_DEVICE(0x2184, 0x001c) }, /* GW Instek AFG-2225 */ +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 37a5e07b3488..1e8f68960014 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -243,6 +243,9 @@ static const struct usb_device_id usb_quirk_list[] = { + { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT | + USB_QUIRK_DELAY_CTRL_MSG }, + ++ /* Corsair K70 LUX RGB */ ++ { USB_DEVICE(0x1b1c, 0x1b33), .driver_info = USB_QUIRK_DELAY_INIT }, ++ + /* Corsair K70 LUX */ + { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT }, + +@@ -263,6 +266,11 @@ static const struct usb_device_id usb_quirk_list[] = { + { USB_DEVICE(0x2040, 0x7200), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, + ++ /* Raydium Touchscreen */ ++ { USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM }, ++ ++ { USB_DEVICE(0x2386, 0x3119), .driver_info = USB_QUIRK_NO_LPM }, ++ + /* DJI CineSSD */ + { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, + +diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c +index da5ff401a354..2d3c656e0bff 100644 +--- a/drivers/usb/misc/appledisplay.c ++++ b/drivers/usb/misc/appledisplay.c +@@ -63,6 +63,7 @@ static const struct usb_device_id appledisplay_table[] = { + { APPLEDISPLAY_DEVICE(0x9219) }, + { APPLEDISPLAY_DEVICE(0x921c) }, + { APPLEDISPLAY_DEVICE(0x921d) }, ++ { APPLEDISPLAY_DEVICE(0x9222) }, + { APPLEDISPLAY_DEVICE(0x9236) }, + + /* Terminating entry */ +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 18d05323ca53..57d375c68e46 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4491,6 +4491,7 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root, + static int btrfs_destroy_pinned_extent(struct btrfs_root *root, + struct extent_io_tree *pinned_extents) + { ++ struct btrfs_fs_info *fs_info = root->fs_info; + struct extent_io_tree *unpin; + u64 start; + u64 end; +@@ -4500,21 +4501,31 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root, + unpin = pinned_extents; + again: + while (1) { ++ /* ++ * The btrfs_finish_extent_commit() may get the same range as ++ * ours between find_first_extent_bit and clear_extent_dirty. ++ * Hence, hold the unused_bg_unpin_mutex to avoid double unpin ++ * the same extent range. ++ */ ++ mutex_lock(&fs_info->unused_bg_unpin_mutex); + ret = find_first_extent_bit(unpin, 0, &start, &end, + EXTENT_DIRTY, NULL); +- if (ret) ++ if (ret) { ++ mutex_unlock(&fs_info->unused_bg_unpin_mutex); + break; ++ } + + clear_extent_dirty(unpin, start, end); + btrfs_error_unpin_extent_range(root, start, end); ++ mutex_unlock(&fs_info->unused_bg_unpin_mutex); + cond_resched(); + } + + if (loop) { +- if (unpin == &root->fs_info->freed_extents[0]) +- unpin = &root->fs_info->freed_extents[1]; ++ if (unpin == &fs_info->freed_extents[0]) ++ unpin = &fs_info->freed_extents[1]; + else +- unpin = &root->fs_info->freed_extents[0]; ++ unpin = &fs_info->freed_extents[0]; + loop = false; + goto again; + } +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 163b61a92b59..a775307f3b6b 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -11140,6 +11140,15 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, + return ret; + } + ++/* ++ * Trim the whole filesystem by: ++ * 1) trimming the free space in each block group ++ * 2) trimming the unallocated space on each device ++ * ++ * This will also continue trimming even if a block group or device encounters ++ * an error. The return value will be the last error, or 0 if nothing bad ++ * happens. ++ */ + int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + { + struct btrfs_fs_info *fs_info = root->fs_info; +@@ -11150,18 +11159,14 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + u64 start; + u64 end; + u64 trimmed = 0; +- u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy); ++ u64 bg_failed = 0; ++ u64 dev_failed = 0; ++ int bg_ret = 0; ++ int dev_ret = 0; + int ret = 0; + +- /* +- * try to trim all FS space, our block group may start from non-zero. +- */ +- if (range->len == total_bytes) +- cache = btrfs_lookup_first_block_group(fs_info, range->start); +- else +- cache = btrfs_lookup_block_group(fs_info, range->start); +- +- while (cache) { ++ cache = btrfs_lookup_first_block_group(fs_info, range->start); ++ for (; cache; cache = next_block_group(fs_info->tree_root, cache)) { + if (cache->key.objectid >= (range->start + range->len)) { + btrfs_put_block_group(cache); + break; +@@ -11175,13 +11180,15 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + if (!block_group_cache_done(cache)) { + ret = cache_block_group(cache, 0); + if (ret) { +- btrfs_put_block_group(cache); +- break; ++ bg_failed++; ++ bg_ret = ret; ++ continue; + } + ret = wait_block_group_cache_done(cache); + if (ret) { +- btrfs_put_block_group(cache); +- break; ++ bg_failed++; ++ bg_ret = ret; ++ continue; + } + } + ret = btrfs_trim_block_group(cache, +@@ -11192,28 +11199,40 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) + + trimmed += group_trimmed; + if (ret) { +- btrfs_put_block_group(cache); +- break; ++ bg_failed++; ++ bg_ret = ret; ++ continue; + } + } +- +- cache = next_block_group(fs_info->tree_root, cache); + } + +- mutex_lock(&root->fs_info->fs_devices->device_list_mutex); +- devices = &root->fs_info->fs_devices->devices; ++ if (bg_failed) ++ btrfs_warn(fs_info, ++ "failed to trim %llu block group(s), last error %d", ++ bg_failed, bg_ret); ++ mutex_lock(&fs_info->fs_devices->device_list_mutex); ++ devices = &fs_info->fs_devices->devices; + list_for_each_entry(device, devices, dev_list) { + ret = btrfs_trim_free_extents(device, range->minlen, + &group_trimmed); +- if (ret) ++ if (ret) { ++ dev_failed++; ++ dev_ret = ret; + break; ++ } + + trimmed += group_trimmed; + } + mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); + ++ if (dev_failed) ++ btrfs_warn(fs_info, ++ "failed to trim %llu device(s), last error %d", ++ dev_failed, dev_ret); + range->len = trimmed; +- return ret; ++ if (bg_ret) ++ return bg_ret; ++ return dev_ret; + } + + /* +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 96ad2778405b..242584a0d3b5 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -380,7 +380,6 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) + struct fstrim_range range; + u64 minlen = ULLONG_MAX; + u64 num_devices = 0; +- u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy); + int ret; + + if (!capable(CAP_SYS_ADMIN)) +@@ -404,11 +403,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) + return -EOPNOTSUPP; + if (copy_from_user(&range, arg, sizeof(range))) + return -EFAULT; +- if (range.start > total_bytes || +- range.len < fs_info->sb->s_blocksize) ++ ++ /* ++ * NOTE: Don't truncate the range using super->total_bytes. Bytenr of ++ * block group is in the logical address space, which can be any ++ * sectorsize aligned bytenr in the range [0, U64_MAX]. ++ */ ++ if (range.len < fs_info->sb->s_blocksize) + return -EINVAL; + +- range.len = min(range.len, total_bytes - range.start); + range.minlen = max(range.minlen, minlen); + ret = btrfs_trim_fs(fs_info->tree_root, &range); + if (ret < 0) +diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c +index 87658f63b374..be84d49f2406 100644 +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -927,8 +927,8 @@ static int cifs_clone_file_range(struct file *src_file, loff_t off, + struct inode *src_inode = file_inode(src_file); + struct inode *target_inode = file_inode(dst_file); + struct cifsFileInfo *smb_file_src = src_file->private_data; +- struct cifsFileInfo *smb_file_target = dst_file->private_data; +- struct cifs_tcon *target_tcon = tlink_tcon(smb_file_target->tlink); ++ struct cifsFileInfo *smb_file_target; ++ struct cifs_tcon *target_tcon; + unsigned int xid; + int rc; + +@@ -942,6 +942,9 @@ static int cifs_clone_file_range(struct file *src_file, loff_t off, + goto out; + } + ++ smb_file_target = dst_file->private_data; ++ target_tcon = tlink_tcon(smb_file_target->tlink); ++ + /* + * Note: cifs case is easier than btrfs since server responsible for + * checks for proper open modes and file type and if it wants +diff --git a/fs/exofs/super.c b/fs/exofs/super.c +index 1076a4233b39..0c48138486dc 100644 +--- a/fs/exofs/super.c ++++ b/fs/exofs/super.c +@@ -100,6 +100,7 @@ static int parse_options(char *options, struct exofs_mountopt *opts) + token = match_token(p, tokens, args); + switch (token) { + case Opt_name: ++ kfree(opts->dev_name); + opts->dev_name = match_strdup(&args[0]); + if (unlikely(!opts->dev_name)) { + EXOFS_ERR("Error allocating dev_name"); +@@ -868,8 +869,10 @@ static struct dentry *exofs_mount(struct file_system_type *type, + int ret; + + ret = parse_options(data, &opts); +- if (ret) ++ if (ret) { ++ kfree(opts.dev_name); + return ERR_PTR(ret); ++ } + + if (!opts.dev_name) + opts.dev_name = dev_name; +diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c +index 832824994aae..073126707270 100644 +--- a/fs/gfs2/rgrp.c ++++ b/fs/gfs2/rgrp.c +@@ -715,6 +715,7 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) + spin_lock(&gl->gl_lockref.lock); + gl->gl_object = NULL; + spin_unlock(&gl->gl_lockref.lock); ++ gfs2_rgrp_brelse(rgd); + gfs2_glock_add_to_lru(gl); + gfs2_glock_put(gl); + } +@@ -1125,7 +1126,7 @@ static u32 count_unlinked(struct gfs2_rgrpd *rgd) + * @rgd: the struct gfs2_rgrpd describing the RG to read in + * + * Read in all of a Resource Group's header and bitmap blocks. +- * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps. ++ * Caller must eventually call gfs2_rgrp_brelse() to free the bitmaps. + * + * Returns: errno + */ +diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c +index 2a6f3c67cb3f..2e713673df42 100644 +--- a/fs/hfs/brec.c ++++ b/fs/hfs/brec.c +@@ -424,6 +424,10 @@ skip: + if (new_node) { + __be32 cnid; + ++ if (!new_node->parent) { ++ hfs_btree_inc_height(tree); ++ new_node->parent = tree->root; ++ } + fd->bnode = hfs_bnode_find(tree, new_node->parent); + /* create index key and entry */ + hfs_bnode_read_key(new_node, fd->search_key, 14); +diff --git a/fs/hfsplus/brec.c b/fs/hfsplus/brec.c +index 754fdf8c6356..1002a0c08319 100644 +--- a/fs/hfsplus/brec.c ++++ b/fs/hfsplus/brec.c +@@ -427,6 +427,10 @@ skip: + if (new_node) { + __be32 cnid; + ++ if (!new_node->parent) { ++ hfs_btree_inc_height(tree); ++ new_node->parent = tree->root; ++ } + fd->bnode = hfs_bnode_find(tree, new_node->parent); + /* create index key and entry */ + hfs_bnode_read_key(new_node, fd->search_key, 14); +diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c +index 06a9fae202a7..9e313fc7fdc7 100644 +--- a/fs/reiserfs/xattr.c ++++ b/fs/reiserfs/xattr.c +@@ -184,6 +184,7 @@ struct reiserfs_dentry_buf { + struct dir_context ctx; + struct dentry *xadir; + int count; ++ int err; + struct dentry *dentries[8]; + }; + +@@ -206,6 +207,7 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen, + + dentry = lookup_one_len(name, dbuf->xadir, namelen); + if (IS_ERR(dentry)) { ++ dbuf->err = PTR_ERR(dentry); + return PTR_ERR(dentry); + } else if (d_really_is_negative(dentry)) { + /* A directory entry exists, but no file? */ +@@ -214,6 +216,7 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen, + "not found for file %pd.\n", + dentry, dbuf->xadir); + dput(dentry); ++ dbuf->err = -EIO; + return -EIO; + } + +@@ -261,6 +264,10 @@ static int reiserfs_for_each_xattr(struct inode *inode, + err = reiserfs_readdir_inode(d_inode(dir), &buf.ctx); + if (err) + break; ++ if (buf.err) { ++ err = buf.err; ++ break; ++ } + if (!buf.count) + break; + for (i = 0; !err && i < buf.count && buf.dentries[i]; i++) { +diff --git a/include/linux/netfilter/ipset/ip_set_comment.h b/include/linux/netfilter/ipset/ip_set_comment.h +index 8d0248525957..9f34204978e4 100644 +--- a/include/linux/netfilter/ipset/ip_set_comment.h ++++ b/include/linux/netfilter/ipset/ip_set_comment.h +@@ -41,11 +41,11 @@ ip_set_init_comment(struct ip_set_comment *comment, + rcu_assign_pointer(comment->c, c); + } + +-/* Used only when dumping a set, protected by rcu_read_lock_bh() */ ++/* Used only when dumping a set, protected by rcu_read_lock() */ + static inline int + ip_set_put_comment(struct sk_buff *skb, struct ip_set_comment *comment) + { +- struct ip_set_comment_rcu *c = rcu_dereference_bh(comment->c); ++ struct ip_set_comment_rcu *c = rcu_dereference(comment->c); + + if (!c) + return 0; +diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h +index f30c187ed785..9442423979c1 100644 +--- a/include/linux/uaccess.h ++++ b/include/linux/uaccess.h +@@ -2,6 +2,9 @@ + #define __LINUX_UACCESS_H__ + + #include ++ ++#define uaccess_kernel() segment_eq(get_fs(), KERNEL_DS) ++ + #include + + static __always_inline void pagefault_disabled_inc(void) +diff --git a/lib/raid6/test/Makefile b/lib/raid6/test/Makefile +index 2c7b60edea04..1faeef0c30b9 100644 +--- a/lib/raid6/test/Makefile ++++ b/lib/raid6/test/Makefile +@@ -26,7 +26,7 @@ ifeq ($(ARCH),arm) + CFLAGS += -I../../../arch/arm/include -mfpu=neon + HAS_NEON = yes + endif +-ifeq ($(ARCH),arm64) ++ifeq ($(ARCH),aarch64) + CFLAGS += -I../../../arch/arm64/include + HAS_NEON = yes + endif +@@ -40,7 +40,7 @@ ifeq ($(IS_X86),yes) + gcc -c -x assembler - >&/dev/null && \ + rm ./-.o && echo -DCONFIG_AS_AVX512=1) + else ifeq ($(HAS_NEON),yes) +- OBJS += neon.o neon1.o neon2.o neon4.o neon8.o ++ OBJS += neon.o neon1.o neon2.o neon4.o neon8.o recov_neon.o recov_neon_inner.o + CFLAGS += -DCONFIG_KERNEL_MODE_NEON=1 + else + HAS_ALTIVEC := $(shell printf '\#include \nvector int a;\n' |\ +diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c +index 98ea28dc03f9..68acf94fae72 100644 +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -588,9 +588,15 @@ static int ceph_tcp_sendpage(struct socket *sock, struct page *page, + int ret; + struct kvec iov; + +- /* sendpage cannot properly handle pages with page_count == 0, +- * we need to fallback to sendmsg if that's the case */ +- if (page_count(page) >= 1) ++ /* ++ * sendpage cannot properly handle pages with page_count == 0, ++ * we need to fall back to sendmsg if that's the case. ++ * ++ * Same goes for slab pages: skb_can_coalesce() allows ++ * coalescing neighboring slab objects into a single frag which ++ * triggers one of hardened usercopy checks. ++ */ ++ if (page_count(page) >= 1 && !PageSlab(page)) + return __ceph_tcp_sendpage(sock, page, offset, size, more); + + iov.iov_base = kmap(page) + offset; +diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c +index 9a14c237830f..b259a5814965 100644 +--- a/net/netfilter/ipset/ip_set_hash_netportnet.c ++++ b/net/netfilter/ipset/ip_set_hash_netportnet.c +@@ -213,13 +213,13 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[], + + if (tb[IPSET_ATTR_CIDR]) { + e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]); +- if (!e.cidr[0] || e.cidr[0] > HOST_MASK) ++ if (e.cidr[0] > HOST_MASK) + return -IPSET_ERR_INVALID_CIDR; + } + + if (tb[IPSET_ATTR_CIDR2]) { + e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]); +- if (!e.cidr[1] || e.cidr[1] > HOST_MASK) ++ if (e.cidr[1] > HOST_MASK) + return -IPSET_ERR_INVALID_CIDR; + } + +@@ -492,13 +492,13 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[], + + if (tb[IPSET_ATTR_CIDR]) { + e.cidr[0] = nla_get_u8(tb[IPSET_ATTR_CIDR]); +- if (!e.cidr[0] || e.cidr[0] > HOST_MASK) ++ if (e.cidr[0] > HOST_MASK) + return -IPSET_ERR_INVALID_CIDR; + } + + if (tb[IPSET_ATTR_CIDR2]) { + e.cidr[1] = nla_get_u8(tb[IPSET_ATTR_CIDR2]); +- if (!e.cidr[1] || e.cidr[1] > HOST_MASK) ++ if (e.cidr[1] > HOST_MASK) + return -IPSET_ERR_INVALID_CIDR; + } + +diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c +index bb5d6a058fb7..921c9bd7e1e7 100644 +--- a/net/netfilter/xt_IDLETIMER.c ++++ b/net/netfilter/xt_IDLETIMER.c +@@ -116,6 +116,22 @@ static void idletimer_tg_expired(unsigned long data) + schedule_work(&timer->work); + } + ++static int idletimer_check_sysfs_name(const char *name, unsigned int size) ++{ ++ int ret; ++ ++ ret = xt_check_proc_name(name, size); ++ if (ret < 0) ++ return ret; ++ ++ if (!strcmp(name, "power") || ++ !strcmp(name, "subsystem") || ++ !strcmp(name, "uevent")) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static int idletimer_tg_create(struct idletimer_tg_info *info) + { + int ret; +@@ -126,6 +142,10 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) + goto out; + } + ++ ret = idletimer_check_sysfs_name(info->label, sizeof(info->label)); ++ if (ret < 0) ++ goto out_free_timer; ++ + sysfs_attr_init(&info->timer->attr.attr); + info->timer->attr.attr.name = kstrdup(info->label, GFP_KERNEL); + if (!info->timer->attr.attr.name) { +diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c +index 1b38fc486351..69846c6574ef 100644 +--- a/net/sunrpc/xdr.c ++++ b/net/sunrpc/xdr.c +@@ -512,7 +512,7 @@ EXPORT_SYMBOL_GPL(xdr_commit_encode); + static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, + size_t nbytes) + { +- static __be32 *p; ++ __be32 *p; + int space_left; + int frag1bytes, frag2bytes; + diff --git a/patch/kernel/archive/meson64-4.9/patch-4.9.270-271.patch b/patch/kernel/archive/meson64-4.9/patch-4.9.270-271.patch new file mode 100644 index 0000000000..9143615ea7 --- /dev/null +++ b/patch/kernel/archive/meson64-4.9/patch-4.9.270-271.patch @@ -0,0 +1,2522 @@ +diff --git a/Documentation/sphinx/parse-headers.pl b/Documentation/sphinx/parse-headers.pl +index db0186a7618f2..299b0f82af27f 100755 +--- a/Documentation/sphinx/parse-headers.pl ++++ b/Documentation/sphinx/parse-headers.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + use strict; + use Text::Tabs; + +diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py +index 94bf6944bb1e4..7e79ff6b09e0e 100755 +--- a/Documentation/target/tcm_mod_builder.py ++++ b/Documentation/target/tcm_mod_builder.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python + # The TCM v4 multi-protocol fabric module generation script for drivers/target/$NEW_MOD + # + # Copyright (c) 2010 Rising Tide Systems +diff --git a/Documentation/trace/postprocess/decode_msr.py b/Documentation/trace/postprocess/decode_msr.py +index 0ab40e0db5809..aa9cc7abd5c2b 100644 +--- a/Documentation/trace/postprocess/decode_msr.py ++++ b/Documentation/trace/postprocess/decode_msr.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python + # add symbolic names to read_msr / write_msr in trace + # decode_msr msr-index.h < trace + import sys +diff --git a/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl b/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl +index 0a120aae33ce5..b9b7d80c2f9d2 100644 +--- a/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl ++++ b/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + # This is a POC (proof of concept or piece of crap, take your pick) for reading the + # text representation of trace output related to page allocation. It makes an attempt + # to extract some high-level information on what is going on. The accuracy of the parser +diff --git a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl +index 8f961ef2b4577..7749cdf372f76 100644 +--- a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl ++++ b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + # This is a POC for reading the text representation of trace output related to + # page reclaim. It makes an attempt to extract some high-level information on + # what is going on. The accuracy of the parser may vary +diff --git a/Makefile b/Makefile +index e8313ffb8af98..4964c2494edb5 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 9 +-SUBLEVEL = 270 ++SUBLEVEL = 271 + EXTRAVERSION = + NAME = Roaring Lionus + +diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py +index 2bfd941ff7c7c..c27849889e193 100644 +--- a/arch/ia64/scripts/unwcheck.py ++++ b/arch/ia64/scripts/unwcheck.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python + # + # Usage: unwcheck.py FILE + # +diff --git a/arch/mips/alchemy/board-xxs1500.c b/arch/mips/alchemy/board-xxs1500.c +index 0fc53e08a894c..c05f7376148a7 100644 +--- a/arch/mips/alchemy/board-xxs1500.c ++++ b/arch/mips/alchemy/board-xxs1500.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + + const char *get_system_type(void) +diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c +index 0aa67a2d0ae6e..6b72268303541 100644 +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -10,6 +10,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -27,6 +28,7 @@ + + __iomem void *rt_sysc_membase; + __iomem void *rt_memc_membase; ++EXPORT_SYMBOL_GPL(rt_sysc_membase); + + __iomem void *plat_of_remap_node(const char *node) + { +diff --git a/arch/openrisc/include/asm/barrier.h b/arch/openrisc/include/asm/barrier.h +new file mode 100644 +index 0000000000000..7538294721bed +--- /dev/null ++++ b/arch/openrisc/include/asm/barrier.h +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __ASM_BARRIER_H ++#define __ASM_BARRIER_H ++ ++#define mb() asm volatile ("l.msync" ::: "memory") ++ ++#include ++ ++#endif /* __ASM_BARRIER_H */ +diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c +index bedfd2412ec19..7975ddd40b357 100644 +--- a/drivers/char/hpet.c ++++ b/drivers/char/hpet.c +@@ -976,6 +976,8 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) + if (ACPI_SUCCESS(status)) { + hdp->hd_phys_address = addr.address.minimum; + hdp->hd_address = ioremap(addr.address.minimum, addr.address.address_length); ++ if (!hdp->hd_address) ++ return AE_ERROR; + + if (hpet_is_known(hdp)) { + iounmap(hdp->hd_address); +@@ -989,6 +991,8 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) + hdp->hd_phys_address = fixmem32->address; + hdp->hd_address = ioremap(fixmem32->address, + HPET_RANGE_SIZE); ++ if (!hdp->hd_address) ++ return AE_ERROR; + + if (hpet_is_known(hdp)) { + iounmap(hdp->hd_address); +diff --git a/drivers/dma/qcom/hidma_mgmt.c b/drivers/dma/qcom/hidma_mgmt.c +index 82f36e4660830..143ea7cad7561 100644 +--- a/drivers/dma/qcom/hidma_mgmt.c ++++ b/drivers/dma/qcom/hidma_mgmt.c +@@ -398,6 +398,20 @@ static int __init hidma_mgmt_init(void) + of_node_put(child); + } + #endif ++ /* ++ * We do not check for return value here, as it is assumed that ++ * platform_driver_register must not fail. The reason for this is that ++ * the (potential) hidma_mgmt_of_populate_channels calls above are not ++ * cleaned up if it does fail, and to do this work is quite ++ * complicated. In particular, various calls of of_address_to_resource, ++ * of_irq_to_resource, platform_device_register_full, of_dma_configure, ++ * and of_msi_configure which then call other functions and so on, must ++ * be cleaned up - this is not a trivial exercise. ++ * ++ * Currently, this module is not intended to be unloaded, and there is ++ * no module_exit function defined which does the needed cleanup. For ++ * this reason, we have to assume success here. ++ */ + platform_driver_register(&hidma_mgmt_driver); + + return 0; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +index 7271e3f32d82e..ab041ae58b20a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +@@ -886,6 +886,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) + + if (gtt && gtt->userptr) { + kfree(ttm->sg); ++ ttm->sg = NULL; + ttm->page_flags &= ~TTM_PAGE_FLAG_SG; + return; + } +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 26f1691f67abc..0e04b27e3158d 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -375,11 +375,9 @@ static int i801_check_post(struct i801_priv *priv, int status) + dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); + /* try to stop the current command */ + dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n"); +- outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL, +- SMBHSTCNT(priv)); ++ outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv)); + usleep_range(1000, 2000); +- outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL), +- SMBHSTCNT(priv)); ++ outb_p(0, SMBHSTCNT(priv)); + + /* Check if it worked */ + status = inb_p(SMBHSTSTS(priv)); +diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c +index 499af26e736e7..acccdfb954207 100644 +--- a/drivers/i2c/busses/i2c-s3c2410.c ++++ b/drivers/i2c/busses/i2c-s3c2410.c +@@ -495,7 +495,10 @@ static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) + * forces us to send a new START + * when we change direction + */ ++ dev_dbg(i2c->dev, ++ "missing START before write->read\n"); + s3c24xx_i2c_stop(i2c, -EINVAL); ++ break; + } + + goto retry_write; +diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c +index 437762a1e4877..f940b1607ef45 100644 +--- a/drivers/iio/adc/ad7793.c ++++ b/drivers/iio/adc/ad7793.c +@@ -279,6 +279,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, + id &= AD7793_ID_MASK; + + if (id != st->chip_info->id) { ++ ret = -ENODEV; + dev_err(&st->sd.spi->dev, "device ID query failed\n"); + goto out; + } +diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c +index d5bdbaf93a1af..d0b6377b98345 100644 +--- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c ++++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c +@@ -645,17 +645,19 @@ static void + release_io(struct inf_hw *hw) + { + if (hw->cfg.mode) { +- if (hw->cfg.p) { ++ if (hw->cfg.mode == AM_MEMIO) { + release_mem_region(hw->cfg.start, hw->cfg.size); +- iounmap(hw->cfg.p); ++ if (hw->cfg.p) ++ iounmap(hw->cfg.p); + } else + release_region(hw->cfg.start, hw->cfg.size); + hw->cfg.mode = AM_NONE; + } + if (hw->addr.mode) { +- if (hw->addr.p) { ++ if (hw->addr.mode == AM_MEMIO) { + release_mem_region(hw->addr.start, hw->addr.size); +- iounmap(hw->addr.p); ++ if (hw->addr.p) ++ iounmap(hw->addr.p); + } else + release_region(hw->addr.start, hw->addr.size); + hw->addr.mode = AM_NONE; +@@ -685,9 +687,12 @@ setup_io(struct inf_hw *hw) + (ulong)hw->cfg.start, (ulong)hw->cfg.size); + return err; + } +- if (hw->ci->cfg_mode == AM_MEMIO) +- hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); + hw->cfg.mode = hw->ci->cfg_mode; ++ if (hw->ci->cfg_mode == AM_MEMIO) { ++ hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); ++ if (!hw->cfg.p) ++ return -ENOMEM; ++ } + if (debug & DEBUG_HW) + pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n", + hw->name, (ulong)hw->cfg.start, +@@ -712,9 +717,12 @@ setup_io(struct inf_hw *hw) + (ulong)hw->addr.start, (ulong)hw->addr.size); + return err; + } +- if (hw->ci->addr_mode == AM_MEMIO) +- hw->addr.p = ioremap(hw->addr.start, hw->addr.size); + hw->addr.mode = hw->ci->addr_mode; ++ if (hw->ci->addr_mode == AM_MEMIO) { ++ hw->addr.p = ioremap(hw->addr.start, hw->addr.size); ++ if (!hw->addr.p) ++ return -ENOMEM; ++ } + if (debug & DEBUG_HW) + pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n", + hw->name, (ulong)hw->addr.start, +diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c +index 6acdbec05f702..d85d13a4c57a4 100644 +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -788,7 +788,7 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) + static uint32_t __minimum_chunk_size(struct origin *o) + { + struct dm_snapshot *snap; +- unsigned chunk_size = 0; ++ unsigned chunk_size = rounddown_pow_of_two(UINT_MAX); + + if (o) + list_for_each_entry(snap, &o->snapshots, list) +diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c +index e87ac30d7fb83..b43135c5a9607 100644 +--- a/drivers/media/dvb-frontends/sp8870.c ++++ b/drivers/media/dvb-frontends/sp8870.c +@@ -293,7 +293,9 @@ static int sp8870_set_frontend_parameters(struct dvb_frontend *fe) + sp8870_writereg(state, 0xc05, reg0xc05); + + // read status reg in order to clear pending irqs +- sp8870_readreg(state, 0x200); ++ err = sp8870_readreg(state, 0x200); ++ if (err < 0) ++ return err; + + // system controller start + sp8870_microcontroller_start(state); +diff --git a/drivers/media/usb/gspca/m5602/m5602_po1030.c b/drivers/media/usb/gspca/m5602/m5602_po1030.c +index a0a90dd34ca83..a098aeb290c36 100644 +--- a/drivers/media/usb/gspca/m5602/m5602_po1030.c ++++ b/drivers/media/usb/gspca/m5602/m5602_po1030.c +@@ -159,6 +159,7 @@ static const struct v4l2_ctrl_config po1030_greenbal_cfg = { + int po1030_probe(struct sd *sd) + { + u8 dev_id_h = 0, i; ++ int err; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + + if (force_sensor) { +@@ -177,10 +178,13 @@ int po1030_probe(struct sd *sd) + for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { + u8 data = preinit_po1030[i][2]; + if (preinit_po1030[i][0] == SENSOR) +- m5602_write_sensor(sd, +- preinit_po1030[i][1], &data, 1); ++ err = m5602_write_sensor(sd, preinit_po1030[i][1], ++ &data, 1); + else +- m5602_write_bridge(sd, preinit_po1030[i][1], data); ++ err = m5602_write_bridge(sd, preinit_po1030[i][1], ++ data); ++ if (err < 0) ++ return err; + } + + if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1)) +diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c +index e4249ce2c42f4..ab2184003c29d 100644 +--- a/drivers/misc/kgdbts.c ++++ b/drivers/misc/kgdbts.c +@@ -110,8 +110,9 @@ + printk(KERN_INFO a); \ + } while (0) + #define v2printk(a...) do { \ +- if (verbose > 1) \ ++ if (verbose > 1) { \ + printk(KERN_INFO a); \ ++ } \ + touch_nmi_watchdog(); \ + } while (0) + #define eprintk(a...) do { \ +diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h +index c439c827eea80..0ef759671b546 100644 +--- a/drivers/misc/lis3lv02d/lis3lv02d.h ++++ b/drivers/misc/lis3lv02d/lis3lv02d.h +@@ -284,6 +284,7 @@ struct lis3lv02d { + int regs_size; + u8 *reg_cache; + bool regs_stored; ++ bool init_required; + u8 odr_mask; /* ODR bit mask */ + u8 whoami; /* indicates measurement precision */ + s16 (*read_data) (struct lis3lv02d *lis3, int reg); +diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c +index 5a4893ce9c240..857bf1f8f4c05 100644 +--- a/drivers/misc/mei/interrupt.c ++++ b/drivers/misc/mei/interrupt.c +@@ -226,6 +226,9 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, + return ret; + } + ++ pm_runtime_mark_last_busy(dev->dev); ++ pm_request_autosuspend(dev->dev); ++ + list_move_tail(&cb->list, &cl->rd_pending); + + return 0; +diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c +index c2dea4916e5d7..32834dad0b836 100644 +--- a/drivers/net/caif/caif_serial.c ++++ b/drivers/net/caif/caif_serial.c +@@ -281,7 +281,6 @@ static int caif_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct ser_device *ser; + +- BUG_ON(dev == NULL); + ser = netdev_priv(dev); + + /* Send flow off once, on high water mark */ +diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c +index 1f7034d739b00..e15e487c14dd0 100644 +--- a/drivers/net/ethernet/broadcom/bnx2.c ++++ b/drivers/net/ethernet/broadcom/bnx2.c +@@ -8256,9 +8256,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) + BNX2_WR(bp, PCI_COMMAND, reg); + } else if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A1) && + !(bp->flags & BNX2_FLAG_PCIX)) { +- + dev_err(&pdev->dev, + "5706 A1 can only be used in a PCIX bus, aborting\n"); ++ rc = -EPERM; + goto err_out_unmap; + } + +diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +index 399cfd217288d..cfda55bfa811a 100644 +--- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c ++++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +@@ -548,6 +548,11 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) + return -1; + + base = ioremap(link->resource[2]->start, resource_size(link->resource[2])); ++ if (!base) { ++ pcmcia_release_window(link, link->resource[2]); ++ return -1; ++ } ++ + pcmcia_map_mem_page(link, link->resource[2], 0); + + /* +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +index d1224d33ecfab..410a36c982419 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +@@ -1931,8 +1931,6 @@ static int mlx4_en_set_tunable(struct net_device *dev, + return ret; + } + +-#define MLX4_EEPROM_PAGE_LEN 256 +- + static int mlx4_en_get_module_info(struct net_device *dev, + struct ethtool_modinfo *modinfo) + { +@@ -1967,7 +1965,7 @@ static int mlx4_en_get_module_info(struct net_device *dev, + break; + case MLX4_MODULE_ID_SFP: + modinfo->type = ETH_MODULE_SFF_8472; +- modinfo->eeprom_len = MLX4_EEPROM_PAGE_LEN; ++ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + break; + default: + return -ENOSYS; +diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c +index 3173875a715fc..231f097128502 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/port.c ++++ b/drivers/net/ethernet/mellanox/mlx4/port.c +@@ -1856,6 +1856,7 @@ EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); + #define I2C_ADDR_LOW 0x50 + #define I2C_ADDR_HIGH 0x51 + #define I2C_PAGE_SIZE 256 ++#define I2C_HIGH_PAGE_SIZE 128 + + /* Module Info Data */ + struct mlx4_cable_info { +@@ -1909,6 +1910,88 @@ static inline const char *cable_info_mad_err_str(u16 mad_status) + return "Unknown Error"; + } + ++static int mlx4_get_module_id(struct mlx4_dev *dev, u8 port, u8 *module_id) ++{ ++ struct mlx4_cmd_mailbox *inbox, *outbox; ++ struct mlx4_mad_ifc *inmad, *outmad; ++ struct mlx4_cable_info *cable_info; ++ int ret; ++ ++ inbox = mlx4_alloc_cmd_mailbox(dev); ++ if (IS_ERR(inbox)) ++ return PTR_ERR(inbox); ++ ++ outbox = mlx4_alloc_cmd_mailbox(dev); ++ if (IS_ERR(outbox)) { ++ mlx4_free_cmd_mailbox(dev, inbox); ++ return PTR_ERR(outbox); ++ } ++ ++ inmad = (struct mlx4_mad_ifc *)(inbox->buf); ++ outmad = (struct mlx4_mad_ifc *)(outbox->buf); ++ ++ inmad->method = 0x1; /* Get */ ++ inmad->class_version = 0x1; ++ inmad->mgmt_class = 0x1; ++ inmad->base_version = 0x1; ++ inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */ ++ ++ cable_info = (struct mlx4_cable_info *)inmad->data; ++ cable_info->dev_mem_address = 0; ++ cable_info->page_num = 0; ++ cable_info->i2c_addr = I2C_ADDR_LOW; ++ cable_info->size = cpu_to_be16(1); ++ ++ ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3, ++ MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, ++ MLX4_CMD_NATIVE); ++ if (ret) ++ goto out; ++ ++ if (be16_to_cpu(outmad->status)) { ++ /* Mad returned with bad status */ ++ ret = be16_to_cpu(outmad->status); ++ mlx4_warn(dev, ++ "MLX4_CMD_MAD_IFC Get Module ID attr(%x) port(%d) i2c_addr(%x) offset(%d) size(%d): Response Mad Status(%x) - %s\n", ++ 0xFF60, port, I2C_ADDR_LOW, 0, 1, ret, ++ cable_info_mad_err_str(ret)); ++ ret = -ret; ++ goto out; ++ } ++ cable_info = (struct mlx4_cable_info *)outmad->data; ++ *module_id = cable_info->data[0]; ++out: ++ mlx4_free_cmd_mailbox(dev, inbox); ++ mlx4_free_cmd_mailbox(dev, outbox); ++ return ret; ++} ++ ++static void mlx4_sfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) ++{ ++ *i2c_addr = I2C_ADDR_LOW; ++ *page_num = 0; ++ ++ if (*offset < I2C_PAGE_SIZE) ++ return; ++ ++ *i2c_addr = I2C_ADDR_HIGH; ++ *offset -= I2C_PAGE_SIZE; ++} ++ ++static void mlx4_qsfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) ++{ ++ /* Offsets 0-255 belong to page 0. ++ * Offsets 256-639 belong to pages 01, 02, 03. ++ * For example, offset 400 is page 02: 1 + (400 - 256) / 128 = 2 ++ */ ++ if (*offset < I2C_PAGE_SIZE) ++ *page_num = 0; ++ else ++ *page_num = 1 + (*offset - I2C_PAGE_SIZE) / I2C_HIGH_PAGE_SIZE; ++ *i2c_addr = I2C_ADDR_LOW; ++ *offset -= *page_num * I2C_HIGH_PAGE_SIZE; ++} ++ + /** + * mlx4_get_module_info - Read cable module eeprom data + * @dev: mlx4_dev. +@@ -1928,12 +2011,30 @@ int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, + struct mlx4_cmd_mailbox *inbox, *outbox; + struct mlx4_mad_ifc *inmad, *outmad; + struct mlx4_cable_info *cable_info; +- u16 i2c_addr; ++ u8 module_id, i2c_addr, page_num; + int ret; + + if (size > MODULE_INFO_MAX_READ) + size = MODULE_INFO_MAX_READ; + ++ ret = mlx4_get_module_id(dev, port, &module_id); ++ if (ret) ++ return ret; ++ ++ switch (module_id) { ++ case MLX4_MODULE_ID_SFP: ++ mlx4_sfp_eeprom_params_set(&i2c_addr, &page_num, &offset); ++ break; ++ case MLX4_MODULE_ID_QSFP: ++ case MLX4_MODULE_ID_QSFP_PLUS: ++ case MLX4_MODULE_ID_QSFP28: ++ mlx4_qsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); ++ break; ++ default: ++ mlx4_err(dev, "Module ID not recognized: %#x\n", module_id); ++ return -EINVAL; ++ } ++ + inbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(inbox)) + return PTR_ERR(inbox); +@@ -1959,11 +2060,9 @@ int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, + */ + size -= offset + size - I2C_PAGE_SIZE; + +- i2c_addr = I2C_ADDR_LOW; +- + cable_info = (struct mlx4_cable_info *)inmad->data; + cable_info->dev_mem_address = cpu_to_be16(offset); +- cable_info->page_num = 0; ++ cable_info->page_num = page_num; + cable_info->i2c_addr = i2c_addr; + cable_info->size = cpu_to_be16(size); + +diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c +index 32516661f180b..c17967b23d3c3 100644 +--- a/drivers/net/ethernet/ti/netcp_core.c ++++ b/drivers/net/ethernet/ti/netcp_core.c +@@ -1325,9 +1325,9 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe) + tx_pipe->dma_queue = knav_queue_open(name, tx_pipe->dma_queue_id, + KNAV_QUEUE_SHARED); + if (IS_ERR(tx_pipe->dma_queue)) { ++ ret = PTR_ERR(tx_pipe->dma_queue); + dev_err(dev, "Could not open DMA queue for channel \"%s\": %d\n", + name, ret); +- ret = PTR_ERR(tx_pipe->dma_queue); + goto err; + } + +diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c +index ab6914f8bd50f..1da104150f445 100644 +--- a/drivers/net/phy/mdio-octeon.c ++++ b/drivers/net/phy/mdio-octeon.c +@@ -75,7 +75,6 @@ static int octeon_mdiobus_probe(struct platform_device *pdev) + + return 0; + fail_register: +- mdiobus_free(bus->mii_bus); + smi_en.u64 = 0; + oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN); + return err; +@@ -89,7 +88,6 @@ static int octeon_mdiobus_remove(struct platform_device *pdev) + bus = platform_get_drvdata(pdev); + + mdiobus_unregister(bus->mii_bus); +- mdiobus_free(bus->mii_bus); + smi_en.u64 = 0; + oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN); + return 0; +diff --git a/drivers/net/phy/mdio-thunder.c b/drivers/net/phy/mdio-thunder.c +index 564616968cad4..c0c922eff760c 100644 +--- a/drivers/net/phy/mdio-thunder.c ++++ b/drivers/net/phy/mdio-thunder.c +@@ -129,7 +129,6 @@ static void thunder_mdiobus_pci_remove(struct pci_dev *pdev) + continue; + + mdiobus_unregister(bus->mii_bus); +- mdiobus_free(bus->mii_bus); + oct_mdio_writeq(0, bus->register_base + SMI_EN); + } + pci_set_drvdata(pdev, NULL); +diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c +index 6ecccc737974c..5066b7bc67da6 100644 +--- a/drivers/net/usb/hso.c ++++ b/drivers/net/usb/hso.c +@@ -1703,7 +1703,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, + spin_unlock_irqrestore(&serial->serial_lock, flags); + + return usb_control_msg(serial->parent->usb, +- usb_rcvctrlpipe(serial->parent->usb, 0), 0x22, ++ usb_sndctrlpipe(serial->parent->usb, 0), 0x22, + 0x21, val, if_num, NULL, 0, + USB_CTRL_SET_TIMEOUT); + } +@@ -2451,7 +2451,7 @@ static int hso_rfkill_set_block(void *data, bool blocked) + if (hso_dev->usb_gone) + rv = 0; + else +- rv = usb_control_msg(hso_dev->usb, usb_rcvctrlpipe(hso_dev->usb, 0), ++ rv = usb_control_msg(hso_dev->usb, usb_sndctrlpipe(hso_dev->usb, 0), + enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0, + USB_CTRL_SET_TIMEOUT); + mutex_unlock(&hso_dev->mutex); +diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c +index 977d9c7725541..3a391ae5c4e0d 100644 +--- a/drivers/net/usb/smsc75xx.c ++++ b/drivers/net/usb/smsc75xx.c +@@ -1497,7 +1497,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) + ret = smsc75xx_wait_ready(dev, 0); + if (ret < 0) { + netdev_warn(dev->net, "device not ready in smsc75xx_bind\n"); +- return ret; ++ goto err; + } + + smsc75xx_init_mac_address(dev); +@@ -1506,7 +1506,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) + ret = smsc75xx_reset(dev); + if (ret < 0) { + netdev_warn(dev->net, "smsc75xx_reset error %d\n", ret); +- return ret; ++ goto err; + } + + dev->net->netdev_ops = &smsc75xx_netdev_ops; +@@ -1515,6 +1515,10 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) + dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; + dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; + return 0; ++ ++err: ++ kfree(pdata); ++ return ret; + } + + static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) +diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c +index 3cbc71fa70d18..381bff3a21038 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -1582,14 +1582,62 @@ static void ath10k_htt_rx_h_unchain(struct ath10k *ar, + ath10k_unchain_msdu(amsdu); + } + ++static bool ath10k_htt_rx_validate_amsdu(struct ath10k *ar, ++ struct sk_buff_head *amsdu) ++{ ++ u8 *subframe_hdr; ++ struct sk_buff *first; ++ bool is_first, is_last; ++ struct htt_rx_desc *rxd; ++ struct ieee80211_hdr *hdr; ++ size_t hdr_len, crypto_len; ++ enum htt_rx_mpdu_encrypt_type enctype; ++ int bytes_aligned = ar->hw_params.decap_align_bytes; ++ ++ first = skb_peek(amsdu); ++ ++ rxd = (void *)first->data - sizeof(*rxd); ++ hdr = (void *)rxd->rx_hdr_status; ++ ++ is_first = !!(rxd->msdu_end.common.info0 & ++ __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); ++ is_last = !!(rxd->msdu_end.common.info0 & ++ __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)); ++ ++ /* Return in case of non-aggregated msdu */ ++ if (is_first && is_last) ++ return true; ++ ++ /* First msdu flag is not set for the first msdu of the list */ ++ if (!is_first) ++ return false; ++ ++ enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), ++ RX_MPDU_START_INFO0_ENCRYPT_TYPE); ++ ++ hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); ++ ++ subframe_hdr = (u8 *)hdr + round_up(hdr_len, bytes_aligned) + ++ crypto_len; ++ ++ /* Validate if the amsdu has a proper first subframe. ++ * There are chances a single msdu can be received as amsdu when ++ * the unauthenticated amsdu flag of a QoS header ++ * gets flipped in non-SPP AMSDU's, in such cases the first ++ * subframe has llc/snap header in place of a valid da. ++ * return false if the da matches rfc1042 pattern ++ */ ++ if (ether_addr_equal(subframe_hdr, rfc1042_header)) ++ return false; ++ ++ return true; ++} ++ + static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *rx_status) + { +- /* FIXME: It might be a good idea to do some fuzzy-testing to drop +- * invalid/dangerous frames. +- */ +- + if (!rx_status->freq) { + ath10k_warn(ar, "no channel configured; ignoring frame(s)!\n"); + return false; +@@ -1600,6 +1648,11 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, + return false; + } + ++ if (!ath10k_htt_rx_validate_amsdu(ar, amsdu)) { ++ ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid amsdu received\n"); ++ return false; ++ } ++ + return true; + } + +diff --git a/drivers/net/wireless/marvell/libertas/mesh.c b/drivers/net/wireless/marvell/libertas/mesh.c +index d0c881dd58467..f1e9cbcfdc168 100644 +--- a/drivers/net/wireless/marvell/libertas/mesh.c ++++ b/drivers/net/wireless/marvell/libertas/mesh.c +@@ -797,19 +797,6 @@ static const struct attribute_group mesh_ie_group = { + .attrs = mesh_ie_attrs, + }; + +-static void lbs_persist_config_init(struct net_device *dev) +-{ +- int ret; +- ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group); +- ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group); +-} +- +-static void lbs_persist_config_remove(struct net_device *dev) +-{ +- sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group); +- sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group); +-} +- + + /*************************************************************************** + * Initializing and starting, stopping mesh +@@ -1021,6 +1008,10 @@ static int lbs_add_mesh(struct lbs_private *priv) + SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); + + mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; ++ mesh_dev->sysfs_groups[0] = &lbs_mesh_attr_group; ++ mesh_dev->sysfs_groups[1] = &boot_opts_group; ++ mesh_dev->sysfs_groups[2] = &mesh_ie_group; ++ + /* Register virtual mesh interface */ + ret = register_netdev(mesh_dev); + if (ret) { +@@ -1028,19 +1019,10 @@ static int lbs_add_mesh(struct lbs_private *priv) + goto err_free_netdev; + } + +- ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); +- if (ret) +- goto err_unregister; +- +- lbs_persist_config_init(mesh_dev); +- + /* Everything successful */ + ret = 0; + goto done; + +-err_unregister: +- unregister_netdev(mesh_dev); +- + err_free_netdev: + free_netdev(mesh_dev); + +@@ -1063,8 +1045,6 @@ void lbs_remove_mesh(struct lbs_private *priv) + lbs_deb_enter(LBS_DEB_MESH); + netif_stop_queue(mesh_dev); + netif_carrier_off(mesh_dev); +- sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); +- lbs_persist_config_remove(mesh_dev); + unregister_netdev(mesh_dev); + priv->mesh_dev = NULL; + kfree(mesh_dev->ieee80211_ptr); +diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c +index abd9d83f60094..403d966223ee9 100644 +--- a/drivers/platform/x86/hp_accel.c ++++ b/drivers/platform/x86/hp_accel.c +@@ -101,6 +101,9 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids); + static int lis3lv02d_acpi_init(struct lis3lv02d *lis3) + { + struct acpi_device *dev = lis3->bus_priv; ++ if (!lis3->init_required) ++ return 0; ++ + if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI, + NULL, NULL) != AE_OK) + return -EINVAL; +@@ -366,6 +369,7 @@ static int lis3lv02d_add(struct acpi_device *device) + } + + /* call the core layer do its init */ ++ lis3_dev.init_required = true; + ret = lis3lv02d_init_device(&lis3_dev); + if (ret) + return ret; +@@ -413,11 +417,27 @@ static int lis3lv02d_suspend(struct device *dev) + + static int lis3lv02d_resume(struct device *dev) + { ++ lis3_dev.init_required = false; ++ lis3lv02d_poweron(&lis3_dev); ++ return 0; ++} ++ ++static int lis3lv02d_restore(struct device *dev) ++{ ++ lis3_dev.init_required = true; + lis3lv02d_poweron(&lis3_dev); + return 0; + } + +-static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume); ++static const struct dev_pm_ops hp_accel_pm = { ++ .suspend = lis3lv02d_suspend, ++ .resume = lis3lv02d_resume, ++ .freeze = lis3lv02d_suspend, ++ .thaw = lis3lv02d_resume, ++ .poweroff = lis3lv02d_suspend, ++ .restore = lis3lv02d_restore, ++}; ++ + #define HP_ACCEL_PM (&hp_accel_pm) + #else + #define HP_ACCEL_PM NULL +diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c +index b7dfe06261f1e..9865d11eda75c 100644 +--- a/drivers/platform/x86/intel_punit_ipc.c ++++ b/drivers/platform/x86/intel_punit_ipc.c +@@ -330,6 +330,7 @@ static const struct acpi_device_id punit_ipc_acpi_ids[] = { + { "INT34D4", 0 }, + { } + }; ++MODULE_DEVICE_TABLE(acpi, punit_ipc_acpi_ids); + + static struct platform_driver intel_punit_ipc_driver = { + .probe = intel_punit_ipc_probe, +diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c +index c7be7bb37209f..b9b4491d732ab 100644 +--- a/drivers/scsi/BusLogic.c ++++ b/drivers/scsi/BusLogic.c +@@ -3081,11 +3081,11 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, + ccb->opcode = BLOGIC_INITIATOR_CCB_SG; + ccb->datalen = count * sizeof(struct blogic_sg_seg); + if (blogic_multimaster_type(adapter)) +- ccb->data = (void *)((unsigned int) ccb->dma_handle + ++ ccb->data = (unsigned int) ccb->dma_handle + + ((unsigned long) &ccb->sglist - +- (unsigned long) ccb)); ++ (unsigned long) ccb); + else +- ccb->data = ccb->sglist; ++ ccb->data = virt_to_32bit_virt(ccb->sglist); + + scsi_for_each_sg(command, sg, count, i) { + ccb->sglist[i].segbytes = sg_dma_len(sg); +diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h +index b53ec2f1e8cdc..5c950a7a1b1c7 100644 +--- a/drivers/scsi/BusLogic.h ++++ b/drivers/scsi/BusLogic.h +@@ -821,7 +821,7 @@ struct blogic_ccb { + unsigned char cdblen; /* Byte 2 */ + unsigned char sense_datalen; /* Byte 3 */ + u32 datalen; /* Bytes 4-7 */ +- void *data; /* Bytes 8-11 */ ++ u32 data; /* Bytes 8-11 */ + unsigned char:8; /* Byte 12 */ + unsigned char:8; /* Byte 13 */ + enum blogic_adapter_status adapter_status; /* Byte 14 */ +diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c +index d3c5297c6c89e..30e0730f613e8 100644 +--- a/drivers/scsi/libsas/sas_port.c ++++ b/drivers/scsi/libsas/sas_port.c +@@ -41,7 +41,7 @@ static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy + + static void sas_resume_port(struct asd_sas_phy *phy) + { +- struct domain_device *dev; ++ struct domain_device *dev, *n; + struct asd_sas_port *port = phy->port; + struct sas_ha_struct *sas_ha = phy->ha; + struct sas_internal *si = to_sas_internal(sas_ha->core.shost->transportt); +@@ -60,7 +60,7 @@ static void sas_resume_port(struct asd_sas_phy *phy) + * 1/ presume every device came back + * 2/ force the next revalidation to check all expander phys + */ +- list_for_each_entry(dev, &port->dev_list, dev_list_node) { ++ list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) { + int i, rc; + + rc = sas_notify_lldd_dev_found(dev); +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index f0ba5eb26128b..84e2296c45a24 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -1869,6 +1869,7 @@ struct spi_master *devm_spi_alloc_master(struct device *dev, unsigned int size) + + master = spi_alloc_master(dev, size); + if (master) { ++ master->devm_allocated = true; + *ptr = master; + devres_add(dev, ptr); + } else { +@@ -2059,11 +2060,6 @@ int devm_spi_register_master(struct device *dev, struct spi_master *master) + } + EXPORT_SYMBOL_GPL(devm_spi_register_master); + +-static int devm_spi_match_master(struct device *dev, void *res, void *master) +-{ +- return *(struct spi_master **)res == master; +-} +- + static int __unregister(struct device *dev, void *null) + { + spi_unregister_device(to_spi_device(dev)); +@@ -2102,8 +2098,7 @@ void spi_unregister_master(struct spi_master *master) + /* Release the last reference on the master if its driver + * has not yet been converted to devm_spi_alloc_master(). + */ +- if (!devres_find(master->dev.parent, devm_spi_release_master, +- devm_spi_match_master, master)) ++ if (!master->devm_allocated) + put_device(&master->dev); + + if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) +diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c +index 1055649f034c0..59266650e071a 100644 +--- a/drivers/staging/emxx_udc/emxx_udc.c ++++ b/drivers/staging/emxx_udc/emxx_udc.c +@@ -2173,7 +2173,7 @@ static int _nbu2ss_nuke(struct nbu2ss_udc *udc, + struct nbu2ss_ep *ep, + int status) + { +- struct nbu2ss_req *req; ++ struct nbu2ss_req *req, *n; + + /* Endpoint Disable */ + _nbu2ss_epn_exit(udc, ep); +@@ -2185,7 +2185,7 @@ static int _nbu2ss_nuke(struct nbu2ss_udc *udc, + return 0; + + /* called with irqs blocked */ +- list_for_each_entry(req, &ep->queue, queue) { ++ list_for_each_entry_safe(req, n, &ep->queue, queue) { + _nbu2ss_ep_done(ep, req, status); + } + +diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c +index 5771d4ee8ef10..1a71bca4e6988 100644 +--- a/drivers/staging/iio/cdc/ad7746.c ++++ b/drivers/staging/iio/cdc/ad7746.c +@@ -714,7 +714,6 @@ static int ad7746_probe(struct i2c_client *client, + indio_dev->num_channels = ARRAY_SIZE(ad7746_channels); + else + indio_dev->num_channels = ARRAY_SIZE(ad7746_channels) - 2; +- indio_dev->num_channels = ARRAY_SIZE(ad7746_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + + if (pdata) { +diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c +index 80ab672d61cc4..febbacecb3ba6 100644 +--- a/drivers/tty/serial/max310x.c ++++ b/drivers/tty/serial/max310x.c +@@ -1385,10 +1385,12 @@ static int __init max310x_uart_init(void) + return ret; + + #ifdef CONFIG_SPI_MASTER +- spi_register_driver(&max310x_spi_driver); ++ ret = spi_register_driver(&max310x_spi_driver); ++ if (ret) ++ uart_unregister_driver(&max310x_uart); + #endif + +- return 0; ++ return ret; + } + module_init(max310x_uart_init); + +diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c +index 056f91b3a4ca5..b7d1b1645c842 100644 +--- a/drivers/tty/serial/rp2.c ++++ b/drivers/tty/serial/rp2.c +@@ -198,7 +198,6 @@ struct rp2_card { + void __iomem *bar0; + void __iomem *bar1; + spinlock_t card_lock; +- struct completion fw_loaded; + }; + + #define RP_ID(prod) PCI_VDEVICE(RP, (prod)) +@@ -667,17 +666,10 @@ static void rp2_remove_ports(struct rp2_card *card) + card->initialized_ports = 0; + } + +-static void rp2_fw_cb(const struct firmware *fw, void *context) ++static int rp2_load_firmware(struct rp2_card *card, const struct firmware *fw) + { +- struct rp2_card *card = context; + resource_size_t phys_base; +- int i, rc = -ENOENT; +- +- if (!fw) { +- dev_err(&card->pdev->dev, "cannot find '%s' firmware image\n", +- RP2_FW_NAME); +- goto no_fw; +- } ++ int i, rc = 0; + + phys_base = pci_resource_start(card->pdev, 1); + +@@ -723,23 +715,13 @@ static void rp2_fw_cb(const struct firmware *fw, void *context) + card->initialized_ports++; + } + +- release_firmware(fw); +-no_fw: +- /* +- * rp2_fw_cb() is called from a workqueue long after rp2_probe() +- * has already returned success. So if something failed here, +- * we'll just leave the now-dormant device in place until somebody +- * unbinds it. +- */ +- if (rc) +- dev_warn(&card->pdev->dev, "driver initialization failed\n"); +- +- complete(&card->fw_loaded); ++ return rc; + } + + static int rp2_probe(struct pci_dev *pdev, + const struct pci_device_id *id) + { ++ const struct firmware *fw; + struct rp2_card *card; + struct rp2_uart_port *ports; + void __iomem * const *bars; +@@ -750,7 +732,6 @@ static int rp2_probe(struct pci_dev *pdev, + return -ENOMEM; + pci_set_drvdata(pdev, card); + spin_lock_init(&card->card_lock); +- init_completion(&card->fw_loaded); + + rc = pcim_enable_device(pdev); + if (rc) +@@ -783,21 +764,23 @@ static int rp2_probe(struct pci_dev *pdev, + return -ENOMEM; + card->ports = ports; + +- rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, +- IRQF_SHARED, DRV_NAME, card); +- if (rc) ++ rc = request_firmware(&fw, RP2_FW_NAME, &pdev->dev); ++ if (rc < 0) { ++ dev_err(&pdev->dev, "cannot find '%s' firmware image\n", ++ RP2_FW_NAME); + return rc; ++ } + +- /* +- * Only catastrophic errors (e.g. ENOMEM) are reported here. +- * If the FW image is missing, we'll find out in rp2_fw_cb() +- * and print an error message. +- */ +- rc = request_firmware_nowait(THIS_MODULE, 1, RP2_FW_NAME, &pdev->dev, +- GFP_KERNEL, card, rp2_fw_cb); ++ rc = rp2_load_firmware(card, fw); ++ ++ release_firmware(fw); ++ if (rc < 0) ++ return rc; ++ ++ rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, ++ IRQF_SHARED, DRV_NAME, card); + if (rc) + return rc; +- dev_dbg(&pdev->dev, "waiting for firmware blob...\n"); + + return 0; + } +@@ -806,7 +789,6 @@ static void rp2_remove(struct pci_dev *pdev) + { + struct rp2_card *card = pci_get_drvdata(pdev); + +- wait_for_completion(&card->fw_loaded); + rp2_remove_ports(card); + } + +diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h +index 34c1a7e22aae0..be5075d414067 100644 +--- a/drivers/usb/core/hub.h ++++ b/drivers/usb/core/hub.h +@@ -151,8 +151,10 @@ static inline unsigned hub_power_on_good_delay(struct usb_hub *hub) + { + unsigned delay = hub->descriptor->bPwrOn2PwrGood * 2; + +- /* Wait at least 100 msec for power to become stable */ +- return max(delay, 100U); ++ if (!hub->hdev->parent) /* root hub */ ++ return delay; ++ else /* Wait at least 100 msec for power to become stable */ ++ return max(delay, 100U); + } + + static inline int hub_port_debounce_be_connected(struct usb_hub *hub, +diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c +index 9795457723d86..ad71840db899e 100644 +--- a/drivers/usb/misc/trancevibrator.c ++++ b/drivers/usb/misc/trancevibrator.c +@@ -74,9 +74,9 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, + /* Set speed */ + retval = usb_control_msg(tv->udev, usb_sndctrlpipe(tv->udev, 0), + 0x01, /* vendor request: set speed */ +- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, + tv->speed, /* speed value */ +- 0, NULL, 0, USB_CTRL_GET_TIMEOUT); ++ 0, NULL, 0, USB_CTRL_SET_TIMEOUT); + if (retval) { + tv->speed = old; + dev_dbg(&tv->udev->dev, "retval = %d\n", retval); +diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c +index e77465a30ac69..0ec6d76d1563b 100644 +--- a/drivers/usb/misc/uss720.c ++++ b/drivers/usb/misc/uss720.c +@@ -750,6 +750,7 @@ static int uss720_probe(struct usb_interface *intf, + parport_announce_port(pp); + + usb_set_intfdata(intf, pp); ++ usb_put_dev(usbdev); + return 0; + + probe_abort: +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index c9f979063af13..276e9790442d9 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1029,6 +1029,9 @@ static const struct usb_device_id id_table_combined[] = { + /* Sienna devices */ + { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) }, + { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) }, ++ /* IDS GmbH devices */ ++ { USB_DEVICE(IDS_VID, IDS_SI31A_PID) }, ++ { USB_DEVICE(IDS_VID, IDS_CM31A_PID) }, + /* U-Blox devices */ + { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) }, + { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index f3302516a1e4f..b5f28a7952282 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -1566,6 +1566,13 @@ + #define UNJO_VID 0x22B7 + #define UNJO_ISODEBUG_V1_PID 0x150D + ++/* ++ * IDS GmbH ++ */ ++#define IDS_VID 0x2CAF ++#define IDS_SI31A_PID 0x13A2 ++#define IDS_CM31A_PID 0x13A3 ++ + /* + * U-Blox products (http://www.u-blox.com). + */ +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 351be73862809..6faa9ac538877 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1222,6 +1222,10 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */ + .driver_info = NCTRL(0) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7010, 0xff), /* Telit LE910-S1 (RNDIS) */ ++ .driver_info = NCTRL(2) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7011, 0xff), /* Telit LE910-S1 (ECM) */ ++ .driver_info = NCTRL(2) }, + { USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */ + .driver_info = NCTRL(0) | ZLP }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ +diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c +index bf5533d6d83bd..3dd0bbb36dd27 100644 +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -102,6 +102,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, + { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, + { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, ++ { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530GC_PRODUCT_ID) }, + { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) }, + { USB_DEVICE(AT_VENDOR_ID, AT_VTKIT3_PRODUCT_ID) }, + { } /* Terminating entry */ +diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h +index 9d27c076f477e..62b8cd673aa11 100644 +--- a/drivers/usb/serial/pl2303.h ++++ b/drivers/usb/serial/pl2303.h +@@ -156,6 +156,7 @@ + /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ + #define ADLINK_VENDOR_ID 0x0b63 + #define ADLINK_ND6530_PRODUCT_ID 0x6530 ++#define ADLINK_ND6530GC_PRODUCT_ID 0x653a + + /* SMART USB Serial Adapter */ + #define SMART_VENDOR_ID 0x0b8c +diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c +index a7e41723c34cf..720bcf29d4f6c 100644 +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -41,6 +41,7 @@ + /* Vendor and product ids */ + #define TI_VENDOR_ID 0x0451 + #define IBM_VENDOR_ID 0x04b3 ++#define STARTECH_VENDOR_ID 0x14b0 + #define TI_3410_PRODUCT_ID 0x3410 + #define IBM_4543_PRODUCT_ID 0x4543 + #define IBM_454B_PRODUCT_ID 0x454b +@@ -378,6 +379,7 @@ static const struct usb_device_id ti_id_table_3410[] = { + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1131_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1150_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1151_PRODUCT_ID) }, ++ { USB_DEVICE(STARTECH_VENDOR_ID, TI_3410_PRODUCT_ID) }, + { } /* terminator */ + }; + +@@ -416,6 +418,7 @@ static const struct usb_device_id ti_id_table_combined[] = { + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1131_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1150_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1151_PRODUCT_ID) }, ++ { USB_DEVICE(STARTECH_VENDOR_ID, TI_3410_PRODUCT_ID) }, + { } /* terminator */ + }; + +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 9909b63d2acda..5c86fecaf167e 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -1600,8 +1600,6 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, + ret = btrfs_update_inode(trans, root, inode); + } else if (ret == -EEXIST) { + ret = 0; +- } else { +- BUG(); /* Logic Error */ + } + iput(inode); + +diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c +index ba1909b887efb..e7339a39e7189 100644 +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -451,7 +451,7 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart, + if (next >= end) + break; + +- hash = hugetlb_fault_mutex_hash(h, mapping, next, 0); ++ hash = hugetlb_fault_mutex_hash(h, mapping, next); + mutex_lock(&hugetlb_fault_mutex_table[hash]); + + /* +@@ -634,7 +634,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, + addr = index * hpage_size; + + /* mutex taken here, fault path and hole punch */ +- hash = hugetlb_fault_mutex_hash(h, mapping, index, addr); ++ hash = hugetlb_fault_mutex_hash(h, mapping, index); + mutex_lock(&hugetlb_fault_mutex_table[hash]); + + /* See if already present in mapping to avoid alloc/free */ +diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c +index a3fc48ba4931d..dec7e5ad525af 100644 +--- a/fs/nfs/filelayout/filelayout.c ++++ b/fs/nfs/filelayout/filelayout.c +@@ -726,7 +726,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, + if (unlikely(!p)) + goto out_err; + fl->fh_array[i]->size = be32_to_cpup(p++); +- if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) { ++ if (fl->fh_array[i]->size > NFS_MAXFHSIZE) { + printk(KERN_ERR "NFS: Too big fh %d received %d\n", + i, fl->fh_array[i]->size); + goto out_err; +diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c +index 7138383382ff1..80718d9999edb 100644 +--- a/fs/nfs/nfs4file.c ++++ b/fs/nfs/nfs4file.c +@@ -147,7 +147,7 @@ static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence) + case SEEK_HOLE: + case SEEK_DATA: + ret = nfs42_proc_llseek(filep, offset, whence); +- if (ret != -ENOTSUPP) ++ if (ret != -EOPNOTSUPP) + return ret; + default: + return nfs_file_llseek(filep, offset, whence); +diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c +index 529f3a5762637..3e0fcb86390ac 100644 +--- a/fs/nfs/pagelist.c ++++ b/fs/nfs/pagelist.c +@@ -952,17 +952,16 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) + { + struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc); + +- + if (!list_empty(&mirror->pg_list)) { + int error = desc->pg_ops->pg_doio(desc); + if (error < 0) + desc->pg_error = error; +- else ++ if (list_empty(&mirror->pg_list)) { + mirror->pg_bytes_written += mirror->pg_count; +- } +- if (list_empty(&mirror->pg_list)) { +- mirror->pg_count = 0; +- mirror->pg_base = 0; ++ mirror->pg_count = 0; ++ mirror->pg_base = 0; ++ mirror->pg_recoalesce = 0; ++ } + } + } + +@@ -1061,7 +1060,6 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) + + do { + list_splice_init(&mirror->pg_list, &head); +- mirror->pg_bytes_written -= mirror->pg_count; + mirror->pg_count = 0; + mirror->pg_base = 0; + mirror->pg_recoalesce = 0; +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index d347d95a1bac1..f19cded49b29d 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -1070,6 +1070,11 @@ _pnfs_return_layout(struct inode *ino) + { + struct pnfs_layout_hdr *lo = NULL; + struct nfs_inode *nfsi = NFS_I(ino); ++ struct pnfs_layout_range range = { ++ .iomode = IOMODE_ANY, ++ .offset = 0, ++ .length = NFS4_MAX_UINT64, ++ }; + LIST_HEAD(tmp_list); + nfs4_stateid stateid; + int status = 0, empty; +@@ -1088,16 +1093,10 @@ _pnfs_return_layout(struct inode *ino) + pnfs_get_layout_hdr(lo); + empty = list_empty(&lo->plh_segs); + pnfs_clear_layoutcommit(ino, &tmp_list); +- pnfs_mark_matching_lsegs_return(lo, &tmp_list, NULL, 0); +- +- if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) { +- struct pnfs_layout_range range = { +- .iomode = IOMODE_ANY, +- .offset = 0, +- .length = NFS4_MAX_UINT64, +- }; ++ pnfs_mark_matching_lsegs_return(lo, &tmp_list, &range, 0); ++ ++ if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) + NFS_SERVER(ino)->pnfs_curr_ld->return_range(lo, &range); +- } + + /* Don't send a LAYOUTRETURN if list was initially empty */ + if (empty) { +diff --git a/fs/proc/base.c b/fs/proc/base.c +index b9e41832315a6..294fb8ee2ff46 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -2522,6 +2522,10 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, + ssize_t length; + struct task_struct *task = get_proc_task(inode); + ++ /* A task may only write when it was the opener. */ ++ if (file->f_cred != current_real_cred()) ++ return -EPERM; ++ + length = -ESRCH; + if (!task) + goto out_no_task; +diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h +index 4e4c35a6bfc5a..8dd365c654780 100644 +--- a/include/linux/hugetlb.h ++++ b/include/linux/hugetlb.h +@@ -93,7 +93,7 @@ void free_huge_page(struct page *page); + void hugetlb_fix_reserve_counts(struct inode *inode); + extern struct mutex *hugetlb_fault_mutex_table; + u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, +- pgoff_t idx, unsigned long address); ++ pgoff_t idx); + + pte_t *huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud); + +diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h +index 69111fa2e5780..3d0a12c5cdf52 100644 +--- a/include/linux/netfilter/x_tables.h ++++ b/include/linux/netfilter/x_tables.h +@@ -334,7 +334,7 @@ static inline unsigned int xt_write_recseq_begin(void) + * since addend is most likely 1 + */ + __this_cpu_add(xt_recseq.sequence, addend); +- smp_wmb(); ++ smp_mb(); + + return addend; + } +diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h +index 8470695e5dd78..9c8445f1af0cc 100644 +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -443,6 +443,9 @@ struct spi_master { + #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ + #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ + ++ /* flag indicating this is a non-devres managed controller */ ++ bool devm_allocated; ++ + /* + * on some hardware transfer / message size may be constrained + * the limit may depend on device transfer settings +diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h +index 28a0d7a8c1429..ba388549b38c1 100644 +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -4056,7 +4056,8 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); + * Return: 0 on success. Non-zero on error. + */ + int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, +- const u8 *addr, enum nl80211_iftype iftype); ++ const u8 *addr, enum nl80211_iftype iftype, ++ bool is_amsdu); + + /** + * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 +@@ -4068,7 +4069,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + enum nl80211_iftype iftype) + { +- return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype); ++ return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, false); + } + + /** +diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h +index 87499b6b35d6d..2ba054fe14ac1 100644 +--- a/include/net/nfc/nci_core.h ++++ b/include/net/nfc/nci_core.h +@@ -310,6 +310,7 @@ int nci_nfcc_loopback(struct nci_dev *ndev, void *data, size_t data_len, + struct sk_buff **resp); + + struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev); ++void nci_hci_deallocate(struct nci_dev *ndev); + int nci_hci_send_event(struct nci_dev *ndev, u8 gate, u8 event, + const u8 *param, size_t param_len); + int nci_hci_send_cmd(struct nci_dev *ndev, u8 gate, +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 9049e8613237f..b7215b0807ca6 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -3887,7 +3887,7 @@ backout_unlocked: + + #ifdef CONFIG_SMP + u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, +- pgoff_t idx, unsigned long address) ++ pgoff_t idx) + { + unsigned long key[2]; + u32 hash; +@@ -3895,7 +3895,7 @@ u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, + key[0] = (unsigned long) mapping; + key[1] = idx; + +- hash = jhash2((u32 *)&key, sizeof(key)/sizeof(u32), 0); ++ hash = jhash2((u32 *)&key, sizeof(key)/(sizeof(u32)), 0); + + return hash & (num_fault_mutexes - 1); + } +@@ -3905,7 +3905,7 @@ u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, + * return 0 and avoid the hashing overhead. + */ + u32 hugetlb_fault_mutex_hash(struct hstate *h, struct address_space *mapping, +- pgoff_t idx, unsigned long address) ++ pgoff_t idx) + { + return 0; + } +@@ -3950,7 +3950,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, + * get spurious allocation failures if two CPUs race to instantiate + * the same page in the page cache. + */ +- hash = hugetlb_fault_mutex_hash(h, mapping, idx, address); ++ hash = hugetlb_fault_mutex_hash(h, mapping, idx); + mutex_lock(&hugetlb_fault_mutex_table[hash]); + + entry = huge_ptep_get(ptep); +diff --git a/mm/vmstat.c b/mm/vmstat.c +index e60435d556e3d..d01a2b3c1b898 100644 +--- a/mm/vmstat.c ++++ b/mm/vmstat.c +@@ -1178,6 +1178,9 @@ static void pagetypeinfo_showfree_print(struct seq_file *m, + list_for_each(curr, &area->free_list[mtype]) + freecount++; + seq_printf(m, "%6lu ", freecount); ++ spin_unlock_irq(&zone->lock); ++ cond_resched(); ++ spin_lock_irq(&zone->lock); + } + seq_putc(m, '\n'); + } +diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c +index 1152ce34dad4a..0bb150e68c53f 100644 +--- a/net/bluetooth/cmtp/core.c ++++ b/net/bluetooth/cmtp/core.c +@@ -391,6 +391,11 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) + if (!(session->flags & BIT(CMTP_LOOPBACK))) { + err = cmtp_attach_device(session); + if (err < 0) { ++ /* Caller will call fput in case of failure, and so ++ * will cmtp_session kthread. ++ */ ++ get_file(session->sock->file); ++ + atomic_inc(&session->terminate); + wake_up_interruptible(sk_sleep(session->sock->sk)); + up_write(&cmtp_session_sem); +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index f904b9b240275..9a78b89690bd6 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1580,10 +1580,7 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + IPV6_TLV_PADN, 0 }; + + /* we assume size > sizeof(ra) here */ +- /* limit our allocations to order-0 page */ +- size = min_t(int, size, SKB_MAX_ORDER(0, 0)); + skb = sock_alloc_send_skb(sk, size, 1, &err); +- + if (!skb) + return NULL; + +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 9c20c53f6729e..21b35255ecc24 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -52,12 +52,6 @@ struct ieee80211_local; + #define IEEE80211_ENCRYPT_HEADROOM 8 + #define IEEE80211_ENCRYPT_TAILROOM 18 + +-/* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent +- * reception of at least three fragmented frames. This limit can be increased +- * by changing this define, at the cost of slower frame reassembly and +- * increased memory use (about 2 kB of RAM per entry). */ +-#define IEEE80211_FRAGMENT_MAX 4 +- + /* power level hasn't been configured (or set to automatic) */ + #define IEEE80211_UNSET_POWER_LEVEL INT_MIN + +@@ -88,18 +82,6 @@ struct ieee80211_local; + + #define IEEE80211_MAX_NAN_INSTANCE_ID 255 + +-struct ieee80211_fragment_entry { +- struct sk_buff_head skb_list; +- unsigned long first_frag_time; +- u16 seq; +- u16 extra_len; +- u16 last_frag; +- u8 rx_queue; +- bool check_sequential_pn; /* needed for CCMP/GCMP */ +- u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ +-}; +- +- + struct ieee80211_bss { + u32 device_ts_beacon, device_ts_presp; + +@@ -239,8 +221,15 @@ struct ieee80211_rx_data { + */ + int security_idx; + +- u32 tkip_iv32; +- u16 tkip_iv16; ++ union { ++ struct { ++ u32 iv32; ++ u16 iv16; ++ } tkip; ++ struct { ++ u8 pn[IEEE80211_CCMP_PN_LEN]; ++ } ccm_gcm; ++ }; + }; + + struct ieee80211_csa_settings { +@@ -869,9 +858,7 @@ struct ieee80211_sub_if_data { + + char name[IFNAMSIZ]; + +- /* Fragment table for host-based reassembly */ +- struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; +- unsigned int fragment_next; ++ struct ieee80211_fragment_cache frags; + + /* TID bitmap for NoAck policy */ + u16 noack_map; +@@ -2136,4 +2123,7 @@ extern const struct ethtool_ops ieee80211_ethtool_ops; + #define debug_noinline + #endif + ++void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache); ++void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache); ++ + #endif /* IEEE80211_I_H */ +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index 7d43e0085cfc7..deebf42c740e6 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -1120,16 +1120,12 @@ static void ieee80211_set_multicast_list(struct net_device *dev) + */ + static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) + { +- int i; +- + /* free extra data */ + ieee80211_free_keys(sdata, false); + + ieee80211_debugfs_remove_netdev(sdata); + +- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) +- __skb_queue_purge(&sdata->fragments[i].skb_list); +- sdata->fragment_next = 0; ++ ieee80211_destroy_frag_cache(&sdata->frags); + + if (ieee80211_vif_is_mesh(&sdata->vif)) + ieee80211_mesh_teardown_sdata(sdata); +@@ -1863,8 +1859,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, + sdata->wdev.wiphy = local->hw.wiphy; + sdata->local = local; + +- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) +- skb_queue_head_init(&sdata->fragments[i].skb_list); ++ ieee80211_init_frag_cache(&sdata->frags); + + INIT_LIST_HEAD(&sdata->key_list); + +diff --git a/net/mac80211/key.c b/net/mac80211/key.c +index 6e02f8dfce2b2..4e23f240f599e 100644 +--- a/net/mac80211/key.c ++++ b/net/mac80211/key.c +@@ -647,6 +647,7 @@ int ieee80211_key_link(struct ieee80211_key *key, + struct sta_info *sta) + { + struct ieee80211_local *local = sdata->local; ++ static atomic_t key_color = ATOMIC_INIT(0); + struct ieee80211_key *old_key; + int idx = key->conf.keyidx; + bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; +@@ -658,6 +659,12 @@ int ieee80211_key_link(struct ieee80211_key *key, + bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION; + int ret; + ++ /* ++ * Assign a unique ID to every key so we can easily prevent mixed ++ * key and fragment cache attacks. ++ */ ++ key->color = atomic_inc_return(&key_color); ++ + mutex_lock(&sdata->local->key_mtx); + + if (sta && pairwise) +diff --git a/net/mac80211/key.h b/net/mac80211/key.h +index 4aa20cef08595..2749a7d05e763 100644 +--- a/net/mac80211/key.h ++++ b/net/mac80211/key.h +@@ -127,6 +127,8 @@ struct ieee80211_key { + } debugfs; + #endif + ++ unsigned int color; ++ + /* + * key config, must be last because it contains key + * material as variable length member +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index c38d68131d02e..721caa5a5430f 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1873,19 +1873,34 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + return result; + } + ++void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cache->entries); i++) ++ skb_queue_head_init(&cache->entries[i].skb_list); ++} ++ ++void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cache->entries); i++) ++ __skb_queue_purge(&cache->entries[i].skb_list); ++} ++ + static inline struct ieee80211_fragment_entry * +-ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, ++ieee80211_reassemble_add(struct ieee80211_fragment_cache *cache, + unsigned int frag, unsigned int seq, int rx_queue, + struct sk_buff **skb) + { + struct ieee80211_fragment_entry *entry; + +- entry = &sdata->fragments[sdata->fragment_next++]; +- if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) +- sdata->fragment_next = 0; ++ entry = &cache->entries[cache->next++]; ++ if (cache->next >= IEEE80211_FRAGMENT_MAX) ++ cache->next = 0; + +- if (!skb_queue_empty(&entry->skb_list)) +- __skb_queue_purge(&entry->skb_list); ++ __skb_queue_purge(&entry->skb_list); + + __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ + *skb = NULL; +@@ -1900,14 +1915,14 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, + } + + static inline struct ieee80211_fragment_entry * +-ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, ++ieee80211_reassemble_find(struct ieee80211_fragment_cache *cache, + unsigned int frag, unsigned int seq, + int rx_queue, struct ieee80211_hdr *hdr) + { + struct ieee80211_fragment_entry *entry; + int i, idx; + +- idx = sdata->fragment_next; ++ idx = cache->next; + for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { + struct ieee80211_hdr *f_hdr; + +@@ -1915,7 +1930,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, + if (idx < 0) + idx = IEEE80211_FRAGMENT_MAX - 1; + +- entry = &sdata->fragments[idx]; ++ entry = &cache->entries[idx]; + if (skb_queue_empty(&entry->skb_list) || entry->seq != seq || + entry->rx_queue != rx_queue || + entry->last_frag + 1 != frag) +@@ -1942,16 +1957,27 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, + return NULL; + } + ++static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc) ++{ ++ return rx->key && ++ (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && ++ ieee80211_has_protected(fc); ++} ++ + static ieee80211_rx_result debug_noinline + ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + { ++ struct ieee80211_fragment_cache *cache = &rx->sdata->frags; + struct ieee80211_hdr *hdr; + u16 sc; + __le16 fc; + unsigned int frag, seq; + struct ieee80211_fragment_entry *entry; + struct sk_buff *skb; +- struct ieee80211_rx_status *status; ++ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + + hdr = (struct ieee80211_hdr *)rx->skb->data; + fc = hdr->frame_control; +@@ -1967,6 +1993,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + goto out_no_led; + } + ++ if (rx->sta) ++ cache = &rx->sta->frags; ++ + if (likely(!ieee80211_has_morefrags(fc) && frag == 0)) + goto out; + +@@ -1985,20 +2014,17 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + + if (frag == 0) { + /* This is the first fragment of a new frame. */ +- entry = ieee80211_reassemble_add(rx->sdata, frag, seq, ++ entry = ieee80211_reassemble_add(cache, frag, seq, + rx->seqno_idx, &(rx->skb)); +- if (rx->key && +- (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && +- ieee80211_has_protected(fc)) { ++ if (requires_sequential_pn(rx, fc)) { + int queue = rx->security_idx; + + /* Store CCMP/GCMP PN so that we can verify that the + * next fragment has a sequential PN value. + */ + entry->check_sequential_pn = true; ++ entry->is_protected = true; ++ entry->key_color = rx->key->color; + memcpy(entry->last_pn, + rx->key->u.ccmp.rx_pn[queue], + IEEE80211_CCMP_PN_LEN); +@@ -2010,6 +2036,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + sizeof(rx->key->u.gcmp.rx_pn[queue])); + BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN != + IEEE80211_GCMP_PN_LEN); ++ } else if (rx->key && ++ (ieee80211_has_protected(fc) || ++ (status->flag & RX_FLAG_DECRYPTED))) { ++ entry->is_protected = true; ++ entry->key_color = rx->key->color; + } + return RX_QUEUED; + } +@@ -2017,7 +2048,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + /* This is a fragment for a frame that should already be pending in + * fragment cache. Add this fragment to the end of the pending entry. + */ +- entry = ieee80211_reassemble_find(rx->sdata, frag, seq, ++ entry = ieee80211_reassemble_find(cache, frag, seq, + rx->seqno_idx, hdr); + if (!entry) { + I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); +@@ -2032,25 +2063,39 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + if (entry->check_sequential_pn) { + int i; + u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; +- int queue; + +- if (!rx->key || +- (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256)) ++ if (!requires_sequential_pn(rx, fc)) + return RX_DROP_UNUSABLE; ++ ++ /* Prevent mixed key and fragment cache attacks */ ++ if (entry->key_color != rx->key->color) ++ return RX_DROP_UNUSABLE; ++ + memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); + for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { + pn[i]++; + if (pn[i]) + break; + } +- queue = rx->security_idx; +- rpn = rx->key->u.ccmp.rx_pn[queue]; ++ ++ rpn = rx->ccm_gcm.pn; + if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN)) + return RX_DROP_UNUSABLE; + memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN); ++ } else if (entry->is_protected && ++ (!rx->key || ++ (!ieee80211_has_protected(fc) && ++ !(status->flag & RX_FLAG_DECRYPTED)) || ++ rx->key->color != entry->key_color)) { ++ /* Drop this as a mixed key or fragment cache attack, even ++ * if for TKIP Michael MIC should protect us, and WEP is a ++ * lost cause anyway. ++ */ ++ return RX_DROP_UNUSABLE; ++ } else if (entry->is_protected && rx->key && ++ entry->key_color != rx->key->color && ++ (status->flag & RX_FLAG_DECRYPTED)) { ++ return RX_DROP_UNUSABLE; + } + + skb_pull(rx->skb, ieee80211_hdrlen(fc)); +@@ -2239,13 +2284,13 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) + struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; + + /* +- * Allow EAPOL frames to us/the PAE group address regardless +- * of whether the frame was encrypted or not. ++ * Allow EAPOL frames to us/the PAE group address regardless of ++ * whether the frame was encrypted or not, and always disallow ++ * all other destination addresses for them. + */ +- if (ehdr->h_proto == rx->sdata->control_port_protocol && +- (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || +- ether_addr_equal(ehdr->h_dest, pae_group_addr))) +- return true; ++ if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol)) ++ return ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || ++ ether_addr_equal(ehdr->h_dest, pae_group_addr); + + if (ieee80211_802_1x_port_control(rx) || + ieee80211_drop_unencrypted(rx, fc)) +@@ -2285,6 +2330,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) + if ((sdata->vif.type == NL80211_IFTYPE_AP || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && + !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && ++ ehdr->h_proto != rx->sdata->control_port_protocol && + (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { + if (is_multicast_ether_addr(ehdr->h_dest)) { + /* +@@ -2337,9 +2383,30 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) + #endif + + if (skb) { ++ struct ethhdr *ehdr = (void *)skb_mac_header(skb); ++ + /* deliver to local stack */ + skb->protocol = eth_type_trans(skb, dev); + memset(skb->cb, 0, sizeof(skb->cb)); ++ ++ /* ++ * 802.1X over 802.11 requires that the authenticator address ++ * be used for EAPOL frames. However, 802.1X allows the use of ++ * the PAE group address instead. If the interface is part of ++ * a bridge and we pass the frame with the PAE group address, ++ * then the bridge will forward it to the network (even if the ++ * client was not associated yet), which isn't supposed to ++ * happen. ++ * To avoid that, rewrite the destination address to our own ++ * address, so that the authenticator (e.g. hostapd) will see ++ * the frame, but bridge won't forward it anywhere else. Note ++ * that due to earlier filtering, the only other address can ++ * be the PAE group address. ++ */ ++ if (unlikely(skb->protocol == sdata->control_port_protocol && ++ !ether_addr_equal(ehdr->h_dest, sdata->vif.addr))) ++ ether_addr_copy(ehdr->h_dest, sdata->vif.addr); ++ + if (rx->napi) + napi_gro_receive(rx->napi, skb); + else +@@ -2421,9 +2488,27 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) + + if (ieee80211_data_to_8023_exthdr(skb, ðhdr, + rx->sdata->vif.addr, +- rx->sdata->vif.type)) ++ rx->sdata->vif.type, ++ true)) + return RX_DROP_UNUSABLE; + ++ if (rx->key) { ++ /* ++ * We should not receive A-MSDUs on pre-HT connections, ++ * and HT connections cannot use old ciphers. Thus drop ++ * them, as in those cases we couldn't even have SPP ++ * A-MSDUs or such. ++ */ ++ switch (rx->key->conf.cipher) { ++ case WLAN_CIPHER_SUITE_WEP40: ++ case WLAN_CIPHER_SUITE_WEP104: ++ case WLAN_CIPHER_SUITE_TKIP: ++ return RX_DROP_UNUSABLE; ++ default: ++ break; ++ } ++ } ++ + ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, + rx->sdata->vif.type, + rx->local->hw.extra_tx_headroom, +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index bdcc6cb60b1c8..ded1264cf8e4b 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -366,6 +366,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, + + u64_stats_init(&sta->rx_stats.syncp); + ++ ieee80211_init_frag_cache(&sta->frags); ++ + sta->sta_state = IEEE80211_STA_NONE; + + /* Mark TID as unreserved */ +@@ -999,6 +1001,8 @@ static void __sta_info_destroy_part2(struct sta_info *sta) + rate_control_remove_sta_debugfs(sta); + ieee80211_sta_debugfs_remove(sta); + ++ ieee80211_destroy_frag_cache(&sta->frags); ++ + cleanup_single_sta(sta); + } + +diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h +index cc808ac783e5c..fd31c4db12821 100644 +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -391,6 +391,34 @@ struct ieee80211_sta_rx_stats { + u64 msdu[IEEE80211_NUM_TIDS + 1]; + }; + ++/* ++ * IEEE 802.11-2016 (10.6 "Defragmentation") recommends support for "concurrent ++ * reception of at least one MSDU per access category per associated STA" ++ * on APs, or "at least one MSDU per access category" on other interface types. ++ * ++ * This limit can be increased by changing this define, at the cost of slower ++ * frame reassembly and increased memory use while fragments are pending. ++ */ ++#define IEEE80211_FRAGMENT_MAX 4 ++ ++struct ieee80211_fragment_entry { ++ struct sk_buff_head skb_list; ++ unsigned long first_frag_time; ++ u16 seq; ++ u16 extra_len; ++ u16 last_frag; ++ u8 rx_queue; ++ u8 check_sequential_pn:1, /* needed for CCMP/GCMP */ ++ is_protected:1; ++ u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ ++ unsigned int key_color; ++}; ++ ++struct ieee80211_fragment_cache { ++ struct ieee80211_fragment_entry entries[IEEE80211_FRAGMENT_MAX]; ++ unsigned int next; ++}; ++ + /** + * struct sta_info - STA information + * +@@ -454,6 +482,7 @@ struct ieee80211_sta_rx_stats { + * @pcpu_rx_stats: per-CPU RX statistics, assigned only if the driver needs + * this (by advertising the USES_RSS hw flag) + * @status_stats: TX status statistics ++ * @frags: fragment cache + */ + struct sta_info { + /* General information, mostly static */ +@@ -551,6 +580,8 @@ struct sta_info { + + struct cfg80211_chan_def tdls_chandef; + ++ struct ieee80211_fragment_cache frags; ++ + /* keep last! */ + struct ieee80211_sta sta; + }; +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index c0529c4b60f82..7819a2507d395 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -162,8 +162,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + + update_iv: + /* update IV in key information to be able to detect replays */ +- rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip_iv32; +- rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip_iv16; ++ rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip.iv32; ++ rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip.iv16; + + return RX_CONTINUE; + +@@ -289,8 +289,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) + key, skb->data + hdrlen, + skb->len - hdrlen, rx->sta->sta.addr, + hdr->addr1, hwaccel, rx->security_idx, +- &rx->tkip_iv32, +- &rx->tkip_iv16); ++ &rx->tkip.iv32, ++ &rx->tkip.iv16); + if (res != TKIP_DECRYPT_OK) + return RX_DROP_UNUSABLE; + +@@ -548,6 +548,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, + } + + memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN); ++ if (unlikely(ieee80211_is_frag(hdr))) ++ memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); + } + + /* Remove CCMP header and MIC */ +@@ -777,6 +779,8 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) + } + + memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN); ++ if (unlikely(ieee80211_is_frag(hdr))) ++ memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); + } + + /* Remove GCMP header and MIC */ +diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c +index 059f9fa0f6c91..52e1632bfee8c 100644 +--- a/net/netfilter/x_tables.c ++++ b/net/netfilter/x_tables.c +@@ -1173,6 +1173,9 @@ xt_replace_table(struct xt_table *table, + smp_wmb(); + table->private = newinfo; + ++ /* make sure all cpus see new ->private value */ ++ smp_mb(); ++ + /* + * Even though table entries have now been swapped, other CPU's + * may still be using the old entries. This is okay, because +diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c +index 85a3d9ed4c290..bff6ba84d3979 100644 +--- a/net/nfc/nci/core.c ++++ b/net/nfc/nci/core.c +@@ -1188,6 +1188,7 @@ EXPORT_SYMBOL(nci_allocate_device); + void nci_free_device(struct nci_dev *ndev) + { + nfc_free_device(ndev->nfc_dev); ++ nci_hci_deallocate(ndev); + kfree(ndev); + } + EXPORT_SYMBOL(nci_free_device); +diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c +index a0ab26d535dca..5fae3f064ad0a 100644 +--- a/net/nfc/nci/hci.c ++++ b/net/nfc/nci/hci.c +@@ -798,3 +798,8 @@ struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev) + + return hdev; + } ++ ++void nci_hci_deallocate(struct nci_dev *ndev) ++{ ++ kfree(ndev->hci_dev); ++} +diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c +index 551cf193649e9..02ef78d2b3dff 100644 +--- a/net/sched/sch_dsmark.c ++++ b/net/sched/sch_dsmark.c +@@ -388,7 +388,8 @@ static void dsmark_reset(struct Qdisc *sch) + struct dsmark_qdisc_data *p = qdisc_priv(sch); + + pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p); +- qdisc_reset(p->q); ++ if (p->q) ++ qdisc_reset(p->q); + sch->qstats.backlog = 0; + sch->q.qlen = 0; + } +diff --git a/net/tipc/msg.c b/net/tipc/msg.c +index aeb4554dfddac..c1ab2ff2f6ace 100644 +--- a/net/tipc/msg.c ++++ b/net/tipc/msg.c +@@ -141,18 +141,13 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) + if (unlikely(head)) + goto err; + *buf = NULL; ++ if (skb_has_frag_list(frag) && __skb_linearize(frag)) ++ goto err; + frag = skb_unshare(frag, GFP_ATOMIC); + if (unlikely(!frag)) + goto err; + head = *headbuf = frag; + TIPC_SKB_CB(head)->tail = NULL; +- if (skb_is_nonlinear(head)) { +- skb_walk_frags(head, tail) { +- TIPC_SKB_CB(head)->tail = tail; +- } +- } else { +- skb_frag_list_init(head); +- } + return 0; + } + +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index 804cab8f95090..c1b9074f3325e 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -741,7 +741,10 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, + spin_lock_bh(&inputq->lock); + if (skb_peek(arrvq) == skb) { + skb_queue_splice_tail_init(&tmpq, inputq); +- __skb_dequeue(arrvq); ++ /* Decrease the skb's refcnt as increasing in the ++ * function tipc_skb_peek ++ */ ++ kfree_skb(__skb_dequeue(arrvq)); + } + spin_unlock_bh(&inputq->lock); + __skb_queue_purge(&tmpq); +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 262922cf6a0cc..939320571d71f 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -421,7 +421,8 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) + EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); + + int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, +- const u8 *addr, enum nl80211_iftype iftype) ++ const u8 *addr, enum nl80211_iftype iftype, ++ bool is_amsdu) + { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct { +@@ -509,7 +510,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); + tmp.h_proto = payload.proto; + +- if (likely((ether_addr_equal(payload.hdr, rfc1042_header) && ++ if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && + tmp.h_proto != htons(ETH_P_AARP) && + tmp.h_proto != htons(ETH_P_IPX)) || + ether_addr_equal(payload.hdr, bridge_tunnel_header))) +@@ -768,6 +769,9 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, + remaining = skb->len - offset; + if (subframe_len > remaining) + goto purge; ++ /* mitigate A-MSDU aggregation injection attacks */ ++ if (ether_addr_equal(eth.h_dest, rfc1042_header)) ++ goto purge; + + offset += sizeof(struct ethhdr); + last = remaining <= subframe_len + padding; +diff --git a/scripts/analyze_suspend.py b/scripts/analyze_suspend.py +index a0ba48fa2c5ea..edc4f1255f9ba 100755 +--- a/scripts/analyze_suspend.py ++++ b/scripts/analyze_suspend.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python + # + # Tool for analyzing suspend/resume timing + # Copyright (c) 2013, Intel Corporation. +diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter +index d9ff038c1b284..a650bea5ccddd 100755 +--- a/scripts/bloat-o-meter ++++ b/scripts/bloat-o-meter +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python3 + # + # Copyright 2004 Matt Mackall + # +diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl +index 9ca667bcaee95..594c55541b162 100755 +--- a/scripts/bootgraph.pl ++++ b/scripts/bootgraph.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + + # Copyright 2008, Intel Corporation + # +diff --git a/scripts/checkincludes.pl b/scripts/checkincludes.pl +index 97b2c6143fe4f..cfdfa02d4d923 100755 +--- a/scripts/checkincludes.pl ++++ b/scripts/checkincludes.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + # + # checkincludes: find/remove files included more than once + # +diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl +index b8f6165452771..32828fafcf5b1 100755 +--- a/scripts/checkstack.pl ++++ b/scripts/checkstack.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + + # Check the stack usage of functions + # +diff --git a/scripts/config b/scripts/config +index 73de17d396987..06ac9882e1de2 100755 +--- a/scripts/config ++++ b/scripts/config +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/usr/bin/env bash + # Manipulate options in a .config file from the command line + + myname=${0##*/} +diff --git a/scripts/diffconfig b/scripts/diffconfig +index 0db267d0adc92..19189f3c4a034 100755 +--- a/scripts/diffconfig ++++ b/scripts/diffconfig +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python3 + # + # diffconfig - a tool to compare .config files. + # +diff --git a/scripts/dtc/dt_to_config b/scripts/dtc/dt_to_config +index 9a248b505c585..5dfd1bff351f7 100755 +--- a/scripts/dtc/dt_to_config ++++ b/scripts/dtc/dt_to_config +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + + # Copyright 2016 by Frank Rowand + # Copyright 2016 by Gaurav Minocha +diff --git a/scripts/extract_xc3028.pl b/scripts/extract_xc3028.pl +index 47877deae6d7f..61d9b256c6581 100755 +--- a/scripts/extract_xc3028.pl ++++ b/scripts/extract_xc3028.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + + # Copyright (c) Mauro Carvalho Chehab + # Released under GPLv2 +diff --git a/scripts/get_dvb_firmware b/scripts/get_dvb_firmware +index 1a0a04125f713..f3f230225aba0 100755 +--- a/scripts/get_dvb_firmware ++++ b/scripts/get_dvb_firmware +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + # DVB firmware extractor + # + # (c) 2004 Andrew de Quincey +diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl +index c21d16328d3f2..70dcfb6b3de1c 100755 +--- a/scripts/markup_oops.pl ++++ b/scripts/markup_oops.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + + use File::Basename; + use Math::BigInt; +diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl +index 6943fa7cc95b6..f23d7be943948 100755 +--- a/scripts/profile2linkerlist.pl ++++ b/scripts/profile2linkerlist.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + + # + # Takes a (sorted) output of readprofile and turns it into a list suitable for +diff --git a/scripts/show_delta b/scripts/show_delta +index 5b365009e6a39..55c66dce6fc17 100755 +--- a/scripts/show_delta ++++ b/scripts/show_delta +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python + # + # show_deltas: Read list of printk messages instrumented with + # time data, and format with time deltas. +diff --git a/scripts/stackdelta b/scripts/stackdelta +index 48eabf2f48f85..20a79f19a111d 100755 +--- a/scripts/stackdelta ++++ b/scripts/stackdelta +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + + # Read two files produced by the stackusage script, and show the + # delta between them. +diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py +index db40fa04cd513..30f117dfab438 100755 +--- a/scripts/tracing/draw_functrace.py ++++ b/scripts/tracing/draw_functrace.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python + + """ + Copyright 2008 (c) Frederic Weisbecker +diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c +index 6df29fa30fb9d..9e449dd8da929 100644 +--- a/sound/soc/codecs/cs35l33.c ++++ b/sound/soc/codecs/cs35l33.c +@@ -1209,6 +1209,7 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client, + dev_err(&i2c_client->dev, + "CS35L33 Device ID (%X). Expected ID %X\n", + devid, CS35L33_CHIP_ID); ++ ret = -EINVAL; + goto err_enable; + } + +diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat +index 581278c584887..5e5797cc37572 100755 +--- a/tools/kvm/kvm_stat/kvm_stat ++++ b/tools/kvm/kvm_stat/kvm_stat +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python + # + # top-like utility for displaying kvm statistics + # +diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c +index 0619054bd7a0d..61fe3ce5862d5 100644 +--- a/tools/perf/pmu-events/jevents.c ++++ b/tools/perf/pmu-events/jevents.c +@@ -603,7 +603,7 @@ static int get_maxfds(void) + struct rlimit rlim; + + if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) +- return min((int)rlim.rlim_max / 2, 512); ++ return min(rlim.rlim_max / 2, (rlim_t)512); + + return 512; + } +diff --git a/tools/perf/python/tracepoint.py b/tools/perf/python/tracepoint.py +index eb4dbed57de7e..ce273c8b512b0 100755 +--- a/tools/perf/python/tracepoint.py ++++ b/tools/perf/python/tracepoint.py +@@ -1,4 +1,4 @@ +-#! /usr/bin/python ++#! /usr/bin/env python + # -*- python -*- + # -*- coding: utf-8 -*- + +diff --git a/tools/perf/python/twatch.py b/tools/perf/python/twatch.py +index c235c22b107ab..5a55b25f0b8c3 100755 +--- a/tools/perf/python/twatch.py ++++ b/tools/perf/python/twatch.py +@@ -1,4 +1,4 @@ +-#! /usr/bin/python ++#! /usr/bin/env python + # -*- python -*- + # -*- coding: utf-8 -*- + # twatch - Experimental use of the perf python interface +diff --git a/tools/perf/scripts/python/sched-migration.py b/tools/perf/scripts/python/sched-migration.py +index de66cb3b72c9e..dd3e7ae2a1af3 100644 +--- a/tools/perf/scripts/python/sched-migration.py ++++ b/tools/perf/scripts/python/sched-migration.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/env python + # + # Cpu task migration overview toy + # +diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py +index c8680984d2d66..163f38fbd79c0 100644 +--- a/tools/perf/util/setup.py ++++ b/tools/perf/util/setup.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python2 ++#!/usr/bin/env python2 + + from distutils.core import setup, Extension + from os import getenv +diff --git a/tools/testing/ktest/compare-ktest-sample.pl b/tools/testing/ktest/compare-ktest-sample.pl +index a373a5bfff683..c488e863d83f1 100755 +--- a/tools/testing/ktest/compare-ktest-sample.pl ++++ b/tools/testing/ktest/compare-ktest-sample.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/env perl + + open (IN,"ktest.pl"); + while () { diff --git a/patch/kernel/archive/meson64-4.9/patch-4.9.271-272.patch b/patch/kernel/archive/meson64-4.9/patch-4.9.271-272.patch new file mode 100644 index 0000000000..ede0c1e267 --- /dev/null +++ b/patch/kernel/archive/meson64-4.9/patch-4.9.271-272.patch @@ -0,0 +1,925 @@ +diff --git a/Makefile b/Makefile +index 4964c2494edb5..39aa8b66fc6ff 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 9 +-SUBLEVEL = 271 ++SUBLEVEL = 272 + EXTRAVERSION = + NAME = Roaring Lionus + +diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c +index 5962badb33462..b6fd2a21b015e 100644 +--- a/arch/arm64/kernel/traps.c ++++ b/arch/arm64/kernel/traps.c +@@ -543,14 +543,6 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) + } + #endif + +- if (show_unhandled_signals_ratelimited()) { +- pr_info("%s[%d]: syscall %d\n", current->comm, +- task_pid_nr(current), (int)regs->syscallno); +- dump_instr("", regs); +- if (user_mode(regs)) +- __show_regs(regs); +- } +- + return sys_ni_syscall(); + } + +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index 29078eaf18c9b..cbc7f177bbd8e 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -3412,7 +3412,7 @@ static int cr_interception(struct vcpu_svm *svm) + err = 0; + if (cr >= 16) { /* mov to cr */ + cr -= 16; +- val = kvm_register_read(&svm->vcpu, reg); ++ val = kvm_register_readl(&svm->vcpu, reg); + switch (cr) { + case 0: + if (!check_selective_cr0_intercepted(svm, val)) +@@ -3457,7 +3457,7 @@ static int cr_interception(struct vcpu_svm *svm) + kvm_queue_exception(&svm->vcpu, UD_VECTOR); + return 1; + } +- kvm_register_write(&svm->vcpu, reg, val); ++ kvm_register_writel(&svm->vcpu, reg, val); + } + kvm_complete_insn_gp(&svm->vcpu, err); + +@@ -3489,13 +3489,13 @@ static int dr_interception(struct vcpu_svm *svm) + if (dr >= 16) { /* mov to DRn */ + if (!kvm_require_dr(&svm->vcpu, dr - 16)) + return 1; +- val = kvm_register_read(&svm->vcpu, reg); ++ val = kvm_register_readl(&svm->vcpu, reg); + kvm_set_dr(&svm->vcpu, dr - 16, val); + } else { + if (!kvm_require_dr(&svm->vcpu, dr)) + return 1; + kvm_get_dr(&svm->vcpu, dr, &val); +- kvm_register_write(&svm->vcpu, reg, val); ++ kvm_register_writel(&svm->vcpu, reg, val); + } + + skip_emulated_instruction(&svm->vcpu); +diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c +index c0e54396f2502..dc8d2603612ed 100644 +--- a/drivers/firmware/efi/cper.c ++++ b/drivers/firmware/efi/cper.c +@@ -257,8 +257,7 @@ static int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg) + if (!msg || !(mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE)) + return 0; + +- n = 0; +- len = CPER_REC_LEN - 1; ++ len = CPER_REC_LEN; + dmi_memdev_name(mem->mem_dev_handle, &bank, &device); + if (bank && device) + n = snprintf(msg, len, "DIMM location: %s %s ", bank, device); +@@ -267,7 +266,6 @@ static int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg) + "DIMM location: not present. DMI handle: 0x%.4x ", + mem->mem_dev_handle); + +- msg[n] = '\0'; + return n; + } + +diff --git a/drivers/firmware/efi/memattr.c b/drivers/firmware/efi/memattr.c +index 9faa09e7c31f1..c2b991b9fa9e6 100644 +--- a/drivers/firmware/efi/memattr.c ++++ b/drivers/firmware/efi/memattr.c +@@ -68,11 +68,6 @@ static bool entry_is_valid(const efi_memory_desc_t *in, efi_memory_desc_t *out) + return false; + } + +- if (!(in->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP))) { +- pr_warn("Entry attributes invalid: RO and XP bits both cleared\n"); +- return false; +- } +- + if (PAGE_SIZE > EFI_PAGE_SIZE && + (!PAGE_ALIGNED(in->phys_addr) || + !PAGE_ALIGNED(in->num_pages << EFI_PAGE_SHIFT))) { +diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c +index 606fd875740c0..800c477dd0761 100644 +--- a/drivers/hid/i2c-hid/i2c-hid-core.c ++++ b/drivers/hid/i2c-hid/i2c-hid-core.c +@@ -1157,8 +1157,8 @@ static int i2c_hid_probe(struct i2c_client *client, + hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); + hid->product = le16_to_cpu(ihid->hdesc.wProductID); + +- snprintf(hid->name, sizeof(hid->name), "%s %04hX:%04hX", +- client->name, hid->vendor, hid->product); ++ snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", ++ client->name, (u16)hid->vendor, (u16)hid->product); + strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys)); + + ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); +diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c +index 08174d341f4a1..bc75f1efa0f4c 100644 +--- a/drivers/hid/usbhid/hid-pidff.c ++++ b/drivers/hid/usbhid/hid-pidff.c +@@ -1304,6 +1304,7 @@ int hid_pidff_init(struct hid_device *hid) + + if (pidff->pool[PID_DEVICE_MANAGED_POOL].value && + pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) { ++ error = -EPERM; + hid_notice(hid, + "device does not support device managed pool\n"); + goto fail; +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 148e1ff2e5e0e..77dadbe1a4464 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -4262,7 +4262,6 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp) + + pf->fw_fid = le16_to_cpu(resp->fid); + pf->port_id = le16_to_cpu(resp->port_id); +- bp->dev->dev_port = pf->port_id; + memcpy(pf->mac_addr, resp->mac_address, ETH_ALEN); + memcpy(bp->dev->dev_addr, pf->mac_addr, ETH_ALEN); + pf->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx); +diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c +index d418542924e16..297d3f599efda 100644 +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -1563,6 +1563,15 @@ cdc_ncm_speed_change(struct usbnet *dev, + uint32_t rx_speed = le32_to_cpu(data->DLBitRRate); + uint32_t tx_speed = le32_to_cpu(data->ULBitRate); + ++ /* if the speed hasn't changed, don't report it. ++ * RTL8156 shipped before 2021 sends notification about every 32ms. ++ */ ++ if (dev->rx_speed == rx_speed && dev->tx_speed == tx_speed) ++ return; ++ ++ dev->rx_speed = rx_speed; ++ dev->tx_speed = tx_speed; ++ + /* + * Currently the USB-NET API does not support reporting the actual + * device speed. Do print it instead. +@@ -1606,7 +1615,8 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) + * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be + * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. + */ +- usbnet_link_change(dev, !!event->wValue, 0); ++ if (netif_carrier_ok(dev->net) != !!event->wValue) ++ usbnet_link_change(dev, !!event->wValue, 0); + break; + + case USB_CDC_NOTIFY_SPEED_CHANGE: +diff --git a/drivers/vfio/pci/Kconfig b/drivers/vfio/pci/Kconfig +index 24ee2605b9f04..0da884bfc7a80 100644 +--- a/drivers/vfio/pci/Kconfig ++++ b/drivers/vfio/pci/Kconfig +@@ -1,6 +1,7 @@ + config VFIO_PCI + tristate "VFIO support for PCI devices" + depends on VFIO && PCI && EVENTFD ++ depends on MMU + select VFIO_VIRQFD + select IRQ_BYPASS_MANAGER + help +diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c +index f3c2de04b20d3..5b0f09b211bee 100644 +--- a/drivers/vfio/pci/vfio_pci_config.c ++++ b/drivers/vfio/pci/vfio_pci_config.c +@@ -1576,7 +1576,7 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev) + if (len == 0xFF) { + len = vfio_ext_cap_len(vdev, ecap, epos); + if (len < 0) +- return ret; ++ return len; + } + } + +diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c +index d143d08c4f0fe..9b1b6c1e218dc 100644 +--- a/drivers/vfio/platform/vfio_platform_common.c ++++ b/drivers/vfio/platform/vfio_platform_common.c +@@ -288,7 +288,7 @@ err_irq: + vfio_platform_regions_cleanup(vdev); + err_reg: + mutex_unlock(&driver_lock); +- module_put(THIS_MODULE); ++ module_put(vdev->parent_module); + return ret; + } + +diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c +index c99f8bb1c56c4..e6c7509a3d873 100644 +--- a/drivers/xen/xen-pciback/vpci.c ++++ b/drivers/xen/xen-pciback/vpci.c +@@ -68,7 +68,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, + struct pci_dev *dev, int devid, + publish_pci_dev_cb publish_cb) + { +- int err = 0, slot, func = -1; ++ int err = 0, slot, func = PCI_FUNC(dev->devfn); + struct pci_dev_entry *t, *dev_entry; + struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; + +@@ -93,23 +93,26 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, + + /* + * Keep multi-function devices together on the virtual PCI bus, except +- * virtual functions. ++ * that we want to keep virtual functions at func 0 on their own. They ++ * aren't multi-function devices and hence their presence at func 0 ++ * may cause guests to not scan the other functions. + */ +- if (!dev->is_virtfn) { ++ if (!dev->is_virtfn || func) { + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { + if (list_empty(&vpci_dev->dev_list[slot])) + continue; + + t = list_entry(list_first(&vpci_dev->dev_list[slot]), + struct pci_dev_entry, list); ++ if (t->dev->is_virtfn && !PCI_FUNC(t->dev->devfn)) ++ continue; + + if (match_slot(dev, t->dev)) { + pr_info("vpci: %s: assign to virtual slot %d func %d\n", + pci_name(dev), slot, +- PCI_FUNC(dev->devfn)); ++ func); + list_add_tail(&dev_entry->list, + &vpci_dev->dev_list[slot]); +- func = PCI_FUNC(dev->devfn); + goto unlock; + } + } +@@ -122,7 +125,6 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, + pci_name(dev), slot); + list_add_tail(&dev_entry->list, + &vpci_dev->dev_list[slot]); +- func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn); + goto unlock; + } + } +diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c +index 4f919628137cb..374d91830a900 100644 +--- a/fs/btrfs/file-item.c ++++ b/fs/btrfs/file-item.c +@@ -608,7 +608,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + u64 end_byte = bytenr + len; + u64 csum_end; + struct extent_buffer *leaf; +- int ret; ++ int ret = 0; + u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); + int blocksize_bits = root->fs_info->sb->s_blocksize_bits; + +@@ -626,6 +626,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + path->leave_spinning = 1; + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); + if (ret > 0) { ++ ret = 0; + if (path->slots[0] == 0) + break; + path->slots[0]--; +@@ -656,7 +657,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + if (key.offset >= bytenr && csum_end <= end_byte) { + ret = btrfs_del_item(trans, root, path); + if (ret) +- goto out; ++ break; + if (key.offset == bytenr) + break; + } else if (key.offset < bytenr && csum_end > end_byte) { +@@ -700,8 +701,9 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + ret = btrfs_split_item(trans, root, path, &key, offset); + if (ret && ret != -EAGAIN) { + btrfs_abort_transaction(trans, ret); +- goto out; ++ break; + } ++ ret = 0; + + key.offset = end_byte - 1; + } else { +@@ -711,8 +713,6 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + } + btrfs_release_path(path); + } +- ret = 0; +-out: + btrfs_free_path(path); + return ret; + } +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 5c86fecaf167e..11ecd798864c8 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -1529,6 +1529,7 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + break; + + if (ret == 1) { ++ ret = 0; + if (path->slots[0] == 0) + break; + path->slots[0]--; +@@ -1541,17 +1542,19 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + + ret = btrfs_del_item(trans, root, path); + if (ret) +- goto out; ++ break; + + btrfs_release_path(path); + inode = read_one_inode(root, key.offset); +- if (!inode) +- return -EIO; ++ if (!inode) { ++ ret = -EIO; ++ break; ++ } + + ret = fixup_inode_link_count(trans, root, inode); + iput(inode); + if (ret) +- goto out; ++ break; + + /* + * fixup on a directory may create new entries, +@@ -1560,8 +1563,6 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + */ + key.offset = (u64)-1; + } +- ret = 0; +-out: + btrfs_release_path(path); + return ret; + } +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 7f291b7be7f3a..e2f31aee67c28 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -3274,7 +3274,10 @@ static int ext4_split_extent_at(handle_t *handle, + ext4_ext_mark_unwritten(ex2); + + err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags); +- if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { ++ if (err != -ENOSPC && err != -EDQUOT) ++ goto out; ++ ++ if (EXT4_EXT_MAY_ZEROOUT & split_flag) { + if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { + if (split_flag & EXT4_EXT_DATA_VALID1) { + err = ext4_ext_zeroout(inode, ex2); +@@ -3300,30 +3303,30 @@ static int ext4_split_extent_at(handle_t *handle, + ext4_ext_pblock(&orig_ex)); + } + +- if (err) +- goto fix_extent_len; +- /* update the extent length and mark as initialized */ +- ex->ee_len = cpu_to_le16(ee_len); +- ext4_ext_try_to_merge(handle, inode, path, ex); +- err = ext4_ext_dirty(handle, inode, path + path->p_depth); +- if (err) +- goto fix_extent_len; +- +- /* update extent status tree */ +- err = ext4_zeroout_es(inode, &zero_ex); +- +- goto out; +- } else if (err) +- goto fix_extent_len; +- +-out: +- ext4_ext_show_leaf(inode, path); +- return err; ++ if (!err) { ++ /* update the extent length and mark as initialized */ ++ ex->ee_len = cpu_to_le16(ee_len); ++ ext4_ext_try_to_merge(handle, inode, path, ex); ++ err = ext4_ext_dirty(handle, inode, path + path->p_depth); ++ if (!err) ++ /* update extent status tree */ ++ err = ext4_zeroout_es(inode, &zero_ex); ++ /* If we failed at this point, we don't know in which ++ * state the extent tree exactly is so don't try to fix ++ * length of the original extent as it may do even more ++ * damage. ++ */ ++ goto out; ++ } ++ } + + fix_extent_len: + ex->ee_len = orig_ex.ee_len; + ext4_ext_dirty(handle, inode, path + path->p_depth); + return err; ++out: ++ ext4_ext_show_leaf(inode, path); ++ return err; + } + + /* +diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c +index c17285df12be2..3aa4441f5ab50 100644 +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -1838,6 +1838,45 @@ out: + return ret; + } + ++/* ++ * zero out partial blocks of one cluster. ++ * ++ * start: file offset where zero starts, will be made upper block aligned. ++ * len: it will be trimmed to the end of current cluster if "start + len" ++ * is bigger than it. ++ */ ++static int ocfs2_zeroout_partial_cluster(struct inode *inode, ++ u64 start, u64 len) ++{ ++ int ret; ++ u64 start_block, end_block, nr_blocks; ++ u64 p_block, offset; ++ u32 cluster, p_cluster, nr_clusters; ++ struct super_block *sb = inode->i_sb; ++ u64 end = ocfs2_align_bytes_to_clusters(sb, start); ++ ++ if (start + len < end) ++ end = start + len; ++ ++ start_block = ocfs2_blocks_for_bytes(sb, start); ++ end_block = ocfs2_blocks_for_bytes(sb, end); ++ nr_blocks = end_block - start_block; ++ if (!nr_blocks) ++ return 0; ++ ++ cluster = ocfs2_bytes_to_clusters(sb, start); ++ ret = ocfs2_get_clusters(inode, cluster, &p_cluster, ++ &nr_clusters, NULL); ++ if (ret) ++ return ret; ++ if (!p_cluster) ++ return 0; ++ ++ offset = start_block - ocfs2_clusters_to_blocks(sb, cluster); ++ p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset; ++ return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS); ++} ++ + /* + * Parts of this function taken from xfs_change_file_space() + */ +@@ -1848,7 +1887,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + { + int ret; + s64 llen; +- loff_t size; ++ loff_t size, orig_isize; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + struct buffer_head *di_bh = NULL; + handle_t *handle; +@@ -1879,6 +1918,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + goto out_inode_unlock; + } + ++ orig_isize = i_size_read(inode); + switch (sr->l_whence) { + case 0: /*SEEK_SET*/ + break; +@@ -1886,7 +1926,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + sr->l_start += f_pos; + break; + case 2: /*SEEK_END*/ +- sr->l_start += i_size_read(inode); ++ sr->l_start += orig_isize; + break; + default: + ret = -EINVAL; +@@ -1940,6 +1980,14 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + default: + ret = -EINVAL; + } ++ ++ /* zeroout eof blocks in the cluster. */ ++ if (!ret && change_size && orig_isize < size) { ++ ret = ocfs2_zeroout_partial_cluster(inode, orig_isize, ++ size - orig_isize); ++ if (!ret) ++ i_size_write(inode, size); ++ } + up_write(&OCFS2_I(inode)->ip_alloc_sem); + if (ret) { + mlog_errno(ret); +@@ -1956,9 +2004,6 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + goto out_inode_unlock; + } + +- if (change_size && i_size_read(inode) < size) +- i_size_write(inode, size); +- + inode->i_ctime = inode->i_mtime = current_time(inode); + ret = ocfs2_mark_inode_dirty(handle, inode, di_bh); + if (ret < 0) +diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h +index fde7550754df6..52f47c2944f84 100644 +--- a/include/linux/usb/usbnet.h ++++ b/include/linux/usb/usbnet.h +@@ -80,6 +80,8 @@ struct usbnet { + # define EVENT_LINK_CHANGE 11 + # define EVENT_SET_RX_MODE 12 + # define EVENT_NO_IP_ALIGN 13 ++ u32 rx_speed; /* in bps - NOT Mbps */ ++ u32 tx_speed; /* in bps - NOT Mbps */ + }; + + static inline struct usb_driver *driver_of(struct usb_interface *intf) +diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h +index 028b754ae9b17..0baf2e21a533f 100644 +--- a/include/net/caif/caif_dev.h ++++ b/include/net/caif/caif_dev.h +@@ -119,7 +119,7 @@ void caif_free_client(struct cflayer *adap_layer); + * The link_support layer is used to add any Link Layer specific + * framing. + */ +-void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, ++int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + struct cflayer *link_support, int head_room, + struct cflayer **layer, int (**rcv_func)( + struct sk_buff *, struct net_device *, +diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h +index 70bfd017581fb..219094ace893c 100644 +--- a/include/net/caif/cfcnfg.h ++++ b/include/net/caif/cfcnfg.h +@@ -62,7 +62,7 @@ void cfcnfg_remove(struct cfcnfg *cfg); + * @fcs: Specify if checksum is used in CAIF Framing Layer. + * @head_room: Head space needed by link specific protocol. + */ +-void ++int + cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + struct net_device *dev, struct cflayer *phy_layer, + enum cfcnfg_phy_preference pref, +diff --git a/include/net/caif/cfserl.h b/include/net/caif/cfserl.h +index b5b020f3c72eb..bc3fae07a25f9 100644 +--- a/include/net/caif/cfserl.h ++++ b/include/net/caif/cfserl.h +@@ -9,4 +9,5 @@ + #include + + struct cflayer *cfserl_create(int instance, bool use_stx); ++void cfserl_release(struct cflayer *layer); + #endif +diff --git a/init/main.c b/init/main.c +index 7ad08957dd180..9e057314a15f3 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -1005,7 +1005,7 @@ static noinline void __init kernel_init_freeable(void) + */ + set_cpus_allowed_ptr(current, cpu_all_mask); + +- cad_pid = task_pid(current); ++ cad_pid = get_pid(task_pid(current)); + + smp_prepare_cpus(setup_max_cpus); + +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 02f44a408edbd..839c534bdcdb9 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -1422,8 +1422,13 @@ static int hci_dev_do_open(struct hci_dev *hdev) + } else { + /* Init failed, cleanup */ + flush_work(&hdev->tx_work); +- flush_work(&hdev->cmd_work); ++ ++ /* Since hci_rx_work() is possible to awake new cmd_work ++ * it should be flushed first to avoid unexpected call of ++ * hci_cmd_work() ++ */ + flush_work(&hdev->rx_work); ++ flush_work(&hdev->cmd_work); + + skb_queue_purge(&hdev->cmd_q); + skb_queue_purge(&hdev->rx_q); +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index 44b3146c61175..35f5585188de7 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -750,7 +750,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) + /* Detach sockets from device */ + read_lock(&hci_sk_list.lock); + sk_for_each(sk, &hci_sk_list.head) { +- bh_lock_sock_nested(sk); ++ lock_sock(sk); + if (hci_pi(sk)->hdev == hdev) { + hci_pi(sk)->hdev = NULL; + sk->sk_err = EPIPE; +@@ -759,7 +759,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) + + hci_dev_put(hdev); + } +- bh_unlock_sock(sk); ++ release_sock(sk); + } + read_unlock(&hci_sk_list.lock); + } +diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c +index a0443d40d677c..a28ffbbf7450c 100644 +--- a/net/caif/caif_dev.c ++++ b/net/caif/caif_dev.c +@@ -303,7 +303,7 @@ static void dev_flowctrl(struct net_device *dev, int on) + caifd_put(caifd); + } + +-void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, ++int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + struct cflayer *link_support, int head_room, + struct cflayer **layer, + int (**rcv_func)(struct sk_buff *, struct net_device *, +@@ -314,11 +314,12 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + enum cfcnfg_phy_preference pref; + struct cfcnfg *cfg = get_cfcnfg(dev_net(dev)); + struct caif_device_entry_list *caifdevs; ++ int res; + + caifdevs = caif_device_list(dev_net(dev)); + caifd = caif_device_alloc(dev); + if (!caifd) +- return; ++ return -ENOMEM; + *layer = &caifd->layer; + spin_lock_init(&caifd->flow_lock); + +@@ -340,7 +341,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + sizeof(caifd->layer.name) - 1); + caifd->layer.name[sizeof(caifd->layer.name) - 1] = 0; + caifd->layer.transmit = transmit; +- cfcnfg_add_phy_layer(cfg, ++ res = cfcnfg_add_phy_layer(cfg, + dev, + &caifd->layer, + pref, +@@ -350,6 +351,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + mutex_unlock(&caifdevs->lock); + if (rcv_func) + *rcv_func = receive; ++ return res; + } + EXPORT_SYMBOL(caif_enroll_dev); + +@@ -364,6 +366,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, + struct cflayer *layer, *link_support; + int head_room = 0; + struct caif_device_entry_list *caifdevs; ++ int res; + + cfg = get_cfcnfg(dev_net(dev)); + caifdevs = caif_device_list(dev_net(dev)); +@@ -389,8 +392,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, + break; + } + } +- caif_enroll_dev(dev, caifdev, link_support, head_room, ++ res = caif_enroll_dev(dev, caifdev, link_support, head_room, + &layer, NULL); ++ if (res) ++ cfserl_release(link_support); + caifdev->flowctrl = dev_flowctrl; + break; + +diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c +index 5cd44f001f647..485dde566c1a9 100644 +--- a/net/caif/caif_usb.c ++++ b/net/caif/caif_usb.c +@@ -116,6 +116,11 @@ static struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN], + return (struct cflayer *) this; + } + ++static void cfusbl_release(struct cflayer *layer) ++{ ++ kfree(layer); ++} ++ + static struct packet_type caif_usb_type __read_mostly = { + .type = cpu_to_be16(ETH_P_802_EX1), + }; +@@ -128,6 +133,7 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, + struct cflayer *layer, *link_support; + struct usbnet *usbnet; + struct usb_device *usbdev; ++ int res; + + /* Check whether we have a NCM device, and find its VID/PID. */ + if (!(dev->dev.parent && dev->dev.parent->driver && +@@ -170,8 +176,11 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, + if (dev->num_tx_queues > 1) + pr_warn("USB device uses more than one tx queue\n"); + +- caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN, ++ res = caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN, + &layer, &caif_usb_type.func); ++ if (res) ++ goto err; ++ + if (!pack_added) + dev_add_pack(&caif_usb_type); + pack_added = true; +@@ -181,6 +190,9 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, + layer->name[sizeof(layer->name) - 1] = 0; + + return 0; ++err: ++ cfusbl_release(link_support); ++ return res; + } + + static struct notifier_block caif_device_notifier = { +diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c +index fa39fc2987086..c45b531a6cd5c 100644 +--- a/net/caif/cfcnfg.c ++++ b/net/caif/cfcnfg.c +@@ -455,7 +455,7 @@ unlock: + rcu_read_unlock(); + } + +-void ++int + cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + struct net_device *dev, struct cflayer *phy_layer, + enum cfcnfg_phy_preference pref, +@@ -464,7 +464,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + { + struct cflayer *frml; + struct cfcnfg_phyinfo *phyinfo = NULL; +- int i; ++ int i, res = 0; + u8 phyid; + + mutex_lock(&cnfg->lock); +@@ -478,12 +478,15 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + goto got_phyid; + } + pr_warn("Too many CAIF Link Layers (max 6)\n"); ++ res = -EEXIST; + goto out; + + got_phyid: + phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC); +- if (!phyinfo) ++ if (!phyinfo) { ++ res = -ENOMEM; + goto out_err; ++ } + + phy_layer->id = phyid; + phyinfo->pref = pref; +@@ -497,8 +500,10 @@ got_phyid: + + frml = cffrml_create(phyid, fcs); + +- if (!frml) ++ if (!frml) { ++ res = -ENOMEM; + goto out_err; ++ } + phyinfo->frm_layer = frml; + layer_set_up(frml, cnfg->mux); + +@@ -516,11 +521,12 @@ got_phyid: + list_add_rcu(&phyinfo->node, &cnfg->phys); + out: + mutex_unlock(&cnfg->lock); +- return; ++ return res; + + out_err: + kfree(phyinfo); + mutex_unlock(&cnfg->lock); ++ return res; + } + EXPORT_SYMBOL(cfcnfg_add_phy_layer); + +diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c +index ce60f06d76de3..af1e1e36dc90a 100644 +--- a/net/caif/cfserl.c ++++ b/net/caif/cfserl.c +@@ -31,6 +31,11 @@ static int cfserl_transmit(struct cflayer *layr, struct cfpkt *pkt); + static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, + int phyid); + ++void cfserl_release(struct cflayer *layer) ++{ ++ kfree(layer); ++} ++ + struct cflayer *cfserl_create(int instance, bool use_stx) + { + struct cfserl *this = kzalloc(sizeof(struct cfserl), GFP_ATOMIC); +diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c +index c0930b9fe848b..7531cb1665d2b 100644 +--- a/net/ieee802154/nl-mac.c ++++ b/net/ieee802154/nl-mac.c +@@ -688,8 +688,10 @@ int ieee802154_llsec_getparams(struct sk_buff *skb, struct genl_info *info) + nla_put_u8(msg, IEEE802154_ATTR_LLSEC_SECLEVEL, params.out_level) || + nla_put_u32(msg, IEEE802154_ATTR_LLSEC_FRAME_COUNTER, + be32_to_cpu(params.frame_counter)) || +- ieee802154_llsec_fill_key_id(msg, ¶ms.out_key)) ++ ieee802154_llsec_fill_key_id(msg, ¶ms.out_key)) { ++ rc = -ENOBUFS; + goto out_free; ++ } + + dev_put(dev); + +diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c +index 77d73014bde31..11f53dc0c1c09 100644 +--- a/net/ieee802154/nl-phy.c ++++ b/net/ieee802154/nl-phy.c +@@ -249,8 +249,10 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) + } + + if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || +- nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) ++ nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) { ++ rc = -EMSGSIZE; + goto nla_put_failure; ++ } + dev_put(dev); + + wpan_phy_put(phy); +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index ba9e711f7e3d6..4e08305a55c48 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -1256,7 +1256,7 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, + ip_vs_addr_copy(svc->af, &svc->addr, &u->addr); + svc->port = u->port; + svc->fwmark = u->fwmark; +- svc->flags = u->flags; ++ svc->flags = u->flags & ~IP_VS_SVC_F_HASHED; + svc->timeout = u->timeout * HZ; + svc->netmask = u->netmask; + svc->ipvs = ipvs; +diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c +index 8396dc8ee2474..babe42ff3eecf 100644 +--- a/net/netfilter/nfnetlink_cthelper.c ++++ b/net/netfilter/nfnetlink_cthelper.c +@@ -355,10 +355,14 @@ static int + nfnl_cthelper_update(const struct nlattr * const tb[], + struct nf_conntrack_helper *helper) + { ++ u32 size; + int ret; + +- if (tb[NFCTH_PRIV_DATA_LEN]) +- return -EBUSY; ++ if (tb[NFCTH_PRIV_DATA_LEN]) { ++ size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN])); ++ if (size != helper->data_len) ++ return -EBUSY; ++ } + + if (tb[NFCTH_POLICY]) { + ret = nfnl_cthelper_update_policy(helper, tb[NFCTH_POLICY]); +diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c +index 22e340a9049c8..92c6fbfd51f79 100644 +--- a/net/nfc/llcp_sock.c ++++ b/net/nfc/llcp_sock.c +@@ -121,6 +121,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) + if (!llcp_sock->service_name) { + nfc_llcp_local_put(llcp_sock->local); + llcp_sock->local = NULL; ++ llcp_sock->dev = NULL; + ret = -ENOMEM; + goto put_dev; + } +@@ -130,6 +131,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) + llcp_sock->local = NULL; + kfree(llcp_sock->service_name); + llcp_sock->service_name = NULL; ++ llcp_sock->dev = NULL; + ret = -EADDRINUSE; + goto put_dev; + } +diff --git a/sound/core/timer.c b/sound/core/timer.c +index f8a4b2a2f8f6b..6475b85599364 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -488,9 +488,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) + return; + if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) + return; ++ event += 10; /* convert to SNDRV_TIMER_EVENT_MXXX */ + list_for_each_entry(ts, &ti->slave_active_head, active_list) + if (ts->ccallback) +- ts->ccallback(ts, event + 100, &tstamp, resolution); ++ ts->ccallback(ts, event, &tstamp, resolution); + } + + /* start/continue a master timer */ diff --git a/patch/kernel/archive/odroidxu4-5.4/patch-5.4.123-124.patch b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.123-124.patch new file mode 100644 index 0000000000..5c39808b6d --- /dev/null +++ b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.123-124.patch @@ -0,0 +1,5657 @@ +diff --git a/Documentation/userspace-api/seccomp_filter.rst b/Documentation/userspace-api/seccomp_filter.rst +index bd9165241b6c8..6efb41cc80725 100644 +--- a/Documentation/userspace-api/seccomp_filter.rst ++++ b/Documentation/userspace-api/seccomp_filter.rst +@@ -250,14 +250,14 @@ Users can read via ``ioctl(SECCOMP_IOCTL_NOTIF_RECV)`` (or ``poll()``) on a + seccomp notification fd to receive a ``struct seccomp_notif``, which contains + five members: the input length of the structure, a unique-per-filter ``id``, + the ``pid`` of the task which triggered this request (which may be 0 if the +-task is in a pid ns not visible from the listener's pid namespace), a ``flags`` +-member which for now only has ``SECCOMP_NOTIF_FLAG_SIGNALED``, representing +-whether or not the notification is a result of a non-fatal signal, and the +-``data`` passed to seccomp. Userspace can then make a decision based on this +-information about what to do, and ``ioctl(SECCOMP_IOCTL_NOTIF_SEND)`` a +-response, indicating what should be returned to userspace. The ``id`` member of +-``struct seccomp_notif_resp`` should be the same ``id`` as in ``struct +-seccomp_notif``. ++task is in a pid ns not visible from the listener's pid namespace). The ++notification also contains the ``data`` passed to seccomp, and a filters flag. ++The structure should be zeroed out prior to calling the ioctl. ++ ++Userspace can then make a decision based on this information about what to do, ++and ``ioctl(SECCOMP_IOCTL_NOTIF_SEND)`` a response, indicating what should be ++returned to userspace. The ``id`` member of ``struct seccomp_notif_resp`` should ++be the same ``id`` as in ``struct seccomp_notif``. + + It is worth noting that ``struct seccomp_data`` contains the values of register + arguments to the syscall, but does not contain pointers to memory. The task's +diff --git a/Makefile b/Makefile +index d3f7a032f080b..22668742d3d04 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 123 ++SUBLEVEL = 124 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/mips/alchemy/board-xxs1500.c b/arch/mips/alchemy/board-xxs1500.c +index c67dfe1f49971..ec35aedc7727d 100644 +--- a/arch/mips/alchemy/board-xxs1500.c ++++ b/arch/mips/alchemy/board-xxs1500.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + + const char *get_system_type(void) +diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c +index 59b23095bfbb4..4e38a905ab386 100644 +--- a/arch/mips/ralink/of.c ++++ b/arch/mips/ralink/of.c +@@ -8,6 +8,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -25,6 +26,7 @@ + + __iomem void *rt_sysc_membase; + __iomem void *rt_memc_membase; ++EXPORT_SYMBOL_GPL(rt_sysc_membase); + + __iomem void *plat_of_remap_node(const char *node) + { +diff --git a/arch/openrisc/include/asm/barrier.h b/arch/openrisc/include/asm/barrier.h +new file mode 100644 +index 0000000000000..7538294721bed +--- /dev/null ++++ b/arch/openrisc/include/asm/barrier.h +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __ASM_BARRIER_H ++#define __ASM_BARRIER_H ++ ++#define mb() asm volatile ("l.msync" ::: "memory") ++ ++#include ++ ++#endif /* __ASM_BARRIER_H */ +diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c +index f69609b47fef8..d390ab5e51d3f 100644 +--- a/drivers/char/hpet.c ++++ b/drivers/char/hpet.c +@@ -984,6 +984,8 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) + hdp->hd_phys_address = fixmem32->address; + hdp->hd_address = ioremap(fixmem32->address, + HPET_RANGE_SIZE); ++ if (!hdp->hd_address) ++ return AE_ERROR; + + if (hpet_is_known(hdp)) { + iounmap(hdp->hd_address); +diff --git a/drivers/dma/qcom/hidma_mgmt.c b/drivers/dma/qcom/hidma_mgmt.c +index 806ca02c52d71..62026607f3f8b 100644 +--- a/drivers/dma/qcom/hidma_mgmt.c ++++ b/drivers/dma/qcom/hidma_mgmt.c +@@ -418,8 +418,23 @@ static int __init hidma_mgmt_init(void) + hidma_mgmt_of_populate_channels(child); + } + #endif +- return platform_driver_register(&hidma_mgmt_driver); ++ /* ++ * We do not check for return value here, as it is assumed that ++ * platform_driver_register must not fail. The reason for this is that ++ * the (potential) hidma_mgmt_of_populate_channels calls above are not ++ * cleaned up if it does fail, and to do this work is quite ++ * complicated. In particular, various calls of of_address_to_resource, ++ * of_irq_to_resource, platform_device_register_full, of_dma_configure, ++ * and of_msi_configure which then call other functions and so on, must ++ * be cleaned up - this is not a trivial exercise. ++ * ++ * Currently, this module is not intended to be unloaded, and there is ++ * no module_exit function defined which does the needed cleanup. For ++ * this reason, we have to assume success here. ++ */ ++ platform_driver_register(&hidma_mgmt_driver); + ++ return 0; + } + module_init(hidma_mgmt_init); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/gpio/gpio-cadence.c b/drivers/gpio/gpio-cadence.c +index a4d3239d25944..4ab3fcd9b9ba6 100644 +--- a/drivers/gpio/gpio-cadence.c ++++ b/drivers/gpio/gpio-cadence.c +@@ -278,6 +278,7 @@ static const struct of_device_id cdns_of_ids[] = { + { .compatible = "cdns,gpio-r1p02" }, + { /* sentinel */ }, + }; ++MODULE_DEVICE_TABLE(of, cdns_of_ids); + + static struct platform_driver cdns_gpio_driver = { + .driver = { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +index 3b3fc9a426e91..765f9a6c46401 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +@@ -3704,7 +3704,6 @@ out: + r = amdgpu_ib_ring_tests(tmp_adev); + if (r) { + dev_err(tmp_adev->dev, "ib ring test failed (%d).\n", r); +- r = amdgpu_device_ip_suspend(tmp_adev); + need_full_reset = true; + r = -EAGAIN; + goto end; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +index fd94a17fb2c6d..46522804c7d84 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +@@ -289,10 +289,13 @@ out: + static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfbdev) + { + struct amdgpu_framebuffer *rfb = &rfbdev->rfb; ++ int i; + + drm_fb_helper_unregister_fbi(&rfbdev->helper); + + if (rfb->base.obj[0]) { ++ for (i = 0; i < rfb->base.format->num_planes; i++) ++ drm_gem_object_put(rfb->base.obj[0]); + amdgpufb_destroy_pinned_object(rfb->base.obj[0]); + rfb->base.obj[0] = NULL; + drm_framebuffer_unregister_private(&rfb->base); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +index 91e3a87b1de83..58e14d3040f03 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +@@ -1300,6 +1300,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) + if (gtt && gtt->userptr) { + amdgpu_ttm_tt_set_user_pages(ttm, NULL); + kfree(ttm->sg); ++ ttm->sg = NULL; + ttm->page_flags &= ~TTM_PAGE_FLAG_SG; + return; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +index 4f0f0de832937..1bb0f3c0978a8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +@@ -233,9 +233,13 @@ static int vcn_v1_0_hw_fini(void *handle) + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec; + ++ cancel_delayed_work_sync(&adev->vcn.idle_work); ++ + if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || +- RREG32_SOC15(VCN, 0, mmUVD_STATUS)) ++ (adev->vcn.cur_state != AMD_PG_STATE_GATE && ++ RREG32_SOC15(VCN, 0, mmUVD_STATUS))) { + vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE); ++ } + + ring->sched.ready = false; + +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +index cd2cbe760e883..82327ee96f953 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +@@ -293,6 +293,8 @@ static int vcn_v2_0_hw_fini(void *handle) + struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec; + int i; + ++ cancel_delayed_work_sync(&adev->vcn.idle_work); ++ + if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || + (adev->vcn.cur_state != AMD_PG_STATE_GATE && + RREG32_SOC15(VCN, 0, mmUVD_STATUS))) +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +index 9d778a0b2c5e2..4c9a1633b02a7 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +@@ -302,6 +302,8 @@ static int vcn_v2_5_hw_fini(void *handle) + struct amdgpu_ring *ring; + int i; + ++ cancel_delayed_work_sync(&adev->vcn.idle_work); ++ + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + if (adev->vcn.harvest_config & (1 << i)) + continue; +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +index 40041c61a100e..6b03267021eac 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c +@@ -936,6 +936,24 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) + dc_is_dvi_signal(link->connector_signal)) { + if (prev_sink != NULL) + dc_sink_release(prev_sink); ++ link_disconnect_sink(link); ++ ++ return false; ++ } ++ /* ++ * Abort detection for DP connectors if we have ++ * no EDID and connector is active converter ++ * as there are no display downstream ++ * ++ */ ++ if (dc_is_dp_sst_signal(link->connector_signal) && ++ (link->dpcd_caps.dongle_type == ++ DISPLAY_DONGLE_DP_VGA_CONVERTER || ++ link->dpcd_caps.dongle_type == ++ DISPLAY_DONGLE_DP_DVI_CONVERTER)) { ++ if (prev_sink) ++ dc_sink_release(prev_sink); ++ link_disconnect_sink(link); + + return false; + } +diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c +index c2fccf97f7a42..abc8c42b8b0c1 100644 +--- a/drivers/gpu/drm/i915/display/intel_dp.c ++++ b/drivers/gpu/drm/i915/display/intel_dp.c +@@ -3634,7 +3634,7 @@ static void chv_dp_post_pll_disable(struct intel_encoder *encoder, + * link status information + */ + bool +-intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATUS_SIZE]) ++intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status) + { + return drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS, link_status, + DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE; +@@ -4706,7 +4706,18 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) + bool bret; + + if (intel_dp->is_mst) { +- u8 esi[DP_DPRX_ESI_LEN] = { 0 }; ++ /* ++ * The +2 is because DP_DPRX_ESI_LEN is 14, but we then ++ * pass in "esi+10" to drm_dp_channel_eq_ok(), which ++ * takes a 6-byte array. So we actually need 16 bytes ++ * here. ++ * ++ * Somebody who knows what the limits actually are ++ * should check this, but for now this is at least ++ * harmless and avoids a valid compiler warning about ++ * using more of the array than we have allocated. ++ */ ++ u8 esi[DP_DPRX_ESI_LEN+2] = {}; + int ret = 0; + int retry; + bool handled; +diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c +index 86d0961112773..61a6536e7e61a 100644 +--- a/drivers/gpu/drm/meson/meson_drv.c ++++ b/drivers/gpu/drm/meson/meson_drv.c +@@ -423,11 +423,12 @@ static int meson_probe_remote(struct platform_device *pdev, + static void meson_drv_shutdown(struct platform_device *pdev) + { + struct meson_drm *priv = dev_get_drvdata(&pdev->dev); +- struct drm_device *drm = priv->drm; + +- DRM_DEBUG_DRIVER("\n"); +- drm_kms_helper_poll_fini(drm); +- drm_atomic_helper_shutdown(drm); ++ if (!priv) ++ return; ++ ++ drm_kms_helper_poll_fini(priv->drm); ++ drm_atomic_helper_shutdown(priv->drm); + } + + static int meson_drv_probe(struct platform_device *pdev) +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 2b6a4c1f188f4..a959062ded4f8 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -379,11 +379,9 @@ static int i801_check_post(struct i801_priv *priv, int status) + dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); + /* try to stop the current command */ + dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n"); +- outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL, +- SMBHSTCNT(priv)); ++ outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv)); + usleep_range(1000, 2000); +- outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL), +- SMBHSTCNT(priv)); ++ outb_p(0, SMBHSTCNT(priv)); + + /* Check if it worked */ + status = inb_p(SMBHSTSTS(priv)); +diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c +index c98ef4c4a0c9e..d6322698b2458 100644 +--- a/drivers/i2c/busses/i2c-s3c2410.c ++++ b/drivers/i2c/busses/i2c-s3c2410.c +@@ -484,7 +484,10 @@ static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) + * forces us to send a new START + * when we change direction + */ ++ dev_dbg(i2c->dev, ++ "missing START before write->read\n"); + s3c24xx_i2c_stop(i2c, -EINVAL); ++ break; + } + + goto retry_write; +diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c +index d5dd58c27ce5f..0dc2494f1a37b 100644 +--- a/drivers/i2c/busses/i2c-sh_mobile.c ++++ b/drivers/i2c/busses/i2c-sh_mobile.c +@@ -813,7 +813,7 @@ static const struct sh_mobile_dt_config r8a7740_dt_config = { + static const struct of_device_id sh_mobile_i2c_dt_ids[] = { + { .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config }, + { .compatible = "renesas,iic-r8a7740", .data = &r8a7740_dt_config }, +- { .compatible = "renesas,iic-r8a774c0", .data = &fast_clock_dt_config }, ++ { .compatible = "renesas,iic-r8a774c0", .data = &v2_freq_calc_dt_config }, + { .compatible = "renesas,iic-r8a7790", .data = &v2_freq_calc_dt_config }, + { .compatible = "renesas,iic-r8a7791", .data = &v2_freq_calc_dt_config }, + { .compatible = "renesas,iic-r8a7792", .data = &v2_freq_calc_dt_config }, +diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c +index 306bf15023a78..fa808f9c0d9af 100644 +--- a/drivers/iio/adc/ad7124.c ++++ b/drivers/iio/adc/ad7124.c +@@ -473,6 +473,13 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, + if (ret) + goto err; + ++ if (channel >= indio_dev->num_channels) { ++ dev_err(indio_dev->dev.parent, ++ "Channel index >= number of channels\n"); ++ ret = -EINVAL; ++ goto err; ++ } ++ + ret = of_property_read_u32_array(child, "diff-channels", + ain, 2); + if (ret) +@@ -564,6 +571,11 @@ static int ad7124_setup(struct ad7124_state *st) + return ret; + } + ++static void ad7124_reg_disable(void *r) ++{ ++ regulator_disable(r); ++} ++ + static int ad7124_probe(struct spi_device *spi) + { + const struct spi_device_id *id; +@@ -607,17 +619,20 @@ static int ad7124_probe(struct spi_device *spi) + ret = regulator_enable(st->vref[i]); + if (ret) + return ret; ++ ++ ret = devm_add_action_or_reset(&spi->dev, ad7124_reg_disable, ++ st->vref[i]); ++ if (ret) ++ return ret; + } + + st->mclk = devm_clk_get(&spi->dev, "mclk"); +- if (IS_ERR(st->mclk)) { +- ret = PTR_ERR(st->mclk); +- goto error_regulator_disable; +- } ++ if (IS_ERR(st->mclk)) ++ return PTR_ERR(st->mclk); + + ret = clk_prepare_enable(st->mclk); + if (ret < 0) +- goto error_regulator_disable; ++ return ret; + + ret = ad7124_soft_reset(st); + if (ret < 0) +@@ -643,11 +658,6 @@ error_remove_trigger: + ad_sd_cleanup_buffer_and_trigger(indio_dev); + error_clk_disable_unprepare: + clk_disable_unprepare(st->mclk); +-error_regulator_disable: +- for (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) { +- if (!IS_ERR_OR_NULL(st->vref[i])) +- regulator_disable(st->vref[i]); +- } + + return ret; + } +@@ -656,17 +666,11 @@ static int ad7124_remove(struct spi_device *spi) + { + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7124_state *st = iio_priv(indio_dev); +- int i; + + iio_device_unregister(indio_dev); + ad_sd_cleanup_buffer_and_trigger(indio_dev); + clk_disable_unprepare(st->mclk); + +- for (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) { +- if (!IS_ERR_OR_NULL(st->vref[i])) +- regulator_disable(st->vref[i]); +- } +- + return 0; + } + +diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c +index 0d132708c4295..0f6c1be1cda2c 100644 +--- a/drivers/iio/adc/ad7768-1.c ++++ b/drivers/iio/adc/ad7768-1.c +@@ -166,6 +166,10 @@ struct ad7768_state { + * transfer buffers to live in their own cache lines. + */ + union { ++ struct { ++ __be32 chan; ++ s64 timestamp; ++ } scan; + __be32 d32; + u8 d8[2]; + } data ____cacheline_aligned; +@@ -459,11 +463,11 @@ static irqreturn_t ad7768_trigger_handler(int irq, void *p) + + mutex_lock(&st->lock); + +- ret = spi_read(st->spi, &st->data.d32, 3); ++ ret = spi_read(st->spi, &st->data.scan.chan, 3); + if (ret < 0) + goto err_unlock; + +- iio_push_to_buffers_with_timestamp(indio_dev, &st->data.d32, ++ iio_push_to_buffers_with_timestamp(indio_dev, &st->data.scan, + iio_get_time_ns(indio_dev)); + + iio_trigger_notify_done(indio_dev->trig); +diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c +index 6ed6d14102016..947d6c7772344 100644 +--- a/drivers/iio/adc/ad7793.c ++++ b/drivers/iio/adc/ad7793.c +@@ -278,6 +278,7 @@ static int ad7793_setup(struct iio_dev *indio_dev, + id &= AD7793_ID_MASK; + + if (id != st->chip_info->id) { ++ ret = -ENODEV; + dev_err(&st->sd.spi->dev, "device ID query failed\n"); + goto out; + } +diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c +index 89d2bb2282eac..958cf8b6002ca 100644 +--- a/drivers/iio/gyro/fxas21002c_core.c ++++ b/drivers/iio/gyro/fxas21002c_core.c +@@ -333,6 +333,7 @@ static int fxas21002c_temp_get(struct fxas21002c_data *data, int *val) + ret = regmap_field_read(data->regmap_fields[F_TEMP], &temp); + if (ret < 0) { + dev_err(dev, "failed to read temp: %d\n", ret); ++ fxas21002c_pm_put(data); + goto data_unlock; + } + +@@ -366,6 +367,7 @@ static int fxas21002c_axis_get(struct fxas21002c_data *data, + &axis_be, sizeof(axis_be)); + if (ret < 0) { + dev_err(dev, "failed to read axis: %d: %d\n", index, ret); ++ fxas21002c_pm_put(data); + goto data_unlock; + } + +diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c +index 1b9795743276d..24616525c90dc 100644 +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -1110,7 +1110,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) + + err = iommu_device_register(&iommu->iommu); + if (err) +- goto err_unmap; ++ goto err_sysfs; + } + + drhd->iommu = iommu; +@@ -1118,6 +1118,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) + + return 0; + ++err_sysfs: ++ iommu_device_sysfs_remove(&iommu->iommu); + err_unmap: + unmap_iommu(iommu); + error_free_seq_id: +diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c +index 008a74a1ed444..1f89378b56231 100644 +--- a/drivers/isdn/hardware/mISDN/hfcsusb.c ++++ b/drivers/isdn/hardware/mISDN/hfcsusb.c +@@ -46,7 +46,7 @@ static void hfcsusb_start_endpoint(struct hfcsusb *hw, int channel); + static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel); + static int hfcsusb_setup_bch(struct bchannel *bch, int protocol); + static void deactivate_bchannel(struct bchannel *bch); +-static void hfcsusb_ph_info(struct hfcsusb *hw); ++static int hfcsusb_ph_info(struct hfcsusb *hw); + + /* start next background transfer for control channel */ + static void +@@ -241,7 +241,7 @@ hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) + * send full D/B channel status information + * as MPH_INFORMATION_IND + */ +-static void ++static int + hfcsusb_ph_info(struct hfcsusb *hw) + { + struct ph_info *phi; +@@ -250,7 +250,7 @@ hfcsusb_ph_info(struct hfcsusb *hw) + + phi = kzalloc(struct_size(phi, bch, dch->dev.nrbchan), GFP_ATOMIC); + if (!phi) +- return; ++ return -ENOMEM; + + phi->dch.ch.protocol = hw->protocol; + phi->dch.ch.Flags = dch->Flags; +@@ -264,6 +264,8 @@ hfcsusb_ph_info(struct hfcsusb *hw) + sizeof(struct ph_info_dch) + dch->dev.nrbchan * + sizeof(struct ph_info_ch), phi, GFP_ATOMIC); + kfree(phi); ++ ++ return 0; + } + + /* +@@ -348,8 +350,7 @@ hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb) + ret = l1_event(dch->l1, hh->prim); + break; + case MPH_INFORMATION_REQ: +- hfcsusb_ph_info(hw); +- ret = 0; ++ ret = hfcsusb_ph_info(hw); + break; + } + +@@ -404,8 +405,7 @@ hfc_l1callback(struct dchannel *dch, u_int cmd) + hw->name, __func__, cmd); + return -1; + } +- hfcsusb_ph_info(hw); +- return 0; ++ return hfcsusb_ph_info(hw); + } + + static int +@@ -747,8 +747,7 @@ hfcsusb_setup_bch(struct bchannel *bch, int protocol) + handle_led(hw, (bch->nr == 1) ? LED_B1_OFF : + LED_B2_OFF); + } +- hfcsusb_ph_info(hw); +- return 0; ++ return hfcsusb_ph_info(hw); + } + + static void +diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c +index f4cb297668884..3cf0c6f5a1dca 100644 +--- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c ++++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c +@@ -630,17 +630,19 @@ static void + release_io(struct inf_hw *hw) + { + if (hw->cfg.mode) { +- if (hw->cfg.p) { ++ if (hw->cfg.mode == AM_MEMIO) { + release_mem_region(hw->cfg.start, hw->cfg.size); +- iounmap(hw->cfg.p); ++ if (hw->cfg.p) ++ iounmap(hw->cfg.p); + } else + release_region(hw->cfg.start, hw->cfg.size); + hw->cfg.mode = AM_NONE; + } + if (hw->addr.mode) { +- if (hw->addr.p) { ++ if (hw->addr.mode == AM_MEMIO) { + release_mem_region(hw->addr.start, hw->addr.size); +- iounmap(hw->addr.p); ++ if (hw->addr.p) ++ iounmap(hw->addr.p); + } else + release_region(hw->addr.start, hw->addr.size); + hw->addr.mode = AM_NONE; +@@ -670,9 +672,12 @@ setup_io(struct inf_hw *hw) + (ulong)hw->cfg.start, (ulong)hw->cfg.size); + return err; + } +- if (hw->ci->cfg_mode == AM_MEMIO) +- hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); + hw->cfg.mode = hw->ci->cfg_mode; ++ if (hw->ci->cfg_mode == AM_MEMIO) { ++ hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); ++ if (!hw->cfg.p) ++ return -ENOMEM; ++ } + if (debug & DEBUG_HW) + pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n", + hw->name, (ulong)hw->cfg.start, +@@ -697,12 +702,12 @@ setup_io(struct inf_hw *hw) + (ulong)hw->addr.start, (ulong)hw->addr.size); + return err; + } ++ hw->addr.mode = hw->ci->addr_mode; + if (hw->ci->addr_mode == AM_MEMIO) { + hw->addr.p = ioremap(hw->addr.start, hw->addr.size); +- if (unlikely(!hw->addr.p)) ++ if (!hw->addr.p) + return -ENOMEM; + } +- hw->addr.mode = hw->ci->addr_mode; + if (debug & DEBUG_HW) + pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n", + hw->name, (ulong)hw->addr.start, +diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c +index add7d4ce41802..e902aae685af9 100644 +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -854,7 +854,7 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) + static uint32_t __minimum_chunk_size(struct origin *o) + { + struct dm_snapshot *snap; +- unsigned chunk_size = 0; ++ unsigned chunk_size = rounddown_pow_of_two(UINT_MAX); + + if (o) + list_for_each_entry(snap, &o->snapshots, list) +diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c +index 655db8272268d..9767159aeb9b2 100644 +--- a/drivers/media/dvb-frontends/sp8870.c ++++ b/drivers/media/dvb-frontends/sp8870.c +@@ -281,7 +281,7 @@ static int sp8870_set_frontend_parameters(struct dvb_frontend *fe) + + // read status reg in order to clear pending irqs + err = sp8870_readreg(state, 0x200); +- if (err) ++ if (err < 0) + return err; + + // system controller start +diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c +index a4f7431486f31..d93d384286c16 100644 +--- a/drivers/media/usb/gspca/cpia1.c ++++ b/drivers/media/usb/gspca/cpia1.c +@@ -1424,7 +1424,6 @@ static int sd_config(struct gspca_dev *gspca_dev, + { + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; +- int ret; + + sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; + reset_camera_params(gspca_dev); +@@ -1436,10 +1435,7 @@ static int sd_config(struct gspca_dev *gspca_dev, + cam->cam_mode = mode; + cam->nmodes = ARRAY_SIZE(mode); + +- ret = goto_low_power(gspca_dev); +- if (ret) +- gspca_err(gspca_dev, "Cannot go to low power mode: %d\n", +- ret); ++ goto_low_power(gspca_dev); + /* Check the firmware version. */ + sd->params.version.firmwareVersion = 0; + get_version_information(gspca_dev); +diff --git a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c +index bfa3b381d8a26..bf1af6ed9131e 100644 +--- a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c ++++ b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c +@@ -195,7 +195,7 @@ static const struct v4l2_ctrl_config mt9m111_greenbal_cfg = { + int mt9m111_probe(struct sd *sd) + { + u8 data[2] = {0x00, 0x00}; +- int i, rc = 0; ++ int i, err; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + + if (force_sensor) { +@@ -213,18 +213,18 @@ int mt9m111_probe(struct sd *sd) + /* Do the preinit */ + for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) { + if (preinit_mt9m111[i][0] == BRIDGE) { +- rc |= m5602_write_bridge(sd, +- preinit_mt9m111[i][1], +- preinit_mt9m111[i][2]); ++ err = m5602_write_bridge(sd, ++ preinit_mt9m111[i][1], ++ preinit_mt9m111[i][2]); + } else { + data[0] = preinit_mt9m111[i][2]; + data[1] = preinit_mt9m111[i][3]; +- rc |= m5602_write_sensor(sd, +- preinit_mt9m111[i][1], data, 2); ++ err = m5602_write_sensor(sd, ++ preinit_mt9m111[i][1], data, 2); + } ++ if (err < 0) ++ return err; + } +- if (rc < 0) +- return rc; + + if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2)) + return -ENODEV; +diff --git a/drivers/media/usb/gspca/m5602/m5602_po1030.c b/drivers/media/usb/gspca/m5602/m5602_po1030.c +index d680b777f097f..8fd99ceee4b67 100644 +--- a/drivers/media/usb/gspca/m5602/m5602_po1030.c ++++ b/drivers/media/usb/gspca/m5602/m5602_po1030.c +@@ -154,8 +154,8 @@ static const struct v4l2_ctrl_config po1030_greenbal_cfg = { + + int po1030_probe(struct sd *sd) + { +- int rc = 0; + u8 dev_id_h = 0, i; ++ int err; + struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; + + if (force_sensor) { +@@ -174,14 +174,14 @@ int po1030_probe(struct sd *sd) + for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { + u8 data = preinit_po1030[i][2]; + if (preinit_po1030[i][0] == SENSOR) +- rc |= m5602_write_sensor(sd, +- preinit_po1030[i][1], &data, 1); ++ err = m5602_write_sensor(sd, preinit_po1030[i][1], ++ &data, 1); + else +- rc |= m5602_write_bridge(sd, preinit_po1030[i][1], +- data); ++ err = m5602_write_bridge(sd, preinit_po1030[i][1], ++ data); ++ if (err < 0) ++ return err; + } +- if (rc < 0) +- return rc; + + if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1)) + return -ENODEV; +diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c +index 5c183c02dfd92..8d18f19c99c4b 100644 +--- a/drivers/misc/kgdbts.c ++++ b/drivers/misc/kgdbts.c +@@ -100,8 +100,9 @@ + printk(KERN_INFO a); \ + } while (0) + #define v2printk(a...) do { \ +- if (verbose > 1) \ ++ if (verbose > 1) { \ + printk(KERN_INFO a); \ ++ } \ + touch_nmi_watchdog(); \ + } while (0) + #define eprintk(a...) do { \ +diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h +index 1b0c99883c57b..c008eecfdfe8d 100644 +--- a/drivers/misc/lis3lv02d/lis3lv02d.h ++++ b/drivers/misc/lis3lv02d/lis3lv02d.h +@@ -271,6 +271,7 @@ struct lis3lv02d { + int regs_size; + u8 *reg_cache; + bool regs_stored; ++ bool init_required; + u8 odr_mask; /* ODR bit mask */ + u8 whoami; /* indicates measurement precision */ + s16 (*read_data) (struct lis3lv02d *lis3, int reg); +diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c +index c70a8c74cc57a..a70d989032c19 100644 +--- a/drivers/misc/mei/interrupt.c ++++ b/drivers/misc/mei/interrupt.c +@@ -222,6 +222,9 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, + return ret; + } + ++ pm_runtime_mark_last_busy(dev->dev); ++ pm_request_autosuspend(dev->dev); ++ + list_move_tail(&cb->list, &cl->rd_pending); + + return 0; +diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c +index 40b079162804f..0f2bee59a82b0 100644 +--- a/drivers/net/caif/caif_serial.c ++++ b/drivers/net/caif/caif_serial.c +@@ -270,7 +270,6 @@ static int caif_xmit(struct sk_buff *skb, struct net_device *dev) + { + struct ser_device *ser; + +- BUG_ON(dev == NULL); + ser = netdev_priv(dev); + + /* Send flow off once, on high water mark */ +diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c +index 00d680cb44418..071e5015bf91d 100644 +--- a/drivers/net/dsa/mt7530.c ++++ b/drivers/net/dsa/mt7530.c +@@ -809,14 +809,6 @@ mt7530_port_set_vlan_aware(struct dsa_switch *ds, int port) + { + struct mt7530_priv *priv = ds->priv; + +- /* The real fabric path would be decided on the membership in the +- * entry of VLAN table. PCR_MATRIX set up here with ALL_MEMBERS +- * means potential VLAN can be consisting of certain subset of all +- * ports. +- */ +- mt7530_rmw(priv, MT7530_PCR_P(port), +- PCR_MATRIX_MASK, PCR_MATRIX(MT7530_ALL_MEMBERS)); +- + /* Trapped into security mode allows packet forwarding through VLAN + * table lookup. CPU port is set to fallback mode to let untagged + * frames pass through. +diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c +index 3b51e87a3714a..034f1b50ab287 100644 +--- a/drivers/net/dsa/sja1105/sja1105_main.c ++++ b/drivers/net/dsa/sja1105/sja1105_main.c +@@ -178,6 +178,7 @@ static int sja1105_init_mii_settings(struct sja1105_private *priv, + default: + dev_err(dev, "Unsupported PHY mode %s!\n", + phy_modes(ports[i].phy_mode)); ++ return -EINVAL; + } + + mii->phy_mac[i] = ports[i].role; +diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c +index fbc196b480b63..c3f67d8e10933 100644 +--- a/drivers/net/ethernet/broadcom/bnx2.c ++++ b/drivers/net/ethernet/broadcom/bnx2.c +@@ -8249,9 +8249,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) + BNX2_WR(bp, PCI_COMMAND, reg); + } else if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A1) && + !(bp->flags & BNX2_FLAG_PCIX)) { +- + dev_err(&pdev->dev, + "5706 A1 can only be used in a PCIX bus, aborting\n"); ++ rc = -EPERM; + goto err_out_unmap; + } + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 106f2b2ce17f0..0dba28bb309a2 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -280,7 +280,8 @@ static bool bnxt_vf_pciid(enum board_idx idx) + { + return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF || + idx == NETXTREME_S_VF || idx == NETXTREME_C_VF_HV || +- idx == NETXTREME_E_VF_HV || idx == NETXTREME_E_P5_VF); ++ idx == NETXTREME_E_VF_HV || idx == NETXTREME_E_P5_VF || ++ idx == NETXTREME_E_P5_VF_HV); + } + + #define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID) +diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c +index e338272931d14..94e87e7f277bb 100644 +--- a/drivers/net/ethernet/brocade/bna/bnad.c ++++ b/drivers/net/ethernet/brocade/bna/bnad.c +@@ -3282,7 +3282,7 @@ bnad_change_mtu(struct net_device *netdev, int new_mtu) + { + int err, mtu; + struct bnad *bnad = netdev_priv(netdev); +- u32 rx_count = 0, frame, new_frame; ++ u32 frame, new_frame; + + mutex_lock(&bnad->conf_mutex); + +@@ -3298,12 +3298,9 @@ bnad_change_mtu(struct net_device *netdev, int new_mtu) + /* only when transition is over 4K */ + if ((frame <= 4096 && new_frame > 4096) || + (frame > 4096 && new_frame <= 4096)) +- rx_count = bnad_reinit_rx(bnad); ++ bnad_reinit_rx(bnad); + } + +- /* rx_count > 0 - new rx created +- * - Linux set err = 0 and return +- */ + err = bnad_mtu_set(bnad, new_frame); + if (err) + err = -EBUSY; +diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c +index 7f3b2e3b0868e..d0c77ff9dbb11 100644 +--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c ++++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c +@@ -1179,7 +1179,7 @@ static void octeon_destroy_resources(struct octeon_device *oct) + * @param lio per-network private data + * @param start_stop whether to start or stop + */ +-static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) ++static int send_rx_ctrl_cmd(struct lio *lio, int start_stop) + { + struct octeon_soft_command *sc; + union octnet_cmd *ncmd; +@@ -1187,15 +1187,15 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) + int retval; + + if (oct->props[lio->ifidx].rx_on == start_stop) +- return; ++ return 0; + + sc = (struct octeon_soft_command *) + octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE, + 16, 0); + if (!sc) { + netif_info(lio, rx_err, lio->netdev, +- "Failed to allocate octeon_soft_command\n"); +- return; ++ "Failed to allocate octeon_soft_command struct\n"); ++ return -ENOMEM; + } + + ncmd = (union octnet_cmd *)sc->virtdptr; +@@ -1218,18 +1218,19 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) + if (retval == IQ_SEND_FAILED) { + netif_info(lio, rx_err, lio->netdev, "Failed to send RX Control message\n"); + octeon_free_soft_command(oct, sc); +- return; + } else { + /* Sleep on a wait queue till the cond flag indicates that the + * response arrived or timed-out. + */ + retval = wait_for_sc_completion_timeout(oct, sc, 0); + if (retval) +- return; ++ return retval; + + oct->props[lio->ifidx].rx_on = start_stop; + WRITE_ONCE(sc->caller_is_done, true); + } ++ ++ return retval; + } + + /** +@@ -1816,6 +1817,7 @@ static int liquidio_open(struct net_device *netdev) + struct octeon_device_priv *oct_priv = + (struct octeon_device_priv *)oct->priv; + struct napi_struct *napi, *n; ++ int ret = 0; + + if (oct->props[lio->ifidx].napi_enabled == 0) { + tasklet_disable(&oct_priv->droq_tasklet); +@@ -1851,7 +1853,9 @@ static int liquidio_open(struct net_device *netdev) + netif_info(lio, ifup, lio->netdev, "Interface Open, ready for traffic\n"); + + /* tell Octeon to start forwarding packets to host */ +- send_rx_ctrl_cmd(lio, 1); ++ ret = send_rx_ctrl_cmd(lio, 1); ++ if (ret) ++ return ret; + + /* start periodical statistics fetch */ + INIT_DELAYED_WORK(&lio->stats_wk.work, lio_fetch_stats); +@@ -1862,7 +1866,7 @@ static int liquidio_open(struct net_device *netdev) + dev_info(&oct->pci_dev->dev, "%s interface is opened\n", + netdev->name); + +- return 0; ++ return ret; + } + + /** +@@ -1876,6 +1880,7 @@ static int liquidio_stop(struct net_device *netdev) + struct octeon_device_priv *oct_priv = + (struct octeon_device_priv *)oct->priv; + struct napi_struct *napi, *n; ++ int ret = 0; + + ifstate_reset(lio, LIO_IFSTATE_RUNNING); + +@@ -1892,7 +1897,9 @@ static int liquidio_stop(struct net_device *netdev) + lio->link_changes++; + + /* Tell Octeon that nic interface is down. */ +- send_rx_ctrl_cmd(lio, 0); ++ ret = send_rx_ctrl_cmd(lio, 0); ++ if (ret) ++ return ret; + + if (OCTEON_CN23XX_PF(oct)) { + if (!oct->msix_on) +@@ -1927,7 +1934,7 @@ static int liquidio_stop(struct net_device *netdev) + + dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name); + +- return 0; ++ return ret; + } + + /** +diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +index 370d76822ee07..929da9e9fe9af 100644 +--- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c ++++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +@@ -598,7 +598,7 @@ static void octeon_destroy_resources(struct octeon_device *oct) + * @param lio per-network private data + * @param start_stop whether to start or stop + */ +-static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) ++static int send_rx_ctrl_cmd(struct lio *lio, int start_stop) + { + struct octeon_device *oct = (struct octeon_device *)lio->oct_dev; + struct octeon_soft_command *sc; +@@ -606,11 +606,16 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) + int retval; + + if (oct->props[lio->ifidx].rx_on == start_stop) +- return; ++ return 0; + + sc = (struct octeon_soft_command *) + octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE, + 16, 0); ++ if (!sc) { ++ netif_info(lio, rx_err, lio->netdev, ++ "Failed to allocate octeon_soft_command struct\n"); ++ return -ENOMEM; ++ } + + ncmd = (union octnet_cmd *)sc->virtdptr; + +@@ -638,11 +643,13 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) + */ + retval = wait_for_sc_completion_timeout(oct, sc, 0); + if (retval) +- return; ++ return retval; + + oct->props[lio->ifidx].rx_on = start_stop; + WRITE_ONCE(sc->caller_is_done, true); + } ++ ++ return retval; + } + + /** +@@ -909,6 +916,7 @@ static int liquidio_open(struct net_device *netdev) + struct octeon_device_priv *oct_priv = + (struct octeon_device_priv *)oct->priv; + struct napi_struct *napi, *n; ++ int ret = 0; + + if (!oct->props[lio->ifidx].napi_enabled) { + tasklet_disable(&oct_priv->droq_tasklet); +@@ -935,11 +943,13 @@ static int liquidio_open(struct net_device *netdev) + (LIQUIDIO_NDEV_STATS_POLL_TIME_MS)); + + /* tell Octeon to start forwarding packets to host */ +- send_rx_ctrl_cmd(lio, 1); ++ ret = send_rx_ctrl_cmd(lio, 1); ++ if (ret) ++ return ret; + + dev_info(&oct->pci_dev->dev, "%s interface is opened\n", netdev->name); + +- return 0; ++ return ret; + } + + /** +@@ -953,9 +963,12 @@ static int liquidio_stop(struct net_device *netdev) + struct octeon_device_priv *oct_priv = + (struct octeon_device_priv *)oct->priv; + struct napi_struct *napi, *n; ++ int ret = 0; + + /* tell Octeon to stop forwarding packets to host */ +- send_rx_ctrl_cmd(lio, 0); ++ ret = send_rx_ctrl_cmd(lio, 0); ++ if (ret) ++ return ret; + + netif_info(lio, ifdown, lio->netdev, "Stopping interface!\n"); + /* Inform that netif carrier is down */ +@@ -989,7 +1002,7 @@ static int liquidio_stop(struct net_device *netdev) + + dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name); + +- return 0; ++ return ret; + } + + /** +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c +index 64a2453e06ba1..ccb28182f745b 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c +@@ -778,7 +778,7 @@ void clear_all_filters(struct adapter *adapter) + cxgb4_del_filter(dev, i, &f->fs); + } + +- sb = t4_read_reg(adapter, LE_DB_SRVR_START_INDEX_A); ++ sb = adapter->tids.stid_base; + for (i = 0; i < sb; i++) { + f = (struct filter_entry *)adapter->tids.tid_tab[i]; + +diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c +index f16853c3c851a..c813e6f2b371e 100644 +--- a/drivers/net/ethernet/dec/tulip/de4x5.c ++++ b/drivers/net/ethernet/dec/tulip/de4x5.c +@@ -4927,11 +4927,11 @@ mii_get_oui(u_char phyaddr, u_long ioaddr) + u_char breg[2]; + } a; + int i, r2, r3, ret=0;*/ +- int r2, r3; ++ int r2; + + /* Read r2 and r3 */ + r2 = mii_rd(MII_ID0, phyaddr, ioaddr); +- r3 = mii_rd(MII_ID1, phyaddr, ioaddr); ++ mii_rd(MII_ID1, phyaddr, ioaddr); + /* SEEQ and Cypress way * / + / * Shuffle r2 and r3 * / + a.reg=0; +diff --git a/drivers/net/ethernet/dec/tulip/media.c b/drivers/net/ethernet/dec/tulip/media.c +index dcf21a36a9cf4..011604787b8ed 100644 +--- a/drivers/net/ethernet/dec/tulip/media.c ++++ b/drivers/net/ethernet/dec/tulip/media.c +@@ -319,13 +319,8 @@ void tulip_select_media(struct net_device *dev, int startup) + break; + } + case 5: case 6: { +- u16 setup[5]; +- + new_csr6 = 0; /* FIXME */ + +- for (i = 0; i < 5; i++) +- setup[i] = get_u16(&p[i*2 + 1]); +- + if (startup && mtable->has_reset) { + struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset]; + unsigned char *rst = rleaf->leafdata; +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index fd7fc6f20c9da..b1856552ab813 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -3274,7 +3274,9 @@ static int fec_enet_init(struct net_device *ndev) + return ret; + } + +- fec_enet_alloc_queue(ndev); ++ ret = fec_enet_alloc_queue(ndev); ++ if (ret) ++ return ret; + + bd_size = (fep->total_tx_ring_size + fep->total_rx_ring_size) * dsize; + +@@ -3282,7 +3284,8 @@ static int fec_enet_init(struct net_device *ndev) + cbd_base = dmam_alloc_coherent(&fep->pdev->dev, bd_size, &bd_dma, + GFP_KERNEL); + if (!cbd_base) { +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto free_queue_mem; + } + + /* Get the Ethernet address */ +@@ -3360,6 +3363,10 @@ static int fec_enet_init(struct net_device *ndev) + fec_enet_update_ethtool_stats(ndev); + + return 0; ++ ++free_queue_mem: ++ fec_enet_free_queue(ndev); ++ return ret; + } + + #ifdef CONFIG_OF +diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +index 1eca0fdb99334..b8fc9bbeca2c7 100644 +--- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c ++++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +@@ -548,8 +548,8 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id) + + base = ioremap(link->resource[2]->start, resource_size(link->resource[2])); + if (!base) { +- pcmcia_release_window(link, link->resource[2]); +- return -ENOMEM; ++ pcmcia_release_window(link, link->resource[2]); ++ return -1; + } + + pcmcia_map_mem_page(link, link->resource[2], 0); +diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c +index 9b7a8db9860fc..6ea0975d74a1f 100644 +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -121,7 +121,7 @@ static int gve_napi_poll(struct napi_struct *napi, int budget) + /* Double check we have no extra work. + * Ensure unmask synchronizes with checking for work. + */ +- dma_rmb(); ++ mb(); + if (block->tx) + reschedule |= gve_tx_poll(block, -1); + if (block->rx) +@@ -161,6 +161,7 @@ static int gve_alloc_notify_blocks(struct gve_priv *priv) + int vecs_left = new_num_ntfy_blks % 2; + + priv->num_ntfy_blks = new_num_ntfy_blks; ++ priv->mgmt_msix_idx = priv->num_ntfy_blks; + priv->tx_cfg.max_queues = min_t(int, priv->tx_cfg.max_queues, + vecs_per_type); + priv->rx_cfg.max_queues = min_t(int, priv->rx_cfg.max_queues, +@@ -241,20 +242,22 @@ static void gve_free_notify_blocks(struct gve_priv *priv) + { + int i; + +- /* Free the irqs */ +- for (i = 0; i < priv->num_ntfy_blks; i++) { +- struct gve_notify_block *block = &priv->ntfy_blocks[i]; +- int msix_idx = i; ++ if (priv->msix_vectors) { ++ /* Free the irqs */ ++ for (i = 0; i < priv->num_ntfy_blks; i++) { ++ struct gve_notify_block *block = &priv->ntfy_blocks[i]; ++ int msix_idx = i; + +- irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, +- NULL); +- free_irq(priv->msix_vectors[msix_idx].vector, block); ++ irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, ++ NULL); ++ free_irq(priv->msix_vectors[msix_idx].vector, block); ++ } ++ free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); + } + dma_free_coherent(&priv->pdev->dev, + priv->num_ntfy_blks * sizeof(*priv->ntfy_blocks), + priv->ntfy_blocks, priv->ntfy_block_bus); + priv->ntfy_blocks = NULL; +- free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); + pci_disable_msix(priv->pdev); + kvfree(priv->msix_vectors); + priv->msix_vectors = NULL; +diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c +index d0244feb03011..b653197b34d10 100644 +--- a/drivers/net/ethernet/google/gve/gve_tx.c ++++ b/drivers/net/ethernet/google/gve/gve_tx.c +@@ -207,10 +207,12 @@ static int gve_tx_alloc_ring(struct gve_priv *priv, int idx) + goto abort_with_info; + + tx->tx_fifo.qpl = gve_assign_tx_qpl(priv); ++ if (!tx->tx_fifo.qpl) ++ goto abort_with_desc; + + /* map Tx FIFO */ + if (gve_tx_fifo_init(priv, &tx->tx_fifo)) +- goto abort_with_desc; ++ goto abort_with_qpl; + + tx->q_resources = + dma_alloc_coherent(hdev, +@@ -229,6 +231,8 @@ static int gve_tx_alloc_ring(struct gve_priv *priv, int idx) + + abort_with_fifo: + gve_tx_fifo_release(priv, &tx->tx_fifo); ++abort_with_qpl: ++ gve_unassign_qpl(priv, tx->tx_fifo.qpl->id); + abort_with_desc: + dma_free_coherent(hdev, bytes, tx->desc, tx->bus); + tx->desc = NULL; +@@ -478,7 +482,7 @@ netdev_tx_t gve_tx(struct sk_buff *skb, struct net_device *dev) + struct gve_tx_ring *tx; + int nsegs; + +- WARN(skb_get_queue_mapping(skb) > priv->tx_cfg.num_queues, ++ WARN(skb_get_queue_mapping(skb) >= priv->tx_cfg.num_queues, + "skb queue index out of range"); + tx = &priv->tx[skb_get_queue_mapping(skb)]; + if (unlikely(gve_maybe_stop_tx(tx, skb))) { +diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +index 5f2948bafff21..e64e175162068 100644 +--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -810,8 +810,6 @@ static bool hns3_tunnel_csum_bug(struct sk_buff *skb) + l4.udp->dest == htons(4790)))) + return false; + +- skb_checksum_help(skb); +- + return true; + } + +@@ -889,8 +887,7 @@ static int hns3_set_l2l3l4(struct sk_buff *skb, u8 ol4_proto, + /* the stack computes the IP header already, + * driver calculate l4 checksum when not TSO. + */ +- skb_checksum_help(skb); +- return 0; ++ return skb_checksum_help(skb); + } + + hns3_set_outer_l2l3l4(skb, ol4_proto, ol_type_vlan_len_msec); +@@ -935,7 +932,7 @@ static int hns3_set_l2l3l4(struct sk_buff *skb, u8 ol4_proto, + break; + case IPPROTO_UDP: + if (hns3_tunnel_csum_bug(skb)) +- break; ++ return skb_checksum_help(skb); + + hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4CS_B, 1); + hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4T_S, +@@ -960,8 +957,7 @@ static int hns3_set_l2l3l4(struct sk_buff *skb, u8 ol4_proto, + /* the stack computes the IP header already, + * driver calculate l4 checksum when not TSO. + */ +- skb_checksum_help(skb); +- return 0; ++ return skb_checksum_help(skb); + } + + return 0; +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +index 537dfff585e0d..47a920128760e 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +@@ -467,12 +467,16 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, + return err; + } + +-static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) ++static int ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 max_frame, u32 vf) + { + struct ixgbe_hw *hw = &adapter->hw; +- int max_frame = msgbuf[1]; + u32 max_frs; + ++ if (max_frame < ETH_MIN_MTU || max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE) { ++ e_err(drv, "VF max_frame %d out of range\n", max_frame); ++ return -EINVAL; ++ } ++ + /* + * For 82599EB we have to keep all PFs and VFs operating with + * the same max_frame value in order to avoid sending an oversize +@@ -533,12 +537,6 @@ static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) + } + } + +- /* MTU < 68 is an error and causes problems on some kernels */ +- if (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE) { +- e_err(drv, "VF max_frame %d out of range\n", max_frame); +- return -EINVAL; +- } +- + /* pull current max frame size from hardware */ + max_frs = IXGBE_READ_REG(hw, IXGBE_MAXFRS); + max_frs &= IXGBE_MHADD_MFS_MASK; +@@ -1249,7 +1247,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) + retval = ixgbe_set_vf_vlan_msg(adapter, msgbuf, vf); + break; + case IXGBE_VF_SET_LPE: +- retval = ixgbe_set_vf_lpe(adapter, msgbuf, vf); ++ retval = ixgbe_set_vf_lpe(adapter, msgbuf[1], vf); + break; + case IXGBE_VF_SET_MACVLAN: + retval = ixgbe_set_vf_macvlan_msg(adapter, msgbuf, vf); +diff --git a/drivers/net/ethernet/lantiq_xrx200.c b/drivers/net/ethernet/lantiq_xrx200.c +index 4e44a39267eb3..6ece99e6b6dde 100644 +--- a/drivers/net/ethernet/lantiq_xrx200.c ++++ b/drivers/net/ethernet/lantiq_xrx200.c +@@ -154,6 +154,7 @@ static int xrx200_close(struct net_device *net_dev) + + static int xrx200_alloc_skb(struct xrx200_chan *ch) + { ++ dma_addr_t mapping; + int ret = 0; + + ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(ch->priv->net_dev, +@@ -163,16 +164,17 @@ static int xrx200_alloc_skb(struct xrx200_chan *ch) + goto skip; + } + +- ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(ch->priv->dev, +- ch->skb[ch->dma.desc]->data, XRX200_DMA_DATA_LEN, +- DMA_FROM_DEVICE); +- if (unlikely(dma_mapping_error(ch->priv->dev, +- ch->dma.desc_base[ch->dma.desc].addr))) { ++ mapping = dma_map_single(ch->priv->dev, ch->skb[ch->dma.desc]->data, ++ XRX200_DMA_DATA_LEN, DMA_FROM_DEVICE); ++ if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) { + dev_kfree_skb_any(ch->skb[ch->dma.desc]); + ret = -ENOMEM; + goto skip; + } + ++ ch->dma.desc_base[ch->dma.desc].addr = mapping; ++ /* Make sure the address is written before we give it to HW */ ++ wmb(); + skip: + ch->dma.desc_base[ch->dma.desc].ctl = + LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | +@@ -196,6 +198,8 @@ static int xrx200_hw_receive(struct xrx200_chan *ch) + ch->dma.desc %= LTQ_DESC_NUM; + + if (ret) { ++ ch->skb[ch->dma.desc] = skb; ++ net_dev->stats.rx_dropped++; + netdev_err(net_dev, "failed to allocate new rx buffer\n"); + return ret; + } +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +index 7e3806fd70b21..48b395b9c15ad 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -675,32 +675,53 @@ static int mtk_set_mac_address(struct net_device *dev, void *p) + void mtk_stats_update_mac(struct mtk_mac *mac) + { + struct mtk_hw_stats *hw_stats = mac->hw_stats; +- unsigned int base = MTK_GDM1_TX_GBCNT; +- u64 stats; +- +- base += hw_stats->reg_offset; ++ struct mtk_eth *eth = mac->hw; + + u64_stats_update_begin(&hw_stats->syncp); + +- hw_stats->rx_bytes += mtk_r32(mac->hw, base); +- stats = mtk_r32(mac->hw, base + 0x04); +- if (stats) +- hw_stats->rx_bytes += (stats << 32); +- hw_stats->rx_packets += mtk_r32(mac->hw, base + 0x08); +- hw_stats->rx_overflow += mtk_r32(mac->hw, base + 0x10); +- hw_stats->rx_fcs_errors += mtk_r32(mac->hw, base + 0x14); +- hw_stats->rx_short_errors += mtk_r32(mac->hw, base + 0x18); +- hw_stats->rx_long_errors += mtk_r32(mac->hw, base + 0x1c); +- hw_stats->rx_checksum_errors += mtk_r32(mac->hw, base + 0x20); +- hw_stats->rx_flow_control_packets += +- mtk_r32(mac->hw, base + 0x24); +- hw_stats->tx_skip += mtk_r32(mac->hw, base + 0x28); +- hw_stats->tx_collisions += mtk_r32(mac->hw, base + 0x2c); +- hw_stats->tx_bytes += mtk_r32(mac->hw, base + 0x30); +- stats = mtk_r32(mac->hw, base + 0x34); +- if (stats) +- hw_stats->tx_bytes += (stats << 32); +- hw_stats->tx_packets += mtk_r32(mac->hw, base + 0x38); ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { ++ hw_stats->tx_packets += mtk_r32(mac->hw, MT7628_SDM_TPCNT); ++ hw_stats->tx_bytes += mtk_r32(mac->hw, MT7628_SDM_TBCNT); ++ hw_stats->rx_packets += mtk_r32(mac->hw, MT7628_SDM_RPCNT); ++ hw_stats->rx_bytes += mtk_r32(mac->hw, MT7628_SDM_RBCNT); ++ hw_stats->rx_checksum_errors += ++ mtk_r32(mac->hw, MT7628_SDM_CS_ERR); ++ } else { ++ unsigned int offs = hw_stats->reg_offset; ++ u64 stats; ++ ++ hw_stats->rx_bytes += mtk_r32(mac->hw, ++ MTK_GDM1_RX_GBCNT_L + offs); ++ stats = mtk_r32(mac->hw, MTK_GDM1_RX_GBCNT_H + offs); ++ if (stats) ++ hw_stats->rx_bytes += (stats << 32); ++ hw_stats->rx_packets += ++ mtk_r32(mac->hw, MTK_GDM1_RX_GPCNT + offs); ++ hw_stats->rx_overflow += ++ mtk_r32(mac->hw, MTK_GDM1_RX_OERCNT + offs); ++ hw_stats->rx_fcs_errors += ++ mtk_r32(mac->hw, MTK_GDM1_RX_FERCNT + offs); ++ hw_stats->rx_short_errors += ++ mtk_r32(mac->hw, MTK_GDM1_RX_SERCNT + offs); ++ hw_stats->rx_long_errors += ++ mtk_r32(mac->hw, MTK_GDM1_RX_LENCNT + offs); ++ hw_stats->rx_checksum_errors += ++ mtk_r32(mac->hw, MTK_GDM1_RX_CERCNT + offs); ++ hw_stats->rx_flow_control_packets += ++ mtk_r32(mac->hw, MTK_GDM1_RX_FCCNT + offs); ++ hw_stats->tx_skip += ++ mtk_r32(mac->hw, MTK_GDM1_TX_SKIPCNT + offs); ++ hw_stats->tx_collisions += ++ mtk_r32(mac->hw, MTK_GDM1_TX_COLCNT + offs); ++ hw_stats->tx_bytes += ++ mtk_r32(mac->hw, MTK_GDM1_TX_GBCNT_L + offs); ++ stats = mtk_r32(mac->hw, MTK_GDM1_TX_GBCNT_H + offs); ++ if (stats) ++ hw_stats->tx_bytes += (stats << 32); ++ hw_stats->tx_packets += ++ mtk_r32(mac->hw, MTK_GDM1_TX_GPCNT + offs); ++ } ++ + u64_stats_update_end(&hw_stats->syncp); + } + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 1e9202b34d352..c0b2768b480f8 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -264,8 +264,21 @@ + /* QDMA FQ Free Page Buffer Length Register */ + #define MTK_QDMA_FQ_BLEN 0x1B2C + +-/* GMA1 Received Good Byte Count Register */ +-#define MTK_GDM1_TX_GBCNT 0x2400 ++/* GMA1 counter / statics register */ ++#define MTK_GDM1_RX_GBCNT_L 0x2400 ++#define MTK_GDM1_RX_GBCNT_H 0x2404 ++#define MTK_GDM1_RX_GPCNT 0x2408 ++#define MTK_GDM1_RX_OERCNT 0x2410 ++#define MTK_GDM1_RX_FERCNT 0x2414 ++#define MTK_GDM1_RX_SERCNT 0x2418 ++#define MTK_GDM1_RX_LENCNT 0x241c ++#define MTK_GDM1_RX_CERCNT 0x2420 ++#define MTK_GDM1_RX_FCCNT 0x2424 ++#define MTK_GDM1_TX_SKIPCNT 0x2428 ++#define MTK_GDM1_TX_COLCNT 0x242c ++#define MTK_GDM1_TX_GBCNT_L 0x2430 ++#define MTK_GDM1_TX_GBCNT_H 0x2434 ++#define MTK_GDM1_TX_GPCNT 0x2438 + #define MTK_STAT_OFFSET 0x40 + + /* QDMA descriptor txd4 */ +@@ -476,6 +489,13 @@ + #define MT7628_SDM_MAC_ADRL (MT7628_SDM_OFFSET + 0x0c) + #define MT7628_SDM_MAC_ADRH (MT7628_SDM_OFFSET + 0x10) + ++/* Counter / stat register */ ++#define MT7628_SDM_TPCNT (MT7628_SDM_OFFSET + 0x100) ++#define MT7628_SDM_TBCNT (MT7628_SDM_OFFSET + 0x104) ++#define MT7628_SDM_RPCNT (MT7628_SDM_OFFSET + 0x108) ++#define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) ++#define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) ++ + struct mtk_rx_dma { + unsigned int rxd1; + unsigned int rxd2; +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +index 5582fba2f5823..426786a349c3c 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +@@ -2011,8 +2011,6 @@ static int mlx4_en_set_tunable(struct net_device *dev, + return ret; + } + +-#define MLX4_EEPROM_PAGE_LEN 256 +- + static int mlx4_en_get_module_info(struct net_device *dev, + struct ethtool_modinfo *modinfo) + { +@@ -2047,7 +2045,7 @@ static int mlx4_en_get_module_info(struct net_device *dev, + break; + case MLX4_MODULE_ID_SFP: + modinfo->type = ETH_MODULE_SFF_8472; +- modinfo->eeprom_len = MLX4_EEPROM_PAGE_LEN; ++ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + break; + default: + return -EINVAL; +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c +index 605c079d48417..b0837ad94da65 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c +@@ -868,6 +868,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) + struct mlx4_en_tx_desc *tx_desc; + struct mlx4_wqe_data_seg *data; + struct mlx4_en_tx_info *tx_info; ++ u32 __maybe_unused ring_cons; + int tx_ind; + int nr_txbb; + int desc_size; +@@ -881,7 +882,6 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) + bool stop_queue; + bool inline_ok; + u8 data_offset; +- u32 ring_cons; + bool bf_ok; + + tx_ind = skb_get_queue_mapping(skb); +diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c +index ba6ac31a339dc..256a06b3c096b 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/port.c ++++ b/drivers/net/ethernet/mellanox/mlx4/port.c +@@ -1973,6 +1973,7 @@ EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); + #define I2C_ADDR_LOW 0x50 + #define I2C_ADDR_HIGH 0x51 + #define I2C_PAGE_SIZE 256 ++#define I2C_HIGH_PAGE_SIZE 128 + + /* Module Info Data */ + struct mlx4_cable_info { +@@ -2026,6 +2027,88 @@ static inline const char *cable_info_mad_err_str(u16 mad_status) + return "Unknown Error"; + } + ++static int mlx4_get_module_id(struct mlx4_dev *dev, u8 port, u8 *module_id) ++{ ++ struct mlx4_cmd_mailbox *inbox, *outbox; ++ struct mlx4_mad_ifc *inmad, *outmad; ++ struct mlx4_cable_info *cable_info; ++ int ret; ++ ++ inbox = mlx4_alloc_cmd_mailbox(dev); ++ if (IS_ERR(inbox)) ++ return PTR_ERR(inbox); ++ ++ outbox = mlx4_alloc_cmd_mailbox(dev); ++ if (IS_ERR(outbox)) { ++ mlx4_free_cmd_mailbox(dev, inbox); ++ return PTR_ERR(outbox); ++ } ++ ++ inmad = (struct mlx4_mad_ifc *)(inbox->buf); ++ outmad = (struct mlx4_mad_ifc *)(outbox->buf); ++ ++ inmad->method = 0x1; /* Get */ ++ inmad->class_version = 0x1; ++ inmad->mgmt_class = 0x1; ++ inmad->base_version = 0x1; ++ inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */ ++ ++ cable_info = (struct mlx4_cable_info *)inmad->data; ++ cable_info->dev_mem_address = 0; ++ cable_info->page_num = 0; ++ cable_info->i2c_addr = I2C_ADDR_LOW; ++ cable_info->size = cpu_to_be16(1); ++ ++ ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3, ++ MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, ++ MLX4_CMD_NATIVE); ++ if (ret) ++ goto out; ++ ++ if (be16_to_cpu(outmad->status)) { ++ /* Mad returned with bad status */ ++ ret = be16_to_cpu(outmad->status); ++ mlx4_warn(dev, ++ "MLX4_CMD_MAD_IFC Get Module ID attr(%x) port(%d) i2c_addr(%x) offset(%d) size(%d): Response Mad Status(%x) - %s\n", ++ 0xFF60, port, I2C_ADDR_LOW, 0, 1, ret, ++ cable_info_mad_err_str(ret)); ++ ret = -ret; ++ goto out; ++ } ++ cable_info = (struct mlx4_cable_info *)outmad->data; ++ *module_id = cable_info->data[0]; ++out: ++ mlx4_free_cmd_mailbox(dev, inbox); ++ mlx4_free_cmd_mailbox(dev, outbox); ++ return ret; ++} ++ ++static void mlx4_sfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) ++{ ++ *i2c_addr = I2C_ADDR_LOW; ++ *page_num = 0; ++ ++ if (*offset < I2C_PAGE_SIZE) ++ return; ++ ++ *i2c_addr = I2C_ADDR_HIGH; ++ *offset -= I2C_PAGE_SIZE; ++} ++ ++static void mlx4_qsfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) ++{ ++ /* Offsets 0-255 belong to page 0. ++ * Offsets 256-639 belong to pages 01, 02, 03. ++ * For example, offset 400 is page 02: 1 + (400 - 256) / 128 = 2 ++ */ ++ if (*offset < I2C_PAGE_SIZE) ++ *page_num = 0; ++ else ++ *page_num = 1 + (*offset - I2C_PAGE_SIZE) / I2C_HIGH_PAGE_SIZE; ++ *i2c_addr = I2C_ADDR_LOW; ++ *offset -= *page_num * I2C_HIGH_PAGE_SIZE; ++} ++ + /** + * mlx4_get_module_info - Read cable module eeprom data + * @dev: mlx4_dev. +@@ -2045,12 +2128,30 @@ int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, + struct mlx4_cmd_mailbox *inbox, *outbox; + struct mlx4_mad_ifc *inmad, *outmad; + struct mlx4_cable_info *cable_info; +- u16 i2c_addr; ++ u8 module_id, i2c_addr, page_num; + int ret; + + if (size > MODULE_INFO_MAX_READ) + size = MODULE_INFO_MAX_READ; + ++ ret = mlx4_get_module_id(dev, port, &module_id); ++ if (ret) ++ return ret; ++ ++ switch (module_id) { ++ case MLX4_MODULE_ID_SFP: ++ mlx4_sfp_eeprom_params_set(&i2c_addr, &page_num, &offset); ++ break; ++ case MLX4_MODULE_ID_QSFP: ++ case MLX4_MODULE_ID_QSFP_PLUS: ++ case MLX4_MODULE_ID_QSFP28: ++ mlx4_qsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); ++ break; ++ default: ++ mlx4_err(dev, "Module ID not recognized: %#x\n", module_id); ++ return -EINVAL; ++ } ++ + inbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(inbox)) + return PTR_ERR(inbox); +@@ -2076,11 +2177,9 @@ int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, + */ + size -= offset + size - I2C_PAGE_SIZE; + +- i2c_addr = I2C_ADDR_LOW; +- + cable_info = (struct mlx4_cable_info *)inmad->data; + cable_info->dev_mem_address = cpu_to_be16(offset); +- cable_info->page_num = 0; ++ cable_info->page_num = page_num; + cable_info->i2c_addr = i2c_addr; + cable_info->size = cpu_to_be16(size); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 6495c26d95969..fe7342e8a043b 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -3170,8 +3170,12 @@ static int add_vlan_push_action(struct mlx5e_priv *priv, + if (err) + return err; + +- *out_dev = dev_get_by_index_rcu(dev_net(vlan_dev), +- dev_get_iflink(vlan_dev)); ++ rcu_read_lock(); ++ *out_dev = dev_get_by_index_rcu(dev_net(vlan_dev), dev_get_iflink(vlan_dev)); ++ rcu_read_unlock(); ++ if (!*out_dev) ++ return -ENODEV; ++ + if (is_vlan_dev(*out_dev)) + err = add_vlan_push_action(priv, attr, out_dev, action); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c b/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c +index 5d20d615663e7..bdc7f915d80e3 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c +@@ -307,6 +307,11 @@ int mlx5_lag_mp_init(struct mlx5_lag *ldev) + struct lag_mp *mp = &ldev->lag_mp; + int err; + ++ /* always clear mfi, as it might become stale when a route delete event ++ * has been missed ++ */ ++ mp->mfi = NULL; ++ + if (mp->fib_nb.notifier_call) + return 0; + +@@ -328,4 +333,5 @@ void mlx5_lag_mp_cleanup(struct mlx5_lag *ldev) + + unregister_fib_notifier(&mp->fib_nb); + mp->fib_nb.notifier_call = NULL; ++ mp->mfi = NULL; + } +diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c +index e102e1560ac79..7dc451fdaf35e 100644 +--- a/drivers/net/ethernet/micrel/ksz884x.c ++++ b/drivers/net/ethernet/micrel/ksz884x.c +@@ -1649,8 +1649,7 @@ static inline void set_tx_len(struct ksz_desc *desc, u32 len) + + #define HW_DELAY(hw, reg) \ + do { \ +- u16 dummy; \ +- dummy = readw(hw->io + reg); \ ++ readw(hw->io + reg); \ + } while (0) + + /** +diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c +index 4bbdc53eaf3f3..dfa0ded169ee9 100644 +--- a/drivers/net/ethernet/microchip/lan743x_main.c ++++ b/drivers/net/ethernet/microchip/lan743x_main.c +@@ -156,9 +156,8 @@ static void lan743x_tx_isr(void *context, u32 int_sts, u32 flags) + struct lan743x_tx *tx = context; + struct lan743x_adapter *adapter = tx->adapter; + bool enable_flag = true; +- u32 int_en = 0; + +- int_en = lan743x_csr_read(adapter, INT_EN_SET); ++ lan743x_csr_read(adapter, INT_EN_SET); + if (flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR) { + lan743x_csr_write(adapter, INT_EN_CLR, + INT_BIT_DMA_TX_(tx->channel_number)); +@@ -1631,10 +1630,9 @@ static int lan743x_tx_napi_poll(struct napi_struct *napi, int weight) + bool start_transmitter = false; + unsigned long irq_flags = 0; + u32 ioc_bit = 0; +- u32 int_sts = 0; + + ioc_bit = DMAC_INT_BIT_TX_IOC_(tx->channel_number); +- int_sts = lan743x_csr_read(adapter, DMAC_INT_STS); ++ lan743x_csr_read(adapter, DMAC_INT_STS); + if (tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C) + lan743x_csr_write(adapter, DMAC_INT_STS, ioc_bit); + spin_lock_irqsave(&tx->ring_lock, irq_flags); +diff --git a/drivers/net/ethernet/neterion/vxge/vxge-traffic.c b/drivers/net/ethernet/neterion/vxge/vxge-traffic.c +index 709d20d9938fb..bd525e8eda10c 100644 +--- a/drivers/net/ethernet/neterion/vxge/vxge-traffic.c ++++ b/drivers/net/ethernet/neterion/vxge/vxge-traffic.c +@@ -30,8 +30,6 @@ + */ + enum vxge_hw_status vxge_hw_vpath_intr_enable(struct __vxge_hw_vpath_handle *vp) + { +- u64 val64; +- + struct __vxge_hw_virtualpath *vpath; + struct vxge_hw_vpath_reg __iomem *vp_reg; + enum vxge_hw_status status = VXGE_HW_OK; +@@ -84,7 +82,7 @@ enum vxge_hw_status vxge_hw_vpath_intr_enable(struct __vxge_hw_vpath_handle *vp) + __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL, + &vp_reg->xgmac_vp_int_status); + +- val64 = readq(&vp_reg->vpath_general_int_status); ++ readq(&vp_reg->vpath_general_int_status); + + /* Mask unwanted interrupts */ + +@@ -157,8 +155,6 @@ exit: + enum vxge_hw_status vxge_hw_vpath_intr_disable( + struct __vxge_hw_vpath_handle *vp) + { +- u64 val64; +- + struct __vxge_hw_virtualpath *vpath; + enum vxge_hw_status status = VXGE_HW_OK; + struct vxge_hw_vpath_reg __iomem *vp_reg; +@@ -179,8 +175,6 @@ enum vxge_hw_status vxge_hw_vpath_intr_disable( + (u32)VXGE_HW_INTR_MASK_ALL, + &vp_reg->vpath_general_int_mask); + +- val64 = VXGE_HW_TIM_CLR_INT_EN_VP(1 << (16 - vpath->vp_id)); +- + writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->kdfcctl_errors_mask); + + __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL, +@@ -487,9 +481,7 @@ void vxge_hw_device_unmask_all(struct __vxge_hw_device *hldev) + */ + void vxge_hw_device_flush_io(struct __vxge_hw_device *hldev) + { +- u32 val32; +- +- val32 = readl(&hldev->common_reg->titan_general_int_status); ++ readl(&hldev->common_reg->titan_general_int_status); + } + + /** +@@ -1716,8 +1708,8 @@ void vxge_hw_fifo_txdl_free(struct __vxge_hw_fifo *fifo, void *txdlh) + enum vxge_hw_status + vxge_hw_vpath_mac_addr_add( + struct __vxge_hw_vpath_handle *vp, +- u8 (macaddr)[ETH_ALEN], +- u8 (macaddr_mask)[ETH_ALEN], ++ u8 *macaddr, ++ u8 *macaddr_mask, + enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode) + { + u32 i; +@@ -1779,8 +1771,8 @@ exit: + enum vxge_hw_status + vxge_hw_vpath_mac_addr_get( + struct __vxge_hw_vpath_handle *vp, +- u8 (macaddr)[ETH_ALEN], +- u8 (macaddr_mask)[ETH_ALEN]) ++ u8 *macaddr, ++ u8 *macaddr_mask) + { + u32 i; + u64 data1 = 0ULL; +@@ -1831,8 +1823,8 @@ exit: + enum vxge_hw_status + vxge_hw_vpath_mac_addr_get_next( + struct __vxge_hw_vpath_handle *vp, +- u8 (macaddr)[ETH_ALEN], +- u8 (macaddr_mask)[ETH_ALEN]) ++ u8 *macaddr, ++ u8 *macaddr_mask) + { + u32 i; + u64 data1 = 0ULL; +@@ -1884,8 +1876,8 @@ exit: + enum vxge_hw_status + vxge_hw_vpath_mac_addr_delete( + struct __vxge_hw_vpath_handle *vp, +- u8 (macaddr)[ETH_ALEN], +- u8 (macaddr_mask)[ETH_ALEN]) ++ u8 *macaddr, ++ u8 *macaddr_mask) + { + u32 i; + u64 data1 = 0ULL; +@@ -2375,7 +2367,6 @@ enum vxge_hw_status vxge_hw_vpath_poll_rx(struct __vxge_hw_ring *ring) + u8 t_code; + enum vxge_hw_status status = VXGE_HW_OK; + void *first_rxdh; +- u64 val64 = 0; + int new_count = 0; + + ring->cmpl_cnt = 0; +@@ -2403,8 +2394,7 @@ enum vxge_hw_status vxge_hw_vpath_poll_rx(struct __vxge_hw_ring *ring) + } + writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(new_count), + &ring->vp_reg->prc_rxd_doorbell); +- val64 = +- readl(&ring->common_reg->titan_general_int_status); ++ readl(&ring->common_reg->titan_general_int_status); + ring->doorbell_cnt = 0; + } + } +diff --git a/drivers/net/ethernet/sfc/falcon/farch.c b/drivers/net/ethernet/sfc/falcon/farch.c +index 332183280a459..612a43233b18b 100644 +--- a/drivers/net/ethernet/sfc/falcon/farch.c ++++ b/drivers/net/ethernet/sfc/falcon/farch.c +@@ -870,17 +870,12 @@ static u16 ef4_farch_handle_rx_not_ok(struct ef4_rx_queue *rx_queue, + { + struct ef4_channel *channel = ef4_rx_queue_channel(rx_queue); + struct ef4_nic *efx = rx_queue->efx; +- bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err; ++ bool __maybe_unused rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err; + bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err; + bool rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc; +- bool rx_ev_other_err, rx_ev_pause_frm; +- bool rx_ev_hdr_type, rx_ev_mcast_pkt; +- unsigned rx_ev_pkt_type; ++ bool rx_ev_pause_frm; + +- rx_ev_hdr_type = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); +- rx_ev_mcast_pkt = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_PKT); + rx_ev_tobe_disc = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_TOBE_DISC); +- rx_ev_pkt_type = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_TYPE); + rx_ev_buf_owner_id_err = EF4_QWORD_FIELD(*event, + FSF_AZ_RX_EV_BUF_OWNER_ID_ERR); + rx_ev_ip_hdr_chksum_err = EF4_QWORD_FIELD(*event, +@@ -893,10 +888,6 @@ static u16 ef4_farch_handle_rx_not_ok(struct ef4_rx_queue *rx_queue, + 0 : EF4_QWORD_FIELD(*event, FSF_AA_RX_EV_DRIB_NIB)); + rx_ev_pause_frm = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_PAUSE_FRM_ERR); + +- /* Every error apart from tobe_disc and pause_frm */ +- rx_ev_other_err = (rx_ev_drib_nib | rx_ev_tcp_udp_chksum_err | +- rx_ev_buf_owner_id_err | rx_ev_eth_crc_err | +- rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err); + + /* Count errors that are not in MAC stats. Ignore expected + * checksum errors during self-test. */ +@@ -916,6 +907,13 @@ static u16 ef4_farch_handle_rx_not_ok(struct ef4_rx_queue *rx_queue, + * to a FIFO overflow. + */ + #ifdef DEBUG ++ { ++ /* Every error apart from tobe_disc and pause_frm */ ++ ++ bool rx_ev_other_err = (rx_ev_drib_nib | rx_ev_tcp_udp_chksum_err | ++ rx_ev_buf_owner_id_err | rx_ev_eth_crc_err | ++ rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err); ++ + if (rx_ev_other_err && net_ratelimit()) { + netif_dbg(efx, rx_err, efx->net_dev, + " RX queue %d unexpected RX event " +@@ -932,6 +930,7 @@ static u16 ef4_farch_handle_rx_not_ok(struct ef4_rx_queue *rx_queue, + rx_ev_tobe_disc ? " [TOBE_DISC]" : "", + rx_ev_pause_frm ? " [PAUSE]" : ""); + } ++ } + #endif + + /* The frame must be discarded if any of these are true. */ +@@ -1643,15 +1642,11 @@ void ef4_farch_rx_push_indir_table(struct ef4_nic *efx) + */ + void ef4_farch_dimension_resources(struct ef4_nic *efx, unsigned sram_lim_qw) + { +- unsigned vi_count, buftbl_min; ++ unsigned vi_count; + + /* Account for the buffer table entries backing the datapath channels + * and the descriptor caches for those channels. + */ +- buftbl_min = ((efx->n_rx_channels * EF4_MAX_DMAQ_SIZE + +- efx->n_tx_channels * EF4_TXQ_TYPES * EF4_MAX_DMAQ_SIZE + +- efx->n_channels * EF4_MAX_EVQ_SIZE) +- * sizeof(ef4_qword_t) / EF4_BUF_SIZE); + vi_count = max(efx->n_channels, efx->n_tx_channels * EF4_TXQ_TYPES); + + efx->tx_dc_base = sram_lim_qw - vi_count * TX_DC_ENTRIES; +@@ -2532,7 +2527,6 @@ int ef4_farch_filter_remove_safe(struct ef4_nic *efx, + enum ef4_farch_filter_table_id table_id; + struct ef4_farch_filter_table *table; + unsigned int filter_idx; +- struct ef4_farch_filter_spec *spec; + int rc; + + table_id = ef4_farch_filter_id_table_id(filter_id); +@@ -2543,7 +2537,6 @@ int ef4_farch_filter_remove_safe(struct ef4_nic *efx, + filter_idx = ef4_farch_filter_id_index(filter_id); + if (filter_idx >= table->size) + return -ENOENT; +- spec = &table->spec[filter_idx]; + + spin_lock_bh(&efx->filter_lock); + rc = ef4_farch_filter_remove(efx, table, filter_idx, priority); +diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c +index 85eaccbbbac1c..44fe2adf0ee0c 100644 +--- a/drivers/net/ethernet/sis/sis900.c ++++ b/drivers/net/ethernet/sis/sis900.c +@@ -787,10 +787,9 @@ static u16 sis900_default_phy(struct net_device * net_dev) + static void sis900_set_capability(struct net_device *net_dev, struct mii_phy *phy) + { + u16 cap; +- u16 status; + +- status = mdio_read(net_dev, phy->phy_addr, MII_STATUS); +- status = mdio_read(net_dev, phy->phy_addr, MII_STATUS); ++ mdio_read(net_dev, phy->phy_addr, MII_STATUS); ++ mdio_read(net_dev, phy->phy_addr, MII_STATUS); + + cap = MII_NWAY_CSMA_CD | + ((phy->status & MII_STAT_CAN_TX_FDX)? MII_NWAY_TX_FDX:0) | +diff --git a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c +index eb1c6b03c329a..df26cea459048 100644 +--- a/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c ++++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c +@@ -513,7 +513,7 @@ void xlgmac_get_all_hw_features(struct xlgmac_pdata *pdata) + + void xlgmac_print_all_hw_features(struct xlgmac_pdata *pdata) + { +- char *str = NULL; ++ char __maybe_unused *str = NULL; + + XLGMAC_PR("\n"); + XLGMAC_PR("=====================================================\n"); +diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c +index 7cc09a6f9f9ae..6869c5c74b9f7 100644 +--- a/drivers/net/ethernet/ti/davinci_emac.c ++++ b/drivers/net/ethernet/ti/davinci_emac.c +@@ -1226,7 +1226,7 @@ static int emac_poll(struct napi_struct *napi, int budget) + struct net_device *ndev = priv->ndev; + struct device *emac_dev = &ndev->dev; + u32 status = 0; +- u32 num_tx_pkts = 0, num_rx_pkts = 0; ++ u32 num_rx_pkts = 0; + + /* Check interrupt vectors and call packet processing */ + status = emac_read(EMAC_MACINVECTOR); +@@ -1237,8 +1237,7 @@ static int emac_poll(struct napi_struct *napi, int budget) + mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC; + + if (status & mask) { +- num_tx_pkts = cpdma_chan_process(priv->txchan, +- EMAC_DEF_TX_MAX_SERVICE); ++ cpdma_chan_process(priv->txchan, EMAC_DEF_TX_MAX_SERVICE); + } /* TX processing */ + + mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC; +diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c +index 1b2702f744552..4154c48d1ddf6 100644 +--- a/drivers/net/ethernet/ti/netcp_core.c ++++ b/drivers/net/ethernet/ti/netcp_core.c +@@ -1350,9 +1350,9 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe) + tx_pipe->dma_queue = knav_queue_open(name, tx_pipe->dma_queue_id, + KNAV_QUEUE_SHARED); + if (IS_ERR(tx_pipe->dma_queue)) { ++ ret = PTR_ERR(tx_pipe->dma_queue); + dev_err(dev, "Could not open DMA queue for channel \"%s\": %d\n", + name, ret); +- ret = PTR_ERR(tx_pipe->dma_queue); + goto err; + } + +diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c +index 78f0f2d59e227..a3691bc94b101 100644 +--- a/drivers/net/ethernet/ti/tlan.c ++++ b/drivers/net/ethernet/ti/tlan.c +@@ -673,7 +673,6 @@ module_exit(tlan_exit); + static void __init tlan_eisa_probe(void) + { + long ioaddr; +- int rc = -ENODEV; + int irq; + u16 device_id; + +@@ -738,8 +737,7 @@ static void __init tlan_eisa_probe(void) + + + /* Setup the newly found eisa adapter */ +- rc = tlan_probe1(NULL, ioaddr, irq, +- 12, NULL); ++ tlan_probe1(NULL, ioaddr, irq, 12, NULL); + continue; + + out: +diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c +index 346e44115c4e0..24a82d51fe60d 100644 +--- a/drivers/net/ethernet/via/via-velocity.c ++++ b/drivers/net/ethernet/via/via-velocity.c +@@ -865,26 +865,13 @@ static u32 check_connection_type(struct mac_regs __iomem *regs) + */ + static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) + { +- u32 curr_status; + struct mac_regs __iomem *regs = vptr->mac_regs; + + vptr->mii_status = mii_check_media_mode(vptr->mac_regs); +- curr_status = vptr->mii_status & (~VELOCITY_LINK_FAIL); + + /* Set mii link status */ + set_mii_flow_control(vptr); + +- /* +- Check if new status is consistent with current status +- if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE) || +- (mii_status==curr_status)) { +- vptr->mii_status=mii_check_media_mode(vptr->mac_regs); +- vptr->mii_status=check_connection_type(vptr->mac_regs); +- VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n"); +- return 0; +- } +- */ +- + if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201) + MII_REG_BITS_ON(AUXCR_MDPPS, MII_NCONFIG, vptr->mac_regs); + +diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c +index 8327382aa5689..088c737316526 100644 +--- a/drivers/net/phy/mdio-octeon.c ++++ b/drivers/net/phy/mdio-octeon.c +@@ -72,7 +72,6 @@ static int octeon_mdiobus_probe(struct platform_device *pdev) + + return 0; + fail_register: +- mdiobus_free(bus->mii_bus); + smi_en.u64 = 0; + oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN); + return err; +@@ -86,7 +85,6 @@ static int octeon_mdiobus_remove(struct platform_device *pdev) + bus = platform_get_drvdata(pdev); + + mdiobus_unregister(bus->mii_bus); +- mdiobus_free(bus->mii_bus); + smi_en.u64 = 0; + oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN); + return 0; +diff --git a/drivers/net/phy/mdio-thunder.c b/drivers/net/phy/mdio-thunder.c +index b6128ae7f14f3..1e2f57ed1ef75 100644 +--- a/drivers/net/phy/mdio-thunder.c ++++ b/drivers/net/phy/mdio-thunder.c +@@ -126,7 +126,6 @@ static void thunder_mdiobus_pci_remove(struct pci_dev *pdev) + continue; + + mdiobus_unregister(bus->mii_bus); +- mdiobus_free(bus->mii_bus); + oct_mdio_writeq(0, bus->register_base + SMI_EN); + } + pci_set_drvdata(pdev, NULL); +diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c +index 02de9480d3f06..22450c4a92251 100644 +--- a/drivers/net/usb/hso.c ++++ b/drivers/net/usb/hso.c +@@ -1689,7 +1689,7 @@ static int hso_serial_tiocmset(struct tty_struct *tty, + spin_unlock_irqrestore(&serial->serial_lock, flags); + + return usb_control_msg(serial->parent->usb, +- usb_rcvctrlpipe(serial->parent->usb, 0), 0x22, ++ usb_sndctrlpipe(serial->parent->usb, 0), 0x22, + 0x21, val, if_num, NULL, 0, + USB_CTRL_SET_TIMEOUT); + } +@@ -2436,7 +2436,7 @@ static int hso_rfkill_set_block(void *data, bool blocked) + if (hso_dev->usb_gone) + rv = 0; + else +- rv = usb_control_msg(hso_dev->usb, usb_rcvctrlpipe(hso_dev->usb, 0), ++ rv = usb_control_msg(hso_dev->usb, usb_sndctrlpipe(hso_dev->usb, 0), + enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0, + USB_CTRL_SET_TIMEOUT); + mutex_unlock(&hso_dev->mutex); +@@ -2619,32 +2619,31 @@ static struct hso_device *hso_create_bulk_serial_device( + num_urbs = 2; + serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), + GFP_KERNEL); ++ if (!serial->tiocmget) ++ goto exit; + serial->tiocmget->serial_state_notification + = kzalloc(sizeof(struct hso_serial_state_notification), + GFP_KERNEL); +- /* it isn't going to break our heart if serial->tiocmget +- * allocation fails don't bother checking this. +- */ +- if (serial->tiocmget && serial->tiocmget->serial_state_notification) { +- tiocmget = serial->tiocmget; +- tiocmget->endp = hso_get_ep(interface, +- USB_ENDPOINT_XFER_INT, +- USB_DIR_IN); +- if (!tiocmget->endp) { +- dev_err(&interface->dev, "Failed to find INT IN ep\n"); +- goto exit; +- } +- +- tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); +- if (tiocmget->urb) { +- mutex_init(&tiocmget->mutex); +- init_waitqueue_head(&tiocmget->waitq); +- } else +- hso_free_tiomget(serial); ++ if (!serial->tiocmget->serial_state_notification) ++ goto exit; ++ tiocmget = serial->tiocmget; ++ tiocmget->endp = hso_get_ep(interface, ++ USB_ENDPOINT_XFER_INT, ++ USB_DIR_IN); ++ if (!tiocmget->endp) { ++ dev_err(&interface->dev, "Failed to find INT IN ep\n"); ++ goto exit; + } +- } +- else ++ ++ tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!tiocmget->urb) ++ goto exit; ++ ++ mutex_init(&tiocmget->mutex); ++ init_waitqueue_head(&tiocmget->waitq); ++ } else { + num_urbs = 1; ++ } + + if (hso_serial_common_create(serial, num_urbs, BULK_URB_RX_SIZE, + BULK_URB_TX_SIZE)) +diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c +index 9556d431885f5..d0ae0df34e132 100644 +--- a/drivers/net/usb/smsc75xx.c ++++ b/drivers/net/usb/smsc75xx.c +@@ -1482,7 +1482,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) + ret = smsc75xx_wait_ready(dev, 0); + if (ret < 0) { + netdev_warn(dev->net, "device not ready in smsc75xx_bind\n"); +- return ret; ++ goto err; + } + + smsc75xx_init_mac_address(dev); +@@ -1491,7 +1491,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) + ret = smsc75xx_reset(dev); + if (ret < 0) { + netdev_warn(dev->net, "smsc75xx_reset error %d\n", ret); +- return ret; ++ goto err; + } + + dev->net->netdev_ops = &smsc75xx_netdev_ops; +@@ -1501,6 +1501,10 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) + dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; + dev->net->max_mtu = MAX_SINGLE_PACKET_SIZE; + return 0; ++ ++err: ++ kfree(pdata); ++ return ret; + } + + static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) +diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h +index bd5fa4dbab9c0..2637e188954d7 100644 +--- a/drivers/net/wireless/ath/ath10k/htt.h ++++ b/drivers/net/wireless/ath/ath10k/htt.h +@@ -835,6 +835,7 @@ enum htt_security_types { + + #define ATH10K_HTT_TXRX_PEER_SECURITY_MAX 2 + #define ATH10K_TXRX_NUM_EXT_TIDS 19 ++#define ATH10K_TXRX_NON_QOS_TID 16 + + enum htt_security_flags { + #define HTT_SECURITY_TYPE_MASK 0x7F +diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c +index 04095f91d3014..760d24a28f392 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -1739,16 +1739,97 @@ static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu) + msdu->ip_summed = ath10k_htt_rx_get_csum_state(msdu); + } + ++static u64 ath10k_htt_rx_h_get_pn(struct ath10k *ar, struct sk_buff *skb, ++ u16 offset, ++ enum htt_rx_mpdu_encrypt_type enctype) ++{ ++ struct ieee80211_hdr *hdr; ++ u64 pn = 0; ++ u8 *ehdr; ++ ++ hdr = (struct ieee80211_hdr *)(skb->data + offset); ++ ehdr = skb->data + offset + ieee80211_hdrlen(hdr->frame_control); ++ ++ if (enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) { ++ pn = ehdr[0]; ++ pn |= (u64)ehdr[1] << 8; ++ pn |= (u64)ehdr[4] << 16; ++ pn |= (u64)ehdr[5] << 24; ++ pn |= (u64)ehdr[6] << 32; ++ pn |= (u64)ehdr[7] << 40; ++ } ++ return pn; ++} ++ ++static bool ath10k_htt_rx_h_frag_multicast_check(struct ath10k *ar, ++ struct sk_buff *skb, ++ u16 offset) ++{ ++ struct ieee80211_hdr *hdr; ++ ++ hdr = (struct ieee80211_hdr *)(skb->data + offset); ++ return !is_multicast_ether_addr(hdr->addr1); ++} ++ ++static bool ath10k_htt_rx_h_frag_pn_check(struct ath10k *ar, ++ struct sk_buff *skb, ++ u16 peer_id, ++ u16 offset, ++ enum htt_rx_mpdu_encrypt_type enctype) ++{ ++ struct ath10k_peer *peer; ++ union htt_rx_pn_t *last_pn, new_pn = {0}; ++ struct ieee80211_hdr *hdr; ++ bool more_frags; ++ u8 tid, frag_number; ++ u32 seq; ++ ++ peer = ath10k_peer_find_by_id(ar, peer_id); ++ if (!peer) { ++ ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid peer for frag pn check\n"); ++ return false; ++ } ++ ++ hdr = (struct ieee80211_hdr *)(skb->data + offset); ++ if (ieee80211_is_data_qos(hdr->frame_control)) ++ tid = ieee80211_get_tid(hdr); ++ else ++ tid = ATH10K_TXRX_NON_QOS_TID; ++ ++ last_pn = &peer->frag_tids_last_pn[tid]; ++ new_pn.pn48 = ath10k_htt_rx_h_get_pn(ar, skb, offset, enctype); ++ more_frags = ieee80211_has_morefrags(hdr->frame_control); ++ frag_number = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; ++ seq = (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; ++ ++ if (frag_number == 0) { ++ last_pn->pn48 = new_pn.pn48; ++ peer->frag_tids_seq[tid] = seq; ++ } else { ++ if (seq != peer->frag_tids_seq[tid]) ++ return false; ++ ++ if (new_pn.pn48 != last_pn->pn48 + 1) ++ return false; ++ ++ last_pn->pn48 = new_pn.pn48; ++ } ++ ++ return true; ++} ++ + static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *status, + bool fill_crypt_header, + u8 *rx_hdr, +- enum ath10k_pkt_rx_err *err) ++ enum ath10k_pkt_rx_err *err, ++ u16 peer_id, ++ bool frag) + { + struct sk_buff *first; + struct sk_buff *last; +- struct sk_buff *msdu; ++ struct sk_buff *msdu, *temp; + struct htt_rx_desc *rxd; + struct ieee80211_hdr *hdr; + enum htt_rx_mpdu_encrypt_type enctype; +@@ -1761,6 +1842,7 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + bool is_decrypted; + bool is_mgmt; + u32 attention; ++ bool frag_pn_check = true, multicast_check = true; + + if (skb_queue_empty(amsdu)) + return; +@@ -1859,7 +1941,37 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + } + + skb_queue_walk(amsdu, msdu) { ++ if (frag && !fill_crypt_header && is_decrypted && ++ enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) ++ frag_pn_check = ath10k_htt_rx_h_frag_pn_check(ar, ++ msdu, ++ peer_id, ++ 0, ++ enctype); ++ ++ if (frag) ++ multicast_check = ath10k_htt_rx_h_frag_multicast_check(ar, ++ msdu, ++ 0); ++ ++ if (!frag_pn_check || !multicast_check) { ++ /* Discard the fragment with invalid PN or multicast DA ++ */ ++ temp = msdu->prev; ++ __skb_unlink(msdu, amsdu); ++ dev_kfree_skb_any(msdu); ++ msdu = temp; ++ frag_pn_check = true; ++ multicast_check = true; ++ continue; ++ } ++ + ath10k_htt_rx_h_csum_offload(msdu); ++ ++ if (frag && !fill_crypt_header && ++ enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) ++ status->flag &= ~RX_FLAG_MMIC_STRIPPED; ++ + ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype, + is_decrypted); + +@@ -1877,6 +1989,11 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + + hdr = (void *)msdu->data; + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); ++ ++ if (frag && !fill_crypt_header && ++ enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) ++ status->flag &= ~RX_FLAG_IV_STRIPPED & ++ ~RX_FLAG_MMIC_STRIPPED; + } + } + +@@ -1984,14 +2101,62 @@ static void ath10k_htt_rx_h_unchain(struct ath10k *ar, + ath10k_unchain_msdu(amsdu, unchain_cnt); + } + ++static bool ath10k_htt_rx_validate_amsdu(struct ath10k *ar, ++ struct sk_buff_head *amsdu) ++{ ++ u8 *subframe_hdr; ++ struct sk_buff *first; ++ bool is_first, is_last; ++ struct htt_rx_desc *rxd; ++ struct ieee80211_hdr *hdr; ++ size_t hdr_len, crypto_len; ++ enum htt_rx_mpdu_encrypt_type enctype; ++ int bytes_aligned = ar->hw_params.decap_align_bytes; ++ ++ first = skb_peek(amsdu); ++ ++ rxd = (void *)first->data - sizeof(*rxd); ++ hdr = (void *)rxd->rx_hdr_status; ++ ++ is_first = !!(rxd->msdu_end.common.info0 & ++ __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); ++ is_last = !!(rxd->msdu_end.common.info0 & ++ __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)); ++ ++ /* Return in case of non-aggregated msdu */ ++ if (is_first && is_last) ++ return true; ++ ++ /* First msdu flag is not set for the first msdu of the list */ ++ if (!is_first) ++ return false; ++ ++ enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), ++ RX_MPDU_START_INFO0_ENCRYPT_TYPE); ++ ++ hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); ++ ++ subframe_hdr = (u8 *)hdr + round_up(hdr_len, bytes_aligned) + ++ crypto_len; ++ ++ /* Validate if the amsdu has a proper first subframe. ++ * There are chances a single msdu can be received as amsdu when ++ * the unauthenticated amsdu flag of a QoS header ++ * gets flipped in non-SPP AMSDU's, in such cases the first ++ * subframe has llc/snap header in place of a valid da. ++ * return false if the da matches rfc1042 pattern ++ */ ++ if (ether_addr_equal(subframe_hdr, rfc1042_header)) ++ return false; ++ ++ return true; ++} ++ + static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, + struct sk_buff_head *amsdu, + struct ieee80211_rx_status *rx_status) + { +- /* FIXME: It might be a good idea to do some fuzzy-testing to drop +- * invalid/dangerous frames. +- */ +- + if (!rx_status->freq) { + ath10k_dbg(ar, ATH10K_DBG_HTT, "no channel configured; ignoring frame(s)!\n"); + return false; +@@ -2002,6 +2167,11 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, + return false; + } + ++ if (!ath10k_htt_rx_validate_amsdu(ar, amsdu)) { ++ ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid amsdu received\n"); ++ return false; ++ } ++ + return true; + } + +@@ -2064,7 +2234,8 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) + ath10k_htt_rx_h_unchain(ar, &amsdu, &drop_cnt, &unchain_cnt); + + ath10k_htt_rx_h_filter(ar, &amsdu, rx_status, &drop_cnt_filter); +- ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err); ++ ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err, 0, ++ false); + msdus_to_queue = skb_queue_len(&amsdu); + ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status); + +@@ -2197,6 +2368,11 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt, + fw_desc = &rx->fw_desc; + rx_desc_len = fw_desc->len; + ++ if (fw_desc->u.bits.discard) { ++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt discard mpdu\n"); ++ goto err; ++ } ++ + /* I have not yet seen any case where num_mpdu_ranges > 1. + * qcacld does not seem handle that case either, so we introduce the + * same limitiation here as well. +@@ -2497,6 +2673,13 @@ static bool ath10k_htt_rx_proc_rx_frag_ind_hl(struct ath10k_htt *htt, + rx_desc = (struct htt_hl_rx_desc *)(skb->data + tot_hdr_len); + rx_desc_info = __le32_to_cpu(rx_desc->info); + ++ hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len); ++ ++ if (is_multicast_ether_addr(hdr->addr1)) { ++ /* Discard the fragment with multicast DA */ ++ goto err; ++ } ++ + if (!MS(rx_desc_info, HTT_RX_DESC_HL_INFO_ENCRYPTED)) { + spin_unlock_bh(&ar->data_lock); + return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb, +@@ -2504,8 +2687,6 @@ static bool ath10k_htt_rx_proc_rx_frag_ind_hl(struct ath10k_htt *htt, + HTT_RX_NON_TKIP_MIC); + } + +- hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len); +- + if (ieee80211_has_retry(hdr->frame_control)) + goto err; + +@@ -3014,7 +3195,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) + ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); + ath10k_htt_rx_h_filter(ar, &amsdu, status, NULL); + ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false, NULL, +- NULL); ++ NULL, peer_id, frag); + ath10k_htt_rx_h_enqueue(ar, &amsdu, status); + break; + case -EAGAIN: +diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h +index dec1582005b94..13a1cae6b51b0 100644 +--- a/drivers/net/wireless/ath/ath10k/rx_desc.h ++++ b/drivers/net/wireless/ath/ath10k/rx_desc.h +@@ -1282,7 +1282,19 @@ struct fw_rx_desc_base { + #define FW_RX_DESC_UDP (1 << 6) + + struct fw_rx_desc_hl { +- u8 info0; ++ union { ++ struct { ++ u8 discard:1, ++ forward:1, ++ any_err:1, ++ dup_err:1, ++ reserved:1, ++ inspect:1, ++ extension:2; ++ } bits; ++ u8 info0; ++ } u; ++ + u8 version; + u8 len; + u8 flags; +diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c +index 54337d60f288b..085a134069f79 100644 +--- a/drivers/net/wireless/ath/ath6kl/debug.c ++++ b/drivers/net/wireless/ath/ath6kl/debug.c +@@ -1027,14 +1027,17 @@ static ssize_t ath6kl_lrssi_roam_write(struct file *file, + { + struct ath6kl *ar = file->private_data; + unsigned long lrssi_roam_threshold; ++ int ret; + + if (kstrtoul_from_user(user_buf, count, 0, &lrssi_roam_threshold)) + return -EINVAL; + + ar->lrssi_roam_threshold = lrssi_roam_threshold; + +- ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, ar->lrssi_roam_threshold); ++ ret = ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, ar->lrssi_roam_threshold); + ++ if (ret) ++ return ret; + return count; + } + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +index fc12598b2dd3f..c492d2d2db1df 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -1168,13 +1168,9 @@ static struct sdio_driver brcmf_sdmmc_driver = { + }, + }; + +-void brcmf_sdio_register(void) ++int brcmf_sdio_register(void) + { +- int ret; +- +- ret = sdio_register_driver(&brcmf_sdmmc_driver); +- if (ret) +- brcmf_err("sdio_register_driver failed: %d\n", ret); ++ return sdio_register_driver(&brcmf_sdmmc_driver); + } + + void brcmf_sdio_exit(void) +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +index 623c0168da79c..8b27494a5d3dc 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -274,11 +274,26 @@ void brcmf_bus_add_txhdrlen(struct device *dev, uint len); + + #ifdef CONFIG_BRCMFMAC_SDIO + void brcmf_sdio_exit(void); +-void brcmf_sdio_register(void); ++int brcmf_sdio_register(void); ++#else ++static inline void brcmf_sdio_exit(void) { } ++static inline int brcmf_sdio_register(void) { return 0; } + #endif ++ + #ifdef CONFIG_BRCMFMAC_USB + void brcmf_usb_exit(void); +-void brcmf_usb_register(void); ++int brcmf_usb_register(void); ++#else ++static inline void brcmf_usb_exit(void) { } ++static inline int brcmf_usb_register(void) { return 0; } ++#endif ++ ++#ifdef CONFIG_BRCMFMAC_PCIE ++void brcmf_pcie_exit(void); ++int brcmf_pcie_register(void); ++#else ++static inline void brcmf_pcie_exit(void) { } ++static inline int brcmf_pcie_register(void) { return 0; } + #endif + + #endif /* BRCMFMAC_BUS_H */ +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +index e9bb8dbdc9aa8..edb79e9665dc3 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1438,40 +1438,34 @@ void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state) + } + } + +-static void brcmf_driver_register(struct work_struct *work) +-{ +-#ifdef CONFIG_BRCMFMAC_SDIO +- brcmf_sdio_register(); +-#endif +-#ifdef CONFIG_BRCMFMAC_USB +- brcmf_usb_register(); +-#endif +-#ifdef CONFIG_BRCMFMAC_PCIE +- brcmf_pcie_register(); +-#endif +-} +-static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); +- + int __init brcmf_core_init(void) + { +- if (!schedule_work(&brcmf_driver_work)) +- return -EBUSY; ++ int err; ++ ++ err = brcmf_sdio_register(); ++ if (err) ++ return err; ++ ++ err = brcmf_usb_register(); ++ if (err) ++ goto error_usb_register; + ++ err = brcmf_pcie_register(); ++ if (err) ++ goto error_pcie_register; + return 0; ++ ++error_pcie_register: ++ brcmf_usb_exit(); ++error_usb_register: ++ brcmf_sdio_exit(); ++ return err; + } + + void __exit brcmf_core_exit(void) + { +- cancel_work_sync(&brcmf_driver_work); +- +-#ifdef CONFIG_BRCMFMAC_SDIO + brcmf_sdio_exit(); +-#endif +-#ifdef CONFIG_BRCMFMAC_USB + brcmf_usb_exit(); +-#endif +-#ifdef CONFIG_BRCMFMAC_PCIE + brcmf_pcie_exit(); +-#endif + } + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +index cb68f54a9c56e..bda042138e967 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -2137,15 +2137,10 @@ static struct pci_driver brcmf_pciedrvr = { + }; + + +-void brcmf_pcie_register(void) ++int brcmf_pcie_register(void) + { +- int err; +- + brcmf_dbg(PCIE, "Enter\n"); +- err = pci_register_driver(&brcmf_pciedrvr); +- if (err) +- brcmf_err(NULL, "PCIE driver registration failed, err=%d\n", +- err); ++ return pci_register_driver(&brcmf_pciedrvr); + } + + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h +index d026401d20010..8e6c227e8315c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h +@@ -11,9 +11,4 @@ struct brcmf_pciedev { + struct brcmf_pciedev_info *devinfo; + }; + +- +-void brcmf_pcie_exit(void); +-void brcmf_pcie_register(void); +- +- + #endif /* BRCMFMAC_PCIE_H */ +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +index 575ed19e91951..3b897f040371c 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1558,12 +1558,8 @@ void brcmf_usb_exit(void) + usb_deregister(&brcmf_usbdrvr); + } + +-void brcmf_usb_register(void) ++int brcmf_usb_register(void) + { +- int ret; +- + brcmf_dbg(USB, "Enter\n"); +- ret = usb_register(&brcmf_usbdrvr); +- if (ret) +- brcmf_err("usb_register failed %d\n", ret); ++ return usb_register(&brcmf_usbdrvr); + } +diff --git a/drivers/net/wireless/marvell/libertas/mesh.c b/drivers/net/wireless/marvell/libertas/mesh.c +index 2747c957d18c9..050fd403110ed 100644 +--- a/drivers/net/wireless/marvell/libertas/mesh.c ++++ b/drivers/net/wireless/marvell/libertas/mesh.c +@@ -801,24 +801,6 @@ static const struct attribute_group mesh_ie_group = { + .attrs = mesh_ie_attrs, + }; + +-static void lbs_persist_config_init(struct net_device *dev) +-{ +- int ret; +- ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group); +- if (ret) +- pr_err("failed to create boot_opts_group.\n"); +- +- ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group); +- if (ret) +- pr_err("failed to create mesh_ie_group.\n"); +-} +- +-static void lbs_persist_config_remove(struct net_device *dev) +-{ +- sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group); +- sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group); +-} +- + + /*************************************************************************** + * Initializing and starting, stopping mesh +@@ -1019,6 +1001,10 @@ static int lbs_add_mesh(struct lbs_private *priv) + SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); + + mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; ++ mesh_dev->sysfs_groups[0] = &lbs_mesh_attr_group; ++ mesh_dev->sysfs_groups[1] = &boot_opts_group; ++ mesh_dev->sysfs_groups[2] = &mesh_ie_group; ++ + /* Register virtual mesh interface */ + ret = register_netdev(mesh_dev); + if (ret) { +@@ -1026,19 +1012,10 @@ static int lbs_add_mesh(struct lbs_private *priv) + goto err_free_netdev; + } + +- ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); +- if (ret) +- goto err_unregister; +- +- lbs_persist_config_init(mesh_dev); +- + /* Everything successful */ + ret = 0; + goto done; + +-err_unregister: +- unregister_netdev(mesh_dev); +- + err_free_netdev: + free_netdev(mesh_dev); + +@@ -1059,8 +1036,6 @@ void lbs_remove_mesh(struct lbs_private *priv) + + netif_stop_queue(mesh_dev); + netif_carrier_off(mesh_dev); +- sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); +- lbs_persist_config_remove(mesh_dev); + unregister_netdev(mesh_dev); + priv->mesh_dev = NULL; + kfree(mesh_dev->ieee80211_ptr); +diff --git a/drivers/platform/x86/hp-wireless.c b/drivers/platform/x86/hp-wireless.c +index 12c31fd5d5ae2..0753ef18e7211 100644 +--- a/drivers/platform/x86/hp-wireless.c ++++ b/drivers/platform/x86/hp-wireless.c +@@ -17,12 +17,14 @@ MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Alex Hung"); + MODULE_ALIAS("acpi*:HPQ6001:*"); + MODULE_ALIAS("acpi*:WSTADEF:*"); ++MODULE_ALIAS("acpi*:AMDI0051:*"); + + static struct input_dev *hpwl_input_dev; + + static const struct acpi_device_id hpwl_ids[] = { + {"HPQ6001", 0}, + {"WSTADEF", 0}, ++ {"AMDI0051", 0}, + {"", 0}, + }; + +diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c +index 799cbe2ffcf36..8c0867bda8280 100644 +--- a/drivers/platform/x86/hp_accel.c ++++ b/drivers/platform/x86/hp_accel.c +@@ -88,6 +88,9 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids); + static int lis3lv02d_acpi_init(struct lis3lv02d *lis3) + { + struct acpi_device *dev = lis3->bus_priv; ++ if (!lis3->init_required) ++ return 0; ++ + if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI, + NULL, NULL) != AE_OK) + return -EINVAL; +@@ -356,6 +359,7 @@ static int lis3lv02d_add(struct acpi_device *device) + } + + /* call the core layer do its init */ ++ lis3_dev.init_required = true; + ret = lis3lv02d_init_device(&lis3_dev); + if (ret) + return ret; +@@ -403,11 +407,27 @@ static int lis3lv02d_suspend(struct device *dev) + + static int lis3lv02d_resume(struct device *dev) + { ++ lis3_dev.init_required = false; ++ lis3lv02d_poweron(&lis3_dev); ++ return 0; ++} ++ ++static int lis3lv02d_restore(struct device *dev) ++{ ++ lis3_dev.init_required = true; + lis3lv02d_poweron(&lis3_dev); + return 0; + } + +-static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume); ++static const struct dev_pm_ops hp_accel_pm = { ++ .suspend = lis3lv02d_suspend, ++ .resume = lis3lv02d_resume, ++ .freeze = lis3lv02d_suspend, ++ .thaw = lis3lv02d_resume, ++ .poweroff = lis3lv02d_suspend, ++ .restore = lis3lv02d_restore, ++}; ++ + #define HP_ACCEL_PM (&hp_accel_pm) + #else + #define HP_ACCEL_PM NULL +diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c +index fa97834fdb78e..ccb44f2eb2407 100644 +--- a/drivers/platform/x86/intel_punit_ipc.c ++++ b/drivers/platform/x86/intel_punit_ipc.c +@@ -328,6 +328,7 @@ static const struct acpi_device_id punit_ipc_acpi_ids[] = { + { "INT34D4", 0 }, + { } + }; ++MODULE_DEVICE_TABLE(acpi, punit_ipc_acpi_ids); + + static struct platform_driver intel_punit_ipc_driver = { + .probe = intel_punit_ipc_probe, +diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c +index 7ed1189a7200c..515c66ca1aecb 100644 +--- a/drivers/platform/x86/touchscreen_dmi.c ++++ b/drivers/platform/x86/touchscreen_dmi.c +@@ -838,6 +838,14 @@ static const struct dmi_system_id touchscreen_dmi_table[] = { + DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"), + }, + }, ++ { ++ /* Mediacom WinPad 7.0 W700 (same hw as Wintron surftab 7") */ ++ .driver_data = (void *)&trekstor_surftab_wintron70_data, ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "MEDIACOM"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "WinPad 7 W10 - WPW700"), ++ }, ++ }, + { + /* Mediacom Flexbook Edge 11 (same hw as TS Primebook C11) */ + .driver_data = (void *)&trekstor_primebook_c11_data, +diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c +index 3645d1720c4b5..9628e0f3add3f 100644 +--- a/drivers/s390/cio/vfio_ccw_cp.c ++++ b/drivers/s390/cio/vfio_ccw_cp.c +@@ -636,6 +636,10 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb) + { + int ret; + ++ /* this is an error in the caller */ ++ if (cp->initialized) ++ return -EBUSY; ++ + /* + * XXX: + * Only support prefetch enable mode now. +diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c +index c25e8a54e8690..6e988233fb81f 100644 +--- a/drivers/scsi/BusLogic.c ++++ b/drivers/scsi/BusLogic.c +@@ -3077,11 +3077,11 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, + ccb->opcode = BLOGIC_INITIATOR_CCB_SG; + ccb->datalen = count * sizeof(struct blogic_sg_seg); + if (blogic_multimaster_type(adapter)) +- ccb->data = (void *)((unsigned int) ccb->dma_handle + ++ ccb->data = (unsigned int) ccb->dma_handle + + ((unsigned long) &ccb->sglist - +- (unsigned long) ccb)); ++ (unsigned long) ccb); + else +- ccb->data = ccb->sglist; ++ ccb->data = virt_to_32bit_virt(ccb->sglist); + + scsi_for_each_sg(command, sg, count, i) { + ccb->sglist[i].segbytes = sg_dma_len(sg); +diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h +index 6182cc8a0344a..e081ad47d1cf4 100644 +--- a/drivers/scsi/BusLogic.h ++++ b/drivers/scsi/BusLogic.h +@@ -814,7 +814,7 @@ struct blogic_ccb { + unsigned char cdblen; /* Byte 2 */ + unsigned char sense_datalen; /* Byte 3 */ + u32 datalen; /* Bytes 4-7 */ +- void *data; /* Bytes 8-11 */ ++ u32 data; /* Bytes 8-11 */ + unsigned char:8; /* Byte 12 */ + unsigned char:8; /* Byte 13 */ + enum blogic_adapter_status adapter_status; /* Byte 14 */ +diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c +index 7c86fd248129a..f751a12f92ea0 100644 +--- a/drivers/scsi/libsas/sas_port.c ++++ b/drivers/scsi/libsas/sas_port.c +@@ -25,7 +25,7 @@ static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy + + static void sas_resume_port(struct asd_sas_phy *phy) + { +- struct domain_device *dev; ++ struct domain_device *dev, *n; + struct asd_sas_port *port = phy->port; + struct sas_ha_struct *sas_ha = phy->ha; + struct sas_internal *si = to_sas_internal(sas_ha->core.shost->transportt); +@@ -44,7 +44,7 @@ static void sas_resume_port(struct asd_sas_phy *phy) + * 1/ presume every device came back + * 2/ force the next revalidation to check all expander phys + */ +- list_for_each_entry(dev, &port->dev_list, dev_list_node) { ++ list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) { + int i, rc; + + rc = sas_notify_lldd_dev_found(dev); +diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c +index c7560d7d16276..40dccc580e866 100644 +--- a/drivers/spi/spi-fsl-dspi.c ++++ b/drivers/spi/spi-fsl-dspi.c +@@ -1142,11 +1142,13 @@ poll_mode: + ret = spi_register_controller(ctlr); + if (ret != 0) { + dev_err(&pdev->dev, "Problem registering DSPI ctlr\n"); +- goto out_free_irq; ++ goto out_release_dma; + } + + return ret; + ++out_release_dma: ++ dspi_release_dma(dspi); + out_free_irq: + if (dspi->irq) + free_irq(dspi->irq, dspi); +diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c +index 6f3d64a1a2b3e..01b53d816497c 100644 +--- a/drivers/spi/spi-geni-qcom.c ++++ b/drivers/spi/spi-geni-qcom.c +@@ -552,7 +552,7 @@ static int spi_geni_probe(struct platform_device *pdev) + return PTR_ERR(clk); + } + +- spi = spi_alloc_master(&pdev->dev, sizeof(*mas)); ++ spi = devm_spi_alloc_master(&pdev->dev, sizeof(*mas)); + if (!spi) + return -ENOMEM; + +@@ -599,7 +599,6 @@ spi_geni_probe_free_irq: + free_irq(mas->irq, spi); + spi_geni_probe_runtime_disable: + pm_runtime_disable(&pdev->dev); +- spi_master_put(spi); + return ret; + } + +diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c +index a6c893ddbf280..cc4c18c3fb36d 100644 +--- a/drivers/staging/emxx_udc/emxx_udc.c ++++ b/drivers/staging/emxx_udc/emxx_udc.c +@@ -2064,7 +2064,7 @@ static int _nbu2ss_nuke(struct nbu2ss_udc *udc, + struct nbu2ss_ep *ep, + int status) + { +- struct nbu2ss_req *req; ++ struct nbu2ss_req *req, *n; + + /* Endpoint Disable */ + _nbu2ss_epn_exit(udc, ep); +@@ -2076,7 +2076,7 @@ static int _nbu2ss_nuke(struct nbu2ss_udc *udc, + return 0; + + /* called with irqs blocked */ +- list_for_each_entry(req, &ep->queue, queue) { ++ list_for_each_entry_safe(req, n, &ep->queue, queue) { + _nbu2ss_ep_done(ep, req, status); + } + +diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c +index 21527d84f9408..004f123bb0708 100644 +--- a/drivers/staging/iio/cdc/ad7746.c ++++ b/drivers/staging/iio/cdc/ad7746.c +@@ -702,7 +702,6 @@ static int ad7746_probe(struct i2c_client *client, + indio_dev->num_channels = ARRAY_SIZE(ad7746_channels); + else + indio_dev->num_channels = ARRAY_SIZE(ad7746_channels) - 2; +- indio_dev->num_channels = ARRAY_SIZE(ad7746_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + + if (pdata) { +diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +index 75484d6c5056a..c313c4f0e8563 100644 +--- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c ++++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +@@ -230,6 +230,8 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, + if (ACPI_FAILURE(status)) + trip_cnt = 0; + else { ++ int i; ++ + int34x_thermal_zone->aux_trips = + kcalloc(trip_cnt, + sizeof(*int34x_thermal_zone->aux_trips), +@@ -240,6 +242,8 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, + } + trip_mask = BIT(trip_cnt) - 1; + int34x_thermal_zone->aux_trip_nr = trip_cnt; ++ for (i = 0; i < trip_cnt; ++i) ++ int34x_thermal_zone->aux_trips[i] = THERMAL_TEMP_INVALID; + } + + trip_cnt = int340x_thermal_read_trips(int34x_thermal_zone); +diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c +index ddb4a973c6986..691931fdc1195 100644 +--- a/drivers/thermal/intel/x86_pkg_temp_thermal.c ++++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c +@@ -164,7 +164,7 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzd, + if (thres_reg_value) + *temp = zonedev->tj_max - thres_reg_value * 1000; + else +- *temp = 0; ++ *temp = THERMAL_TEMP_INVALID; + pr_debug("sys_get_trip_temp %d\n", *temp); + + return 0; +diff --git a/drivers/thunderbolt/dma_port.c b/drivers/thunderbolt/dma_port.c +index 847dd07a7b172..de219953c8b37 100644 +--- a/drivers/thunderbolt/dma_port.c ++++ b/drivers/thunderbolt/dma_port.c +@@ -364,15 +364,15 @@ int dma_port_flash_read(struct tb_dma_port *dma, unsigned int address, + void *buf, size_t size) + { + unsigned int retries = DMA_PORT_RETRIES; +- unsigned int offset; +- +- offset = address & 3; +- address = address & ~3; + + do { +- u32 nbytes = min_t(u32, size, MAIL_DATA_DWORDS * 4); ++ unsigned int offset; ++ size_t nbytes; + int ret; + ++ offset = address & 3; ++ nbytes = min_t(size_t, size + offset, MAIL_DATA_DWORDS * 4); ++ + ret = dma_port_flash_read_block(dma, address, dma->buf, + ALIGN(nbytes, 4)); + if (ret) { +@@ -384,6 +384,7 @@ int dma_port_flash_read(struct tb_dma_port *dma, unsigned int address, + return ret; + } + ++ nbytes -= offset; + memcpy(buf, dma->buf + offset, nbytes); + + size -= nbytes; +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index 8814ff38aa67b..51346ca91c45c 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -58,6 +58,8 @@ struct serial_private { + int line[0]; + }; + ++#define PCI_DEVICE_ID_HPE_PCI_SERIAL 0x37e ++ + static const struct pci_device_id pci_use_msi[] = { + { PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, + 0xA000, 0x1000) }, +@@ -65,6 +67,8 @@ static const struct pci_device_id pci_use_msi[] = { + 0xA000, 0x1000) }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922, + 0xA000, 0x1000) }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_HP_3PAR, PCI_DEVICE_ID_HPE_PCI_SERIAL, ++ PCI_ANY_ID, PCI_ANY_ID) }, + { } + }; + +@@ -1965,6 +1969,16 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { + .init = pci_hp_diva_init, + .setup = pci_hp_diva_setup, + }, ++ /* ++ * HPE PCI serial device ++ */ ++ { ++ .vendor = PCI_VENDOR_ID_HP_3PAR, ++ .device = PCI_DEVICE_ID_HPE_PCI_SERIAL, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .setup = pci_hp_diva_setup, ++ }, + /* + * Intel + */ +@@ -3903,21 +3917,26 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) + uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; + uart.port.uartclk = board->base_baud * 16; + +- if (pci_match_id(pci_use_msi, dev)) { +- dev_dbg(&dev->dev, "Using MSI(-X) interrupts\n"); +- pci_set_master(dev); +- rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES); ++ if (board->flags & FL_NOIRQ) { ++ uart.port.irq = 0; + } else { +- dev_dbg(&dev->dev, "Using legacy interrupts\n"); +- rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY); +- } +- if (rc < 0) { +- kfree(priv); +- priv = ERR_PTR(rc); +- goto err_deinit; ++ if (pci_match_id(pci_use_msi, dev)) { ++ dev_dbg(&dev->dev, "Using MSI(-X) interrupts\n"); ++ pci_set_master(dev); ++ rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES); ++ } else { ++ dev_dbg(&dev->dev, "Using legacy interrupts\n"); ++ rc = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY); ++ } ++ if (rc < 0) { ++ kfree(priv); ++ priv = ERR_PTR(rc); ++ goto err_deinit; ++ } ++ ++ uart.port.irq = pci_irq_vector(dev, 0); + } + +- uart.port.irq = pci_irq_vector(dev, 0); + uart.port.dev = &dev->dev; + + for (i = 0; i < nr_ports; i++) { +@@ -4932,6 +4951,10 @@ static const struct pci_device_id serial_pci_tbl[] = { + { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_DIVA_AUX, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b2_1_115200 }, ++ /* HPE PCI serial device */ ++ { PCI_VENDOR_ID_HP_3PAR, PCI_DEVICE_ID_HPE_PCI_SERIAL, ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, ++ pbn_b1_1_115200 }, + + { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, +diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c +index 8434bd5a8ec78..5bf8dd6198bbd 100644 +--- a/drivers/tty/serial/max310x.c ++++ b/drivers/tty/serial/max310x.c +@@ -1528,6 +1528,8 @@ static int __init max310x_uart_init(void) + + #ifdef CONFIG_SPI_MASTER + ret = spi_register_driver(&max310x_spi_driver); ++ if (ret) ++ uart_unregister_driver(&max310x_uart); + #endif + + return ret; +diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c +index 5690c09cc0417..944a4c0105795 100644 +--- a/drivers/tty/serial/rp2.c ++++ b/drivers/tty/serial/rp2.c +@@ -195,7 +195,6 @@ struct rp2_card { + void __iomem *bar0; + void __iomem *bar1; + spinlock_t card_lock; +- struct completion fw_loaded; + }; + + #define RP_ID(prod) PCI_VDEVICE(RP, (prod)) +@@ -664,17 +663,10 @@ static void rp2_remove_ports(struct rp2_card *card) + card->initialized_ports = 0; + } + +-static void rp2_fw_cb(const struct firmware *fw, void *context) ++static int rp2_load_firmware(struct rp2_card *card, const struct firmware *fw) + { +- struct rp2_card *card = context; + resource_size_t phys_base; +- int i, rc = -ENOENT; +- +- if (!fw) { +- dev_err(&card->pdev->dev, "cannot find '%s' firmware image\n", +- RP2_FW_NAME); +- goto no_fw; +- } ++ int i, rc = 0; + + phys_base = pci_resource_start(card->pdev, 1); + +@@ -720,23 +712,13 @@ static void rp2_fw_cb(const struct firmware *fw, void *context) + card->initialized_ports++; + } + +- release_firmware(fw); +-no_fw: +- /* +- * rp2_fw_cb() is called from a workqueue long after rp2_probe() +- * has already returned success. So if something failed here, +- * we'll just leave the now-dormant device in place until somebody +- * unbinds it. +- */ +- if (rc) +- dev_warn(&card->pdev->dev, "driver initialization failed\n"); +- +- complete(&card->fw_loaded); ++ return rc; + } + + static int rp2_probe(struct pci_dev *pdev, + const struct pci_device_id *id) + { ++ const struct firmware *fw; + struct rp2_card *card; + struct rp2_uart_port *ports; + void __iomem * const *bars; +@@ -747,7 +729,6 @@ static int rp2_probe(struct pci_dev *pdev, + return -ENOMEM; + pci_set_drvdata(pdev, card); + spin_lock_init(&card->card_lock); +- init_completion(&card->fw_loaded); + + rc = pcim_enable_device(pdev); + if (rc) +@@ -780,21 +761,23 @@ static int rp2_probe(struct pci_dev *pdev, + return -ENOMEM; + card->ports = ports; + +- rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, +- IRQF_SHARED, DRV_NAME, card); +- if (rc) ++ rc = request_firmware(&fw, RP2_FW_NAME, &pdev->dev); ++ if (rc < 0) { ++ dev_err(&pdev->dev, "cannot find '%s' firmware image\n", ++ RP2_FW_NAME); + return rc; ++ } + +- /* +- * Only catastrophic errors (e.g. ENOMEM) are reported here. +- * If the FW image is missing, we'll find out in rp2_fw_cb() +- * and print an error message. +- */ +- rc = request_firmware_nowait(THIS_MODULE, 1, RP2_FW_NAME, &pdev->dev, +- GFP_KERNEL, card, rp2_fw_cb); ++ rc = rp2_load_firmware(card, fw); ++ ++ release_firmware(fw); ++ if (rc < 0) ++ return rc; ++ ++ rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, ++ IRQF_SHARED, DRV_NAME, card); + if (rc) + return rc; +- dev_dbg(&pdev->dev, "waiting for firmware blob...\n"); + + return 0; + } +@@ -803,7 +786,6 @@ static void rp2_remove(struct pci_dev *pdev) + { + struct rp2_card *card = pci_get_drvdata(pdev); + +- wait_for_completion(&card->fw_loaded); + rp2_remove_ports(card); + } + +diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c +index 51c3f579ccd02..2007a40feef9d 100644 +--- a/drivers/tty/serial/serial-tegra.c ++++ b/drivers/tty/serial/serial-tegra.c +@@ -332,7 +332,7 @@ static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits) + + do { + lsr = tegra_uart_read(tup, UART_LSR); +- if ((lsr | UART_LSR_TEMT) && !(lsr & UART_LSR_DR)) ++ if ((lsr & UART_LSR_TEMT) && !(lsr & UART_LSR_DR)) + break; + udelay(1); + } while (--tmout); +diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c +index e2ab6524119a5..fa3bd8a97b244 100644 +--- a/drivers/tty/serial/serial_core.c ++++ b/drivers/tty/serial/serial_core.c +@@ -863,9 +863,11 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, + goto check_and_exit; + } + +- retval = security_locked_down(LOCKDOWN_TIOCSSERIAL); +- if (retval && (change_irq || change_port)) +- goto exit; ++ if (change_irq || change_port) { ++ retval = security_locked_down(LOCKDOWN_TIOCSSERIAL); ++ if (retval) ++ goto exit; ++ } + + /* + * Ask the low level driver to verify the settings. +diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c +index 7d1529b11ae9c..de86e9021a8ff 100644 +--- a/drivers/tty/serial/sh-sci.c ++++ b/drivers/tty/serial/sh-sci.c +@@ -1026,10 +1026,10 @@ static int scif_set_rtrg(struct uart_port *port, int rx_trig) + { + unsigned int bits; + ++ if (rx_trig >= port->fifosize) ++ rx_trig = port->fifosize - 1; + if (rx_trig < 1) + rx_trig = 1; +- if (rx_trig >= port->fifosize) +- rx_trig = port->fifosize; + + /* HSCIF can be set to an arbitrary level. */ + if (sci_getreg(port, HSRTRGR)->size) { +diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c +index 35e89460b9ca8..d037deb958841 100644 +--- a/drivers/usb/core/devio.c ++++ b/drivers/usb/core/devio.c +@@ -1218,7 +1218,12 @@ static int proc_bulk(struct usb_dev_state *ps, void __user *arg) + ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb)); + if (ret) + return ret; +- tbuf = kmalloc(len1, GFP_KERNEL); ++ ++ /* ++ * len1 can be almost arbitrarily large. Don't WARN if it's ++ * too big, just fail the request. ++ */ ++ tbuf = kmalloc(len1, GFP_KERNEL | __GFP_NOWARN); + if (!tbuf) { + ret = -ENOMEM; + goto done; +@@ -1691,7 +1696,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb + if (num_sgs) { + as->urb->sg = kmalloc_array(num_sgs, + sizeof(struct scatterlist), +- GFP_KERNEL); ++ GFP_KERNEL | __GFP_NOWARN); + if (!as->urb->sg) { + ret = -ENOMEM; + goto error; +@@ -1726,7 +1731,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb + (uurb_start - as->usbm->vm_start); + } else { + as->urb->transfer_buffer = kmalloc(uurb->buffer_length, +- GFP_KERNEL); ++ GFP_KERNEL | __GFP_NOWARN); + if (!as->urb->transfer_buffer) { + ret = -ENOMEM; + goto error; +diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h +index a97dd1ba964ee..a8f23f8bc6efd 100644 +--- a/drivers/usb/core/hub.h ++++ b/drivers/usb/core/hub.h +@@ -148,8 +148,10 @@ static inline unsigned hub_power_on_good_delay(struct usb_hub *hub) + { + unsigned delay = hub->descriptor->bPwrOn2PwrGood * 2; + +- /* Wait at least 100 msec for power to become stable */ +- return max(delay, 100U); ++ if (!hub->hdev->parent) /* root hub */ ++ return delay; ++ else /* Wait at least 100 msec for power to become stable */ ++ return max(delay, 100U); + } + + static inline int hub_port_debounce_be_connected(struct usb_hub *hub, +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 6145311a3855f..ecd83526f26fe 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1162,6 +1162,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, + req->start_sg = sg_next(s); + + req->num_queued_sgs++; ++ req->num_pending_sgs--; + + /* + * The number of pending SG entries may not correspond to the +@@ -1169,7 +1170,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, + * don't include unused SG entries. + */ + if (length == 0) { +- req->num_pending_sgs -= req->request.num_mapped_sgs - req->num_queued_sgs; ++ req->num_pending_sgs = 0; + break; + } + +@@ -2602,15 +2603,15 @@ static int dwc3_gadget_ep_reclaim_trb_sg(struct dwc3_ep *dep, + struct dwc3_trb *trb = &dep->trb_pool[dep->trb_dequeue]; + struct scatterlist *sg = req->sg; + struct scatterlist *s; +- unsigned int pending = req->num_pending_sgs; ++ unsigned int num_queued = req->num_queued_sgs; + unsigned int i; + int ret = 0; + +- for_each_sg(sg, s, pending, i) { ++ for_each_sg(sg, s, num_queued, i) { + trb = &dep->trb_pool[dep->trb_dequeue]; + + req->sg = sg_next(s); +- req->num_pending_sgs--; ++ req->num_queued_sgs--; + + ret = dwc3_gadget_ep_reclaim_completed_trb(dep, req, + trb, event, status, true); +@@ -2633,7 +2634,7 @@ static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep, + + static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req) + { +- return req->num_pending_sgs == 0; ++ return req->num_pending_sgs == 0 && req->num_queued_sgs == 0; + } + + static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, +@@ -2642,7 +2643,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, + { + int ret; + +- if (req->num_pending_sgs) ++ if (req->request.num_mapped_sgs) + ret = dwc3_gadget_ep_reclaim_trb_sg(dep, req, event, + status); + else +diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c +index 33703140233aa..08a93cf68efff 100644 +--- a/drivers/usb/gadget/udc/renesas_usb3.c ++++ b/drivers/usb/gadget/udc/renesas_usb3.c +@@ -1473,7 +1473,7 @@ static void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep, + struct renesas_usb3_request *usb3_req) + { + struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); +- struct renesas_usb3_request *usb3_req_first = usb3_get_request(usb3_ep); ++ struct renesas_usb3_request *usb3_req_first; + unsigned long flags; + int ret = -EAGAIN; + u32 enable_bits = 0; +@@ -1481,7 +1481,8 @@ static void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep, + spin_lock_irqsave(&usb3->lock, flags); + if (usb3_ep->halt || usb3_ep->started) + goto out; +- if (usb3_req != usb3_req_first) ++ usb3_req_first = __usb3_get_request(usb3_ep); ++ if (!usb3_req_first || usb3_req != usb3_req_first) + goto out; + + if (usb3_pn_change(usb3, usb3_ep->num) < 0) +diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c +index a3dfc77578ea1..26baba3ab7d73 100644 +--- a/drivers/usb/misc/trancevibrator.c ++++ b/drivers/usb/misc/trancevibrator.c +@@ -61,9 +61,9 @@ static ssize_t speed_store(struct device *dev, struct device_attribute *attr, + /* Set speed */ + retval = usb_control_msg(tv->udev, usb_sndctrlpipe(tv->udev, 0), + 0x01, /* vendor request: set speed */ +- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, ++ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, + tv->speed, /* speed value */ +- 0, NULL, 0, USB_CTRL_GET_TIMEOUT); ++ 0, NULL, 0, USB_CTRL_SET_TIMEOUT); + if (retval) { + tv->speed = old; + dev_dbg(&tv->udev->dev, "retval = %d\n", retval); +diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c +index b5d6616442635..748139d262633 100644 +--- a/drivers/usb/misc/uss720.c ++++ b/drivers/usb/misc/uss720.c +@@ -736,6 +736,7 @@ static int uss720_probe(struct usb_interface *intf, + parport_announce_port(pp); + + usb_set_intfdata(intf, pp); ++ usb_put_dev(usbdev); + return 0; + + probe_abort: +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index c00e4177651a8..7c0181ae44e9c 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1034,6 +1034,9 @@ static const struct usb_device_id id_table_combined[] = { + /* Sienna devices */ + { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) }, + { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) }, ++ /* IDS GmbH devices */ ++ { USB_DEVICE(IDS_VID, IDS_SI31A_PID) }, ++ { USB_DEVICE(IDS_VID, IDS_CM31A_PID) }, + /* U-Blox devices */ + { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) }, + { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 3d47c6d72256e..d854e04a4286e 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -1567,6 +1567,13 @@ + #define UNJO_VID 0x22B7 + #define UNJO_ISODEBUG_V1_PID 0x150D + ++/* ++ * IDS GmbH ++ */ ++#define IDS_VID 0x2CAF ++#define IDS_SI31A_PID 0x13A2 ++#define IDS_CM31A_PID 0x13A3 ++ + /* + * U-Blox products (http://www.u-blox.com). + */ +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 5c167bc089a08..25d8fb3a7395f 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1240,6 +1240,10 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */ + .driver_info = NCTRL(0) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7010, 0xff), /* Telit LE910-S1 (RNDIS) */ ++ .driver_info = NCTRL(2) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7011, 0xff), /* Telit LE910-S1 (ECM) */ ++ .driver_info = NCTRL(2) }, + { USB_DEVICE(TELIT_VENDOR_ID, 0x9010), /* Telit SBL FN980 flashing device */ + .driver_info = NCTRL(0) | ZLP }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ +diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c +index e290b250f45cc..9600cee957697 100644 +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -107,6 +107,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, + { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, + { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, ++ { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530GC_PRODUCT_ID) }, + { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) }, + { USB_DEVICE(AT_VENDOR_ID, AT_VTKIT3_PRODUCT_ID) }, + { } /* Terminating entry */ +diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h +index a897680473a78..3e5442573fe4e 100644 +--- a/drivers/usb/serial/pl2303.h ++++ b/drivers/usb/serial/pl2303.h +@@ -152,6 +152,7 @@ + /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ + #define ADLINK_VENDOR_ID 0x0b63 + #define ADLINK_ND6530_PRODUCT_ID 0x6530 ++#define ADLINK_ND6530GC_PRODUCT_ID 0x653a + + /* SMART USB Serial Adapter */ + #define SMART_VENDOR_ID 0x0b8c +diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c +index b1449d4914cca..acc115d20f812 100644 +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -37,6 +37,7 @@ + /* Vendor and product ids */ + #define TI_VENDOR_ID 0x0451 + #define IBM_VENDOR_ID 0x04b3 ++#define STARTECH_VENDOR_ID 0x14b0 + #define TI_3410_PRODUCT_ID 0x3410 + #define IBM_4543_PRODUCT_ID 0x4543 + #define IBM_454B_PRODUCT_ID 0x454b +@@ -372,6 +373,7 @@ static const struct usb_device_id ti_id_table_3410[] = { + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1131_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1150_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1151_PRODUCT_ID) }, ++ { USB_DEVICE(STARTECH_VENDOR_ID, TI_3410_PRODUCT_ID) }, + { } /* terminator */ + }; + +@@ -410,6 +412,7 @@ static const struct usb_device_id ti_id_table_combined[] = { + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1131_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1150_PRODUCT_ID) }, + { USB_DEVICE(MXU1_VENDOR_ID, MXU1_1151_PRODUCT_ID) }, ++ { USB_DEVICE(STARTECH_VENDOR_ID, TI_3410_PRODUCT_ID) }, + { } /* terminator */ + }; + +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index 95205bde240f7..eca3abc1a7cd9 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -4648,7 +4648,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + __u64 start, __u64 len) + { + int ret = 0; +- u64 off = start; ++ u64 off; + u64 max = start + len; + u32 flags = 0; + u32 found_type; +@@ -4684,6 +4684,11 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + goto out_free_ulist; + } + ++ /* ++ * We can't initialize that to 'start' as this could miss extents due ++ * to extent item merging ++ */ ++ off = 0; + start = round_down(start, btrfs_inode_sectorsize(inode)); + len = round_up(max, btrfs_inode_sectorsize(inode)) - start; + +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index de53e51669976..54647eb9c6ed2 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -1846,8 +1846,6 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans, + ret = btrfs_update_inode(trans, root, inode); + } else if (ret == -EEXIST) { + ret = 0; +- } else { +- BUG(); /* Logic Error */ + } + iput(inode); + +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 81d9c4ea0e8f3..e068f82ffeddf 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -979,6 +979,13 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) + /* Internal types */ + server->capabilities |= SMB2_NT_FIND | SMB2_LARGE_FILES; + ++ /* ++ * SMB3.0 supports only 1 cipher and doesn't have a encryption neg context ++ * Set the cipher type manually. ++ */ ++ if (server->dialect == SMB30_PROT_ID && (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) ++ server->cipher_type = SMB2_ENCRYPTION_AES128_CCM; ++ + security_blob = smb2_get_data_area_len(&blob_offset, &blob_length, + (struct smb2_sync_hdr *)rsp); + /* +@@ -3604,10 +3611,10 @@ smb2_new_read_req(void **buf, unsigned int *total_len, + * Related requests use info from previous read request + * in chain. + */ +- shdr->SessionId = 0xFFFFFFFF; ++ shdr->SessionId = 0xFFFFFFFFFFFFFFFF; + shdr->TreeId = 0xFFFFFFFF; +- req->PersistentFileId = 0xFFFFFFFF; +- req->VolatileFileId = 0xFFFFFFFF; ++ req->PersistentFileId = 0xFFFFFFFFFFFFFFFF; ++ req->VolatileFileId = 0xFFFFFFFFFFFFFFFF; + } + } + if (remaining_bytes > io_parms->length) +diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c +index c9b605f6c9cb2..98b74cdabb99a 100644 +--- a/fs/nfs/filelayout/filelayout.c ++++ b/fs/nfs/filelayout/filelayout.c +@@ -717,7 +717,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, + if (unlikely(!p)) + goto out_err; + fl->fh_array[i]->size = be32_to_cpup(p++); +- if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) { ++ if (fl->fh_array[i]->size > NFS_MAXFHSIZE) { + printk(KERN_ERR "NFS: Too big fh %d received %d\n", + i, fl->fh_array[i]->size); + goto out_err; +diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c +index 6b31cb5f9c9db..7c73097b2f4e5 100644 +--- a/fs/nfs/nfs4file.c ++++ b/fs/nfs/nfs4file.c +@@ -168,7 +168,7 @@ static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence) + case SEEK_HOLE: + case SEEK_DATA: + ret = nfs42_proc_llseek(filep, offset, whence); +- if (ret != -ENOTSUPP) ++ if (ret != -EOPNOTSUPP) + return ret; + /* Fall through */ + default: +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 304ab4cdaa8c1..ff54ba3c82477 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1647,7 +1647,7 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, + rcu_read_unlock(); + trace_nfs4_open_stateid_update_wait(state->inode, stateid, 0); + +- if (!signal_pending(current)) { ++ if (!fatal_signal_pending(current)) { + if (schedule_timeout(5*HZ) == 0) + status = -EAGAIN; + else +@@ -3416,7 +3416,7 @@ static bool nfs4_refresh_open_old_stateid(nfs4_stateid *dst, + write_sequnlock(&state->seqlock); + trace_nfs4_close_stateid_update_wait(state->inode, dst, 0); + +- if (signal_pending(current)) ++ if (fatal_signal_pending(current)) + status = -EINTR; + else + if (schedule_timeout(5*HZ) != 0) +diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c +index f4407dd426bf0..e3b85bfcfc7dc 100644 +--- a/fs/nfs/pagelist.c ++++ b/fs/nfs/pagelist.c +@@ -986,15 +986,16 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, + + struct nfs_page *prev = NULL; + +- if (mirror->pg_count != 0) { +- prev = nfs_list_entry(mirror->pg_list.prev); +- } else { ++ if (list_empty(&mirror->pg_list)) { + if (desc->pg_ops->pg_init) + desc->pg_ops->pg_init(desc, req); + if (desc->pg_error < 0) + return 0; + mirror->pg_base = req->wb_pgbase; +- } ++ mirror->pg_count = 0; ++ mirror->pg_recoalesce = 0; ++ } else ++ prev = nfs_list_entry(mirror->pg_list.prev); + + if (desc->pg_maxretrans && req->wb_nio > desc->pg_maxretrans) { + if (NFS_SERVER(desc->pg_inode)->flags & NFS_MOUNT_SOFTERR) +@@ -1018,17 +1019,16 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) + { + struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc); + +- + if (!list_empty(&mirror->pg_list)) { + int error = desc->pg_ops->pg_doio(desc); + if (error < 0) + desc->pg_error = error; +- else ++ if (list_empty(&mirror->pg_list)) { + mirror->pg_bytes_written += mirror->pg_count; +- } +- if (list_empty(&mirror->pg_list)) { +- mirror->pg_count = 0; +- mirror->pg_base = 0; ++ mirror->pg_count = 0; ++ mirror->pg_base = 0; ++ mirror->pg_recoalesce = 0; ++ } + } + } + +@@ -1122,7 +1122,6 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) + + do { + list_splice_init(&mirror->pg_list, &head); +- mirror->pg_bytes_written -= mirror->pg_count; + mirror->pg_count = 0; + mirror->pg_base = 0; + mirror->pg_recoalesce = 0; +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index 7e8c18218e68f..1b512df1003f9 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -1285,6 +1285,11 @@ _pnfs_return_layout(struct inode *ino) + { + struct pnfs_layout_hdr *lo = NULL; + struct nfs_inode *nfsi = NFS_I(ino); ++ struct pnfs_layout_range range = { ++ .iomode = IOMODE_ANY, ++ .offset = 0, ++ .length = NFS4_MAX_UINT64, ++ }; + LIST_HEAD(tmp_list); + nfs4_stateid stateid; + int status = 0; +@@ -1311,16 +1316,10 @@ _pnfs_return_layout(struct inode *ino) + } + valid_layout = pnfs_layout_is_valid(lo); + pnfs_clear_layoutcommit(ino, &tmp_list); +- pnfs_mark_matching_lsegs_return(lo, &tmp_list, NULL, 0); ++ pnfs_mark_matching_lsegs_return(lo, &tmp_list, &range, 0); + +- if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) { +- struct pnfs_layout_range range = { +- .iomode = IOMODE_ANY, +- .offset = 0, +- .length = NFS4_MAX_UINT64, +- }; ++ if (NFS_SERVER(ino)->pnfs_curr_ld->return_range) + NFS_SERVER(ino)->pnfs_curr_ld->return_range(lo, &range); +- } + + /* Don't send a LAYOUTRETURN if list was initially empty */ + if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags) || +diff --git a/fs/proc/base.c b/fs/proc/base.c +index 653c2d8aa1cd7..35114624fb036 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -2556,6 +2556,10 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, + void *page; + int rv; + ++ /* A task may only write when it was the opener. */ ++ if (file->f_cred != current_real_cred()) ++ return -EPERM; ++ + rcu_read_lock(); + task = pid_task(proc_pid(inode), PIDTYPE_PID); + if (!task) { +diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h +index 68782ba8b6e8d..69b9ccbe1ad0f 100644 +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -5194,7 +5194,7 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); + */ + int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + const u8 *addr, enum nl80211_iftype iftype, +- u8 data_offset); ++ u8 data_offset, bool is_amsdu); + + /** + * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 +@@ -5206,7 +5206,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, + enum nl80211_iftype iftype) + { +- return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0); ++ return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0, false); + } + + /** +diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h +index cee1c084e9f40..b16f9236de147 100644 +--- a/include/net/pkt_sched.h ++++ b/include/net/pkt_sched.h +@@ -118,12 +118,7 @@ void __qdisc_run(struct Qdisc *q); + static inline void qdisc_run(struct Qdisc *q) + { + if (qdisc_run_begin(q)) { +- /* NOLOCK qdisc must check 'state' under the qdisc seqlock +- * to avoid racing with dev_qdisc_reset() +- */ +- if (!(q->flags & TCQ_F_NOLOCK) || +- likely(!test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) +- __qdisc_run(q); ++ __qdisc_run(q); + qdisc_run_end(q); + } + } +diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h +index b2ceec7b280d4..0852f3e51360a 100644 +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -36,6 +36,7 @@ struct qdisc_rate_table { + enum qdisc_state_t { + __QDISC_STATE_SCHED, + __QDISC_STATE_DEACTIVATED, ++ __QDISC_STATE_MISSED, + }; + + struct qdisc_size_table { +@@ -156,8 +157,33 @@ static inline bool qdisc_is_empty(const struct Qdisc *qdisc) + static inline bool qdisc_run_begin(struct Qdisc *qdisc) + { + if (qdisc->flags & TCQ_F_NOLOCK) { ++ if (spin_trylock(&qdisc->seqlock)) ++ goto nolock_empty; ++ ++ /* If the MISSED flag is set, it means other thread has ++ * set the MISSED flag before second spin_trylock(), so ++ * we can return false here to avoid multi cpus doing ++ * the set_bit() and second spin_trylock() concurrently. ++ */ ++ if (test_bit(__QDISC_STATE_MISSED, &qdisc->state)) ++ return false; ++ ++ /* Set the MISSED flag before the second spin_trylock(), ++ * if the second spin_trylock() return false, it means ++ * other cpu holding the lock will do dequeuing for us ++ * or it will see the MISSED flag set after releasing ++ * lock and reschedule the net_tx_action() to do the ++ * dequeuing. ++ */ ++ set_bit(__QDISC_STATE_MISSED, &qdisc->state); ++ ++ /* Retry again in case other CPU may not see the new flag ++ * after it releases the lock at the end of qdisc_run_end(). ++ */ + if (!spin_trylock(&qdisc->seqlock)) + return false; ++ ++nolock_empty: + WRITE_ONCE(qdisc->empty, false); + } else if (qdisc_is_running(qdisc)) { + return false; +@@ -173,8 +199,15 @@ static inline bool qdisc_run_begin(struct Qdisc *qdisc) + static inline void qdisc_run_end(struct Qdisc *qdisc) + { + write_seqcount_end(&qdisc->running); +- if (qdisc->flags & TCQ_F_NOLOCK) ++ if (qdisc->flags & TCQ_F_NOLOCK) { + spin_unlock(&qdisc->seqlock); ++ ++ if (unlikely(test_bit(__QDISC_STATE_MISSED, ++ &qdisc->state))) { ++ clear_bit(__QDISC_STATE_MISSED, &qdisc->state); ++ __netif_schedule(qdisc); ++ } ++ } + } + + static inline bool qdisc_may_bulk(const struct Qdisc *qdisc) +diff --git a/include/net/sock.h b/include/net/sock.h +index 4137fa1787903..a0728f24ecc53 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2150,13 +2150,15 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) + sk_mem_charge(sk, skb->truesize); + } + +-static inline void skb_set_owner_sk_safe(struct sk_buff *skb, struct sock *sk) ++static inline __must_check bool skb_set_owner_sk_safe(struct sk_buff *skb, struct sock *sk) + { + if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) { + skb_orphan(skb); + skb->destructor = sock_efree; + skb->sk = sk; ++ return true; + } ++ return false; + } + + void sk_reset_timer(struct sock *sk, struct timer_list *timer, +diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c +index 07cfa3249f83a..0a2d78e811cf5 100644 +--- a/net/bluetooth/cmtp/core.c ++++ b/net/bluetooth/cmtp/core.c +@@ -392,6 +392,11 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) + if (!(session->flags & BIT(CMTP_LOOPBACK))) { + err = cmtp_attach_device(session); + if (err < 0) { ++ /* Caller will call fput in case of failure, and so ++ * will cmtp_session kthread. ++ */ ++ get_file(session->sock->file); ++ + atomic_inc(&session->terminate); + wake_up_interruptible(sk_sleep(session->sock->sk)); + up_write(&cmtp_session_sem); +diff --git a/net/core/dev.c b/net/core/dev.c +index a30878346f54b..e226f266da9e0 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -3384,7 +3384,8 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, + + if (q->flags & TCQ_F_NOLOCK) { + rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK; +- qdisc_run(q); ++ if (likely(!netif_xmit_frozen_or_stopped(txq))) ++ qdisc_run(q); + + if (unlikely(to_free)) + kfree_skb_list(to_free); +@@ -4515,25 +4516,43 @@ static __latent_entropy void net_tx_action(struct softirq_action *h) + sd->output_queue_tailp = &sd->output_queue; + local_irq_enable(); + ++ rcu_read_lock(); ++ + while (head) { + struct Qdisc *q = head; + spinlock_t *root_lock = NULL; + + head = head->next_sched; + +- if (!(q->flags & TCQ_F_NOLOCK)) { +- root_lock = qdisc_lock(q); +- spin_lock(root_lock); +- } + /* We need to make sure head->next_sched is read + * before clearing __QDISC_STATE_SCHED + */ + smp_mb__before_atomic(); ++ ++ if (!(q->flags & TCQ_F_NOLOCK)) { ++ root_lock = qdisc_lock(q); ++ spin_lock(root_lock); ++ } else if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, ++ &q->state))) { ++ /* There is a synchronize_net() between ++ * STATE_DEACTIVATED flag being set and ++ * qdisc_reset()/some_qdisc_is_busy() in ++ * dev_deactivate(), so we can safely bail out ++ * early here to avoid data race between ++ * qdisc_deactivate() and some_qdisc_is_busy() ++ * for lockless qdisc. ++ */ ++ clear_bit(__QDISC_STATE_SCHED, &q->state); ++ continue; ++ } ++ + clear_bit(__QDISC_STATE_SCHED, &q->state); + qdisc_run(q); + if (root_lock) + spin_unlock(root_lock); + } ++ ++ rcu_read_unlock(); + } + + xfrm_dev_backlog(sd); +diff --git a/net/core/filter.c b/net/core/filter.c +index 7fbb274b7fe32..108bcf6000529 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -3331,6 +3331,7 @@ static inline int __bpf_skb_change_head(struct sk_buff *skb, u32 head_room, + __skb_push(skb, head_room); + memset(skb->data, 0, head_room); + skb_reset_mac_header(skb); ++ skb_reset_mac_len(skb); + } + + return ret; +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 6635b83113f8f..472a615775f32 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -132,6 +132,9 @@ static void neigh_update_gc_list(struct neighbour *n) + write_lock_bh(&n->tbl->lock); + write_lock(&n->lock); + ++ if (n->dead) ++ goto out; ++ + /* remove from the gc list if new state is permanent or if neighbor + * is externally learned; otherwise entry should be on the gc list + */ +@@ -148,6 +151,7 @@ static void neigh_update_gc_list(struct neighbour *n) + atomic_inc(&n->tbl->gc_entries); + } + ++out: + write_unlock(&n->lock); + write_unlock_bh(&n->tbl->lock); + } +diff --git a/net/core/sock.c b/net/core/sock.c +index 19c178aac0ae8..68f84fac63e0b 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -2026,10 +2026,10 @@ void skb_orphan_partial(struct sk_buff *skb) + if (skb_is_tcp_pure_ack(skb)) + return; + +- if (can_skb_orphan_partial(skb)) +- skb_set_owner_sk_safe(skb, skb->sk); +- else +- skb_orphan(skb); ++ if (can_skb_orphan_partial(skb) && skb_set_owner_sk_safe(skb, skb->sk)) ++ return; ++ ++ skb_orphan(skb); + } + EXPORT_SYMBOL(skb_orphan_partial); + +diff --git a/net/dsa/master.c b/net/dsa/master.c +index be0b4ed3b7d89..40eddec48f26e 100644 +--- a/net/dsa/master.c ++++ b/net/dsa/master.c +@@ -147,8 +147,7 @@ static void dsa_master_get_strings(struct net_device *dev, uint32_t stringset, + struct dsa_switch *ds = cpu_dp->ds; + int port = cpu_dp->index; + int len = ETH_GSTRING_LEN; +- int mcount = 0, count; +- unsigned int i; ++ int mcount = 0, count, i; + uint8_t pfx[4]; + uint8_t *ndata; + +@@ -178,6 +177,8 @@ static void dsa_master_get_strings(struct net_device *dev, uint32_t stringset, + */ + ds->ops->get_strings(ds, port, stringset, ndata); + count = ds->ops->get_sset_count(ds, port, stringset); ++ if (count < 0) ++ return; + for (i = 0; i < count; i++) { + memmove(ndata + (i * len + sizeof(pfx)), + ndata + i * len, len - sizeof(pfx)); +diff --git a/net/dsa/slave.c b/net/dsa/slave.c +index 06f8874d53eea..75b4cd4bcafb9 100644 +--- a/net/dsa/slave.c ++++ b/net/dsa/slave.c +@@ -692,13 +692,15 @@ static int dsa_slave_get_sset_count(struct net_device *dev, int sset) + struct dsa_switch *ds = dp->ds; + + if (sset == ETH_SS_STATS) { +- int count; ++ int count = 0; + +- count = 4; +- if (ds->ops->get_sset_count) +- count += ds->ops->get_sset_count(ds, dp->index, sset); ++ if (ds->ops->get_sset_count) { ++ count = ds->ops->get_sset_count(ds, dp->index, sset); ++ if (count < 0) ++ return count; ++ } + +- return count; ++ return count + 4; + } + + return -EOPNOTSUPP; +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index c875c9b6edbe9..7d0a6a7c9d283 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1604,10 +1604,7 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + IPV6_TLV_PADN, 0 }; + + /* we assume size > sizeof(ra) here */ +- /* limit our allocations to order-0 page */ +- size = min_t(int, size, SKB_MAX_ORDER(0, 0)); + skb = sock_alloc_send_skb(sk, size, 1, &err); +- + if (!skb) + return NULL; + +diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c +index c8cf1bbad74a2..45ee1971d9986 100644 +--- a/net/ipv6/reassembly.c ++++ b/net/ipv6/reassembly.c +@@ -344,7 +344,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) + hdr = ipv6_hdr(skb); + fhdr = (struct frag_hdr *)skb_transport_header(skb); + +- if (!(fhdr->frag_off & htons(0xFFF9))) { ++ if (!(fhdr->frag_off & htons(IP6_OFFSET | IP6_MF))) { + /* It is not a fragmented frame */ + skb->transport_header += sizeof(struct frag_hdr); + __IP6_INC_STATS(net, +@@ -352,6 +352,8 @@ static int ipv6_frag_rcv(struct sk_buff *skb) + + IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb); + IP6CB(skb)->flags |= IP6SKB_FRAGMENTED; ++ IP6CB(skb)->frag_max_size = ntohs(hdr->payload_len) + ++ sizeof(struct ipv6hdr); + return 1; + } + +diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h +index 268f1d8f440ba..a7933279a80b7 100644 +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -50,12 +50,6 @@ struct ieee80211_local; + #define IEEE80211_ENCRYPT_HEADROOM 8 + #define IEEE80211_ENCRYPT_TAILROOM 18 + +-/* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent +- * reception of at least three fragmented frames. This limit can be increased +- * by changing this define, at the cost of slower frame reassembly and +- * increased memory use (about 2 kB of RAM per entry). */ +-#define IEEE80211_FRAGMENT_MAX 4 +- + /* power level hasn't been configured (or set to automatic) */ + #define IEEE80211_UNSET_POWER_LEVEL INT_MIN + +@@ -88,18 +82,6 @@ extern const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS]; + + #define IEEE80211_MAX_NAN_INSTANCE_ID 255 + +-struct ieee80211_fragment_entry { +- struct sk_buff_head skb_list; +- unsigned long first_frag_time; +- u16 seq; +- u16 extra_len; +- u16 last_frag; +- u8 rx_queue; +- bool check_sequential_pn; /* needed for CCMP/GCMP */ +- u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ +-}; +- +- + struct ieee80211_bss { + u32 device_ts_beacon, device_ts_presp; + +@@ -240,8 +222,15 @@ struct ieee80211_rx_data { + */ + int security_idx; + +- u32 tkip_iv32; +- u16 tkip_iv16; ++ union { ++ struct { ++ u32 iv32; ++ u16 iv16; ++ } tkip; ++ struct { ++ u8 pn[IEEE80211_CCMP_PN_LEN]; ++ } ccm_gcm; ++ }; + }; + + struct ieee80211_csa_settings { +@@ -894,9 +883,7 @@ struct ieee80211_sub_if_data { + + char name[IFNAMSIZ]; + +- /* Fragment table for host-based reassembly */ +- struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; +- unsigned int fragment_next; ++ struct ieee80211_fragment_cache frags; + + /* TID bitmap for NoAck policy */ + u16 noack_map; +@@ -2256,4 +2243,7 @@ extern const struct ethtool_ops ieee80211_ethtool_ops; + #define debug_noinline + #endif + ++void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache); ++void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache); ++ + #endif /* IEEE80211_I_H */ +diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c +index 6089b09ec13b6..6f576306a4d74 100644 +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -8,7 +8,7 @@ + * Copyright 2008, Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright (c) 2016 Intel Deutschland GmbH +- * Copyright (C) 2018 Intel Corporation ++ * Copyright (C) 2018-2021 Intel Corporation + */ + #include + #include +@@ -1108,16 +1108,12 @@ static void ieee80211_set_multicast_list(struct net_device *dev) + */ + static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) + { +- int i; +- + /* free extra data */ + ieee80211_free_keys(sdata, false); + + ieee80211_debugfs_remove_netdev(sdata); + +- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) +- __skb_queue_purge(&sdata->fragments[i].skb_list); +- sdata->fragment_next = 0; ++ ieee80211_destroy_frag_cache(&sdata->frags); + + if (ieee80211_vif_is_mesh(&sdata->vif)) + ieee80211_mesh_teardown_sdata(sdata); +@@ -1827,8 +1823,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, + sdata->wdev.wiphy = local->hw.wiphy; + sdata->local = local; + +- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) +- skb_queue_head_init(&sdata->fragments[i].skb_list); ++ ieee80211_init_frag_cache(&sdata->frags); + + INIT_LIST_HEAD(&sdata->key_list); + +diff --git a/net/mac80211/key.c b/net/mac80211/key.c +index efc1acc6543c9..fff7efc5b9713 100644 +--- a/net/mac80211/key.c ++++ b/net/mac80211/key.c +@@ -764,6 +764,7 @@ int ieee80211_key_link(struct ieee80211_key *key, + struct ieee80211_sub_if_data *sdata, + struct sta_info *sta) + { ++ static atomic_t key_color = ATOMIC_INIT(0); + struct ieee80211_key *old_key; + int idx = key->conf.keyidx; + bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; +@@ -815,6 +816,12 @@ int ieee80211_key_link(struct ieee80211_key *key, + key->sdata = sdata; + key->sta = sta; + ++ /* ++ * Assign a unique ID to every key so we can easily prevent mixed ++ * key and fragment cache attacks. ++ */ ++ key->color = atomic_inc_return(&key_color); ++ + increment_tailroom_need_count(sdata); + + ret = ieee80211_key_replace(sdata, sta, pairwise, old_key, key); +diff --git a/net/mac80211/key.h b/net/mac80211/key.h +index d6d6e89cf7dd2..c463938bec99e 100644 +--- a/net/mac80211/key.h ++++ b/net/mac80211/key.h +@@ -127,6 +127,8 @@ struct ieee80211_key { + } debugfs; + #endif + ++ unsigned int color; ++ + /* + * key config, must be last because it contains key + * material as variable length member +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 1a15e7bae106a..3d7a5c5e586a6 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -6,7 +6,7 @@ + * Copyright 2007-2010 Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright(c) 2015 - 2017 Intel Deutschland GmbH +- * Copyright (C) 2018-2019 Intel Corporation ++ * Copyright (C) 2018-2021 Intel Corporation + */ + + #include +@@ -2083,19 +2083,34 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + return result; + } + ++void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cache->entries); i++) ++ skb_queue_head_init(&cache->entries[i].skb_list); ++} ++ ++void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(cache->entries); i++) ++ __skb_queue_purge(&cache->entries[i].skb_list); ++} ++ + static inline struct ieee80211_fragment_entry * +-ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, ++ieee80211_reassemble_add(struct ieee80211_fragment_cache *cache, + unsigned int frag, unsigned int seq, int rx_queue, + struct sk_buff **skb) + { + struct ieee80211_fragment_entry *entry; + +- entry = &sdata->fragments[sdata->fragment_next++]; +- if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) +- sdata->fragment_next = 0; ++ entry = &cache->entries[cache->next++]; ++ if (cache->next >= IEEE80211_FRAGMENT_MAX) ++ cache->next = 0; + +- if (!skb_queue_empty(&entry->skb_list)) +- __skb_queue_purge(&entry->skb_list); ++ __skb_queue_purge(&entry->skb_list); + + __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ + *skb = NULL; +@@ -2110,14 +2125,14 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, + } + + static inline struct ieee80211_fragment_entry * +-ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, ++ieee80211_reassemble_find(struct ieee80211_fragment_cache *cache, + unsigned int frag, unsigned int seq, + int rx_queue, struct ieee80211_hdr *hdr) + { + struct ieee80211_fragment_entry *entry; + int i, idx; + +- idx = sdata->fragment_next; ++ idx = cache->next; + for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { + struct ieee80211_hdr *f_hdr; + struct sk_buff *f_skb; +@@ -2126,7 +2141,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, + if (idx < 0) + idx = IEEE80211_FRAGMENT_MAX - 1; + +- entry = &sdata->fragments[idx]; ++ entry = &cache->entries[idx]; + if (skb_queue_empty(&entry->skb_list) || entry->seq != seq || + entry->rx_queue != rx_queue || + entry->last_frag + 1 != frag) +@@ -2154,15 +2169,27 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, + return NULL; + } + ++static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc) ++{ ++ return rx->key && ++ (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && ++ ieee80211_has_protected(fc); ++} ++ + static ieee80211_rx_result debug_noinline + ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + { ++ struct ieee80211_fragment_cache *cache = &rx->sdata->frags; + struct ieee80211_hdr *hdr; + u16 sc; + __le16 fc; + unsigned int frag, seq; + struct ieee80211_fragment_entry *entry; + struct sk_buff *skb; ++ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + + hdr = (struct ieee80211_hdr *)rx->skb->data; + fc = hdr->frame_control; +@@ -2178,6 +2205,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + goto out_no_led; + } + ++ if (rx->sta) ++ cache = &rx->sta->frags; ++ + if (likely(!ieee80211_has_morefrags(fc) && frag == 0)) + goto out; + +@@ -2196,20 +2226,17 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + + if (frag == 0) { + /* This is the first fragment of a new frame. */ +- entry = ieee80211_reassemble_add(rx->sdata, frag, seq, ++ entry = ieee80211_reassemble_add(cache, frag, seq, + rx->seqno_idx, &(rx->skb)); +- if (rx->key && +- (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && +- ieee80211_has_protected(fc)) { ++ if (requires_sequential_pn(rx, fc)) { + int queue = rx->security_idx; + + /* Store CCMP/GCMP PN so that we can verify that the + * next fragment has a sequential PN value. + */ + entry->check_sequential_pn = true; ++ entry->is_protected = true; ++ entry->key_color = rx->key->color; + memcpy(entry->last_pn, + rx->key->u.ccmp.rx_pn[queue], + IEEE80211_CCMP_PN_LEN); +@@ -2221,6 +2248,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + sizeof(rx->key->u.gcmp.rx_pn[queue])); + BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN != + IEEE80211_GCMP_PN_LEN); ++ } else if (rx->key && ++ (ieee80211_has_protected(fc) || ++ (status->flag & RX_FLAG_DECRYPTED))) { ++ entry->is_protected = true; ++ entry->key_color = rx->key->color; + } + return RX_QUEUED; + } +@@ -2228,7 +2260,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + /* This is a fragment for a frame that should already be pending in + * fragment cache. Add this fragment to the end of the pending entry. + */ +- entry = ieee80211_reassemble_find(rx->sdata, frag, seq, ++ entry = ieee80211_reassemble_find(cache, frag, seq, + rx->seqno_idx, hdr); + if (!entry) { + I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); +@@ -2243,25 +2275,39 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + if (entry->check_sequential_pn) { + int i; + u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; +- int queue; + +- if (!rx->key || +- (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256)) ++ if (!requires_sequential_pn(rx, fc)) ++ return RX_DROP_UNUSABLE; ++ ++ /* Prevent mixed key and fragment cache attacks */ ++ if (entry->key_color != rx->key->color) + return RX_DROP_UNUSABLE; ++ + memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); + for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { + pn[i]++; + if (pn[i]) + break; + } +- queue = rx->security_idx; +- rpn = rx->key->u.ccmp.rx_pn[queue]; ++ ++ rpn = rx->ccm_gcm.pn; + if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN)) + return RX_DROP_UNUSABLE; + memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN); ++ } else if (entry->is_protected && ++ (!rx->key || ++ (!ieee80211_has_protected(fc) && ++ !(status->flag & RX_FLAG_DECRYPTED)) || ++ rx->key->color != entry->key_color)) { ++ /* Drop this as a mixed key or fragment cache attack, even ++ * if for TKIP Michael MIC should protect us, and WEP is a ++ * lost cause anyway. ++ */ ++ return RX_DROP_UNUSABLE; ++ } else if (entry->is_protected && rx->key && ++ entry->key_color != rx->key->color && ++ (status->flag & RX_FLAG_DECRYPTED)) { ++ return RX_DROP_UNUSABLE; + } + + skb_pull(rx->skb, ieee80211_hdrlen(fc)); +@@ -2447,13 +2493,13 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) + struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; + + /* +- * Allow EAPOL frames to us/the PAE group address regardless +- * of whether the frame was encrypted or not. ++ * Allow EAPOL frames to us/the PAE group address regardless of ++ * whether the frame was encrypted or not, and always disallow ++ * all other destination addresses for them. + */ +- if (ehdr->h_proto == rx->sdata->control_port_protocol && +- (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || +- ether_addr_equal(ehdr->h_dest, pae_group_addr))) +- return true; ++ if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol)) ++ return ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) || ++ ether_addr_equal(ehdr->h_dest, pae_group_addr); + + if (ieee80211_802_1x_port_control(rx) || + ieee80211_drop_unencrypted(rx, fc)) +@@ -2477,8 +2523,28 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb, + cfg80211_rx_control_port(dev, skb, noencrypt); + dev_kfree_skb(skb); + } else { ++ struct ethhdr *ehdr = (void *)skb_mac_header(skb); ++ + memset(skb->cb, 0, sizeof(skb->cb)); + ++ /* ++ * 802.1X over 802.11 requires that the authenticator address ++ * be used for EAPOL frames. However, 802.1X allows the use of ++ * the PAE group address instead. If the interface is part of ++ * a bridge and we pass the frame with the PAE group address, ++ * then the bridge will forward it to the network (even if the ++ * client was not associated yet), which isn't supposed to ++ * happen. ++ * To avoid that, rewrite the destination address to our own ++ * address, so that the authenticator (e.g. hostapd) will see ++ * the frame, but bridge won't forward it anywhere else. Note ++ * that due to earlier filtering, the only other address can ++ * be the PAE group address. ++ */ ++ if (unlikely(skb->protocol == sdata->control_port_protocol && ++ !ether_addr_equal(ehdr->h_dest, sdata->vif.addr))) ++ ether_addr_copy(ehdr->h_dest, sdata->vif.addr); ++ + /* deliver to local stack */ + if (rx->napi) + napi_gro_receive(rx->napi, skb); +@@ -2518,6 +2584,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) + if ((sdata->vif.type == NL80211_IFTYPE_AP || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && + !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && ++ ehdr->h_proto != rx->sdata->control_port_protocol && + (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { + if (is_multicast_ether_addr(ehdr->h_dest) && + ieee80211_vif_get_num_mcast_if(sdata) != 0) { +@@ -2627,7 +2694,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) + if (ieee80211_data_to_8023_exthdr(skb, ðhdr, + rx->sdata->vif.addr, + rx->sdata->vif.type, +- data_offset)) ++ data_offset, true)) + return RX_DROP_UNUSABLE; + + ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, +@@ -2684,6 +2751,23 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) + if (is_multicast_ether_addr(hdr->addr1)) + return RX_DROP_UNUSABLE; + ++ if (rx->key) { ++ /* ++ * We should not receive A-MSDUs on pre-HT connections, ++ * and HT connections cannot use old ciphers. Thus drop ++ * them, as in those cases we couldn't even have SPP ++ * A-MSDUs or such. ++ */ ++ switch (rx->key->conf.cipher) { ++ case WLAN_CIPHER_SUITE_WEP40: ++ case WLAN_CIPHER_SUITE_WEP104: ++ case WLAN_CIPHER_SUITE_TKIP: ++ return RX_DROP_UNUSABLE; ++ default: ++ break; ++ } ++ } ++ + return __ieee80211_rx_h_amsdu(rx, 0); + } + +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index 4a23996dce044..82a1dd7b7d689 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -4,7 +4,7 @@ + * Copyright 2006-2007 Jiri Benc + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright (C) 2015 - 2017 Intel Deutschland GmbH +- * Copyright (C) 2018-2020 Intel Corporation ++ * Copyright (C) 2018-2021 Intel Corporation + */ + + #include +@@ -378,6 +378,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, + + u64_stats_init(&sta->rx_stats.syncp); + ++ ieee80211_init_frag_cache(&sta->frags); ++ + sta->sta_state = IEEE80211_STA_NONE; + + /* Mark TID as unreserved */ +@@ -1085,6 +1087,8 @@ static void __sta_info_destroy_part2(struct sta_info *sta) + + ieee80211_sta_debugfs_remove(sta); + ++ ieee80211_destroy_frag_cache(&sta->frags); ++ + cleanup_single_sta(sta); + } + +diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h +index be1d9dfa760d4..2eb73be9b9865 100644 +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -3,6 +3,7 @@ + * Copyright 2002-2005, Devicescape Software, Inc. + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright(c) 2015-2017 Intel Deutschland GmbH ++ * Copyright(c) 2020-2021 Intel Corporation + */ + + #ifndef STA_INFO_H +@@ -425,6 +426,34 @@ struct ieee80211_sta_rx_stats { + u64 msdu[IEEE80211_NUM_TIDS + 1]; + }; + ++/* ++ * IEEE 802.11-2016 (10.6 "Defragmentation") recommends support for "concurrent ++ * reception of at least one MSDU per access category per associated STA" ++ * on APs, or "at least one MSDU per access category" on other interface types. ++ * ++ * This limit can be increased by changing this define, at the cost of slower ++ * frame reassembly and increased memory use while fragments are pending. ++ */ ++#define IEEE80211_FRAGMENT_MAX 4 ++ ++struct ieee80211_fragment_entry { ++ struct sk_buff_head skb_list; ++ unsigned long first_frag_time; ++ u16 seq; ++ u16 extra_len; ++ u16 last_frag; ++ u8 rx_queue; ++ u8 check_sequential_pn:1, /* needed for CCMP/GCMP */ ++ is_protected:1; ++ u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ ++ unsigned int key_color; ++}; ++ ++struct ieee80211_fragment_cache { ++ struct ieee80211_fragment_entry entries[IEEE80211_FRAGMENT_MAX]; ++ unsigned int next; ++}; ++ + /* + * The bandwidth threshold below which the per-station CoDel parameters will be + * scaled to be more lenient (to prevent starvation of slow stations). This +@@ -518,6 +547,7 @@ struct ieee80211_sta_rx_stats { + * @status_stats.last_ack_signal: last ACK signal + * @status_stats.ack_signal_filled: last ACK signal validity + * @status_stats.avg_ack_signal: average ACK signal ++ * @frags: fragment cache + */ + struct sta_info { + /* General information, mostly static */ +@@ -623,6 +653,8 @@ struct sta_info { + + struct cfg80211_chan_def tdls_chandef; + ++ struct ieee80211_fragment_cache frags; ++ + /* keep last! */ + struct ieee80211_sta sta; + }; +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index 91bf32af55e9a..bca47fad5a162 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -3,6 +3,7 @@ + * Copyright 2002-2004, Instant802 Networks, Inc. + * Copyright 2008, Jouni Malinen + * Copyright (C) 2016-2017 Intel Deutschland GmbH ++ * Copyright (C) 2020-2021 Intel Corporation + */ + + #include +@@ -167,8 +168,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + + update_iv: + /* update IV in key information to be able to detect replays */ +- rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip_iv32; +- rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip_iv16; ++ rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip.iv32; ++ rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip.iv16; + + return RX_CONTINUE; + +@@ -294,8 +295,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) + key, skb->data + hdrlen, + skb->len - hdrlen, rx->sta->sta.addr, + hdr->addr1, hwaccel, rx->security_idx, +- &rx->tkip_iv32, +- &rx->tkip_iv16); ++ &rx->tkip.iv32, ++ &rx->tkip.iv16); + if (res != TKIP_DECRYPT_OK) + return RX_DROP_UNUSABLE; + +@@ -553,6 +554,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, + } + + memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN); ++ if (unlikely(ieee80211_is_frag(hdr))) ++ memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); + } + + /* Remove CCMP header and MIC */ +@@ -781,6 +784,8 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) + } + + memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN); ++ if (unlikely(ieee80211_is_frag(hdr))) ++ memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); + } + + /* Remove GCMP header and MIC */ +diff --git a/net/openvswitch/meter.c b/net/openvswitch/meter.c +index 541eea74ef7a6..c37e09223cbb4 100644 +--- a/net/openvswitch/meter.c ++++ b/net/openvswitch/meter.c +@@ -460,6 +460,14 @@ bool ovs_meter_execute(struct datapath *dp, struct sk_buff *skb, + spin_lock(&meter->lock); + + long_delta_ms = (now_ms - meter->used); /* ms */ ++ if (long_delta_ms < 0) { ++ /* This condition means that we have several threads fighting ++ * for a meter lock, and the one who received the packets a ++ * bit later wins. Assuming that all racing threads received ++ * packets at the same time to avoid overflow. ++ */ ++ long_delta_ms = 0; ++ } + + /* Make sure delta_ms will not be too large, so that bucket will not + * wrap around below. +diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c +index 2b88710994d71..76ed1a05ded27 100644 +--- a/net/sched/sch_dsmark.c ++++ b/net/sched/sch_dsmark.c +@@ -406,7 +406,8 @@ static void dsmark_reset(struct Qdisc *sch) + struct dsmark_qdisc_data *p = qdisc_priv(sch); + + pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p); +- qdisc_reset(p->q); ++ if (p->q) ++ qdisc_reset(p->q); + sch->qstats.backlog = 0; + sch->q.qlen = 0; + } +diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c +index 6e6147a81bc3a..9bc5cbe9809b8 100644 +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -35,6 +35,25 @@ + const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops; + EXPORT_SYMBOL(default_qdisc_ops); + ++static void qdisc_maybe_clear_missed(struct Qdisc *q, ++ const struct netdev_queue *txq) ++{ ++ clear_bit(__QDISC_STATE_MISSED, &q->state); ++ ++ /* Make sure the below netif_xmit_frozen_or_stopped() ++ * checking happens after clearing STATE_MISSED. ++ */ ++ smp_mb__after_atomic(); ++ ++ /* Checking netif_xmit_frozen_or_stopped() again to ++ * make sure STATE_MISSED is set if the STATE_MISSED ++ * set by netif_tx_wake_queue()'s rescheduling of ++ * net_tx_action() is cleared by the above clear_bit(). ++ */ ++ if (!netif_xmit_frozen_or_stopped(txq)) ++ set_bit(__QDISC_STATE_MISSED, &q->state); ++} ++ + /* Main transmission queue. */ + + /* Modifications to data participating in scheduling must be protected with +@@ -74,6 +93,7 @@ static inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q) + } + } else { + skb = SKB_XOFF_MAGIC; ++ qdisc_maybe_clear_missed(q, txq); + } + } + +@@ -242,6 +262,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, + } + } else { + skb = NULL; ++ qdisc_maybe_clear_missed(q, txq); + } + if (lock) + spin_unlock(lock); +@@ -251,8 +272,10 @@ validate: + *validate = true; + + if ((q->flags & TCQ_F_ONETXQUEUE) && +- netif_xmit_frozen_or_stopped(txq)) ++ netif_xmit_frozen_or_stopped(txq)) { ++ qdisc_maybe_clear_missed(q, txq); + return skb; ++ } + + skb = qdisc_dequeue_skb_bad_txq(q); + if (unlikely(skb)) { +@@ -311,6 +334,8 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, + HARD_TX_LOCK(dev, txq, smp_processor_id()); + if (!netif_xmit_frozen_or_stopped(txq)) + skb = dev_hard_start_xmit(skb, dev, txq, &ret); ++ else ++ qdisc_maybe_clear_missed(q, txq); + + HARD_TX_UNLOCK(dev, txq); + } else { +@@ -645,8 +670,10 @@ static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc) + { + struct pfifo_fast_priv *priv = qdisc_priv(qdisc); + struct sk_buff *skb = NULL; ++ bool need_retry = true; + int band; + ++retry: + for (band = 0; band < PFIFO_FAST_BANDS && !skb; band++) { + struct skb_array *q = band2list(priv, band); + +@@ -657,6 +684,23 @@ static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc) + } + if (likely(skb)) { + qdisc_update_stats_at_dequeue(qdisc, skb); ++ } else if (need_retry && ++ test_bit(__QDISC_STATE_MISSED, &qdisc->state)) { ++ /* Delay clearing the STATE_MISSED here to reduce ++ * the overhead of the second spin_trylock() in ++ * qdisc_run_begin() and __netif_schedule() calling ++ * in qdisc_run_end(). ++ */ ++ clear_bit(__QDISC_STATE_MISSED, &qdisc->state); ++ ++ /* Make sure dequeuing happens after clearing ++ * STATE_MISSED. ++ */ ++ smp_mb__after_atomic(); ++ ++ need_retry = false; ++ ++ goto retry; + } else { + WRITE_ONCE(qdisc->empty, true); + } +@@ -1157,8 +1201,10 @@ static void dev_reset_queue(struct net_device *dev, + qdisc_reset(qdisc); + + spin_unlock_bh(qdisc_lock(qdisc)); +- if (nolock) ++ if (nolock) { ++ clear_bit(__QDISC_STATE_MISSED, &qdisc->state); + spin_unlock_bh(&qdisc->seqlock); ++ } + } + + static bool some_qdisc_is_busy(struct net_device *dev) +diff --git a/net/smc/smc_ism.c b/net/smc/smc_ism.c +index e89e918b88e09..2fff79db1a59c 100644 +--- a/net/smc/smc_ism.c ++++ b/net/smc/smc_ism.c +@@ -289,11 +289,6 @@ struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name, + INIT_LIST_HEAD(&smcd->vlan); + smcd->event_wq = alloc_ordered_workqueue("ism_evt_wq-%s)", + WQ_MEM_RECLAIM, name); +- if (!smcd->event_wq) { +- kfree(smcd->conn); +- kfree(smcd); +- return NULL; +- } + return smcd; + } + EXPORT_SYMBOL_GPL(smcd_alloc_dev); +diff --git a/net/tipc/core.c b/net/tipc/core.c +index e3d79f8b69d81..90cf7e0bbaf0f 100644 +--- a/net/tipc/core.c ++++ b/net/tipc/core.c +@@ -107,6 +107,9 @@ static void __net_exit tipc_exit_net(struct net *net) + tipc_bcast_stop(net); + tipc_nametbl_stop(net); + tipc_sk_rht_destroy(net); ++ ++ while (atomic_read(&tn->wq_count)) ++ cond_resched(); + } + + static struct pernet_operations tipc_net_ops = { +diff --git a/net/tipc/core.h b/net/tipc/core.h +index e119c4a88d63e..c6bda91f85810 100644 +--- a/net/tipc/core.h ++++ b/net/tipc/core.h +@@ -143,6 +143,8 @@ struct tipc_net { + + /* Work item for net finalize */ + struct tipc_net_work final_work; ++ /* The numbers of work queues in schedule */ ++ atomic_t wq_count; + }; + + static inline struct tipc_net *tipc_net(struct net *net) +diff --git a/net/tipc/msg.c b/net/tipc/msg.c +index 46e89c992c2dc..e4ea942873d49 100644 +--- a/net/tipc/msg.c ++++ b/net/tipc/msg.c +@@ -141,18 +141,13 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) + if (unlikely(head)) + goto err; + *buf = NULL; ++ if (skb_has_frag_list(frag) && __skb_linearize(frag)) ++ goto err; + frag = skb_unshare(frag, GFP_ATOMIC); + if (unlikely(!frag)) + goto err; + head = *headbuf = frag; + TIPC_SKB_CB(head)->tail = NULL; +- if (skb_is_nonlinear(head)) { +- skb_walk_frags(head, tail) { +- TIPC_SKB_CB(head)->tail = tail; +- } +- } else { +- skb_frag_list_init(head); +- } + return 0; + } + +diff --git a/net/tipc/socket.c b/net/tipc/socket.c +index b2c36dcfc8e2f..cdade990fe445 100644 +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -1210,7 +1210,10 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, + spin_lock_bh(&inputq->lock); + if (skb_peek(arrvq) == skb) { + skb_queue_splice_tail_init(&tmpq, inputq); +- __skb_dequeue(arrvq); ++ /* Decrease the skb's refcnt as increasing in the ++ * function tipc_skb_peek ++ */ ++ kfree_skb(__skb_dequeue(arrvq)); + } + spin_unlock_bh(&inputq->lock); + __skb_queue_purge(&tmpq); +diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c +index 8f0977a9d423c..1fb0535e2eb47 100644 +--- a/net/tipc/udp_media.c ++++ b/net/tipc/udp_media.c +@@ -802,6 +802,7 @@ static void cleanup_bearer(struct work_struct *work) + kfree_rcu(rcast, rcu); + } + ++ atomic_dec(&tipc_net(sock_net(ub->ubsock->sk))->wq_count); + dst_cache_destroy(&ub->rcast.dst_cache); + udp_tunnel_sock_release(ub->ubsock); + synchronize_net(); +@@ -822,6 +823,7 @@ static void tipc_udp_disable(struct tipc_bearer *b) + RCU_INIT_POINTER(ub->bearer, NULL); + + /* sock_release need to be done outside of rtnl lock */ ++ atomic_inc(&tipc_net(sock_net(ub->ubsock->sk))->wq_count); + INIT_WORK(&ub->work, cleanup_bearer); + schedule_work(&ub->work); + } +diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c +index 0d524ef0d8c80..cdb65aa54be70 100644 +--- a/net/tls/tls_sw.c ++++ b/net/tls/tls_sw.c +@@ -37,6 +37,7 @@ + + #include + #include ++#include + #include + + #include +@@ -1278,7 +1279,7 @@ int tls_sw_sendpage(struct sock *sk, struct page *page, + } + + static struct sk_buff *tls_wait_data(struct sock *sk, struct sk_psock *psock, +- int flags, long timeo, int *err) ++ bool nonblock, long timeo, int *err) + { + struct tls_context *tls_ctx = tls_get_ctx(sk); + struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx); +@@ -1303,7 +1304,7 @@ static struct sk_buff *tls_wait_data(struct sock *sk, struct sk_psock *psock, + if (sock_flag(sk, SOCK_DONE)) + return NULL; + +- if ((flags & MSG_DONTWAIT) || !timeo) { ++ if (nonblock || !timeo) { + *err = -EAGAIN; + return NULL; + } +@@ -1781,7 +1782,7 @@ int tls_sw_recvmsg(struct sock *sk, + bool async_capable; + bool async = false; + +- skb = tls_wait_data(sk, psock, flags, timeo, &err); ++ skb = tls_wait_data(sk, psock, flags & MSG_DONTWAIT, timeo, &err); + if (!skb) { + if (psock) { + int ret = __tcp_bpf_recvmsg(sk, psock, +@@ -1985,9 +1986,9 @@ ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos, + + lock_sock(sk); + +- timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); ++ timeo = sock_rcvtimeo(sk, flags & SPLICE_F_NONBLOCK); + +- skb = tls_wait_data(sk, NULL, flags, timeo, &err); ++ skb = tls_wait_data(sk, NULL, flags & SPLICE_F_NONBLOCK, timeo, &err); + if (!skb) + goto splice_read_end; + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 9abafd76ec50e..82244e2fc1f54 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -451,7 +451,7 @@ EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); + + int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + const u8 *addr, enum nl80211_iftype iftype, +- u8 data_offset) ++ u8 data_offset, bool is_amsdu) + { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct { +@@ -539,7 +539,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, + skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); + tmp.h_proto = payload.proto; + +- if (likely((ether_addr_equal(payload.hdr, rfc1042_header) && ++ if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && + tmp.h_proto != htons(ETH_P_AARP) && + tmp.h_proto != htons(ETH_P_IPX)) || + ether_addr_equal(payload.hdr, bridge_tunnel_header))) +@@ -681,6 +681,9 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, + remaining = skb->len - offset; + if (subframe_len > remaining) + goto purge; ++ /* mitigate A-MSDU aggregation injection attacks */ ++ if (ether_addr_equal(eth.h_dest, rfc1042_header)) ++ goto purge; + + offset += sizeof(struct ethhdr); + last = remaining <= subframe_len + padding; +diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c +index af6b4d89d6952..39911a637e802 100644 +--- a/sound/isa/gus/gus_main.c ++++ b/sound/isa/gus/gus_main.c +@@ -77,17 +77,8 @@ static const struct snd_kcontrol_new snd_gus_joystick_control = { + + static void snd_gus_init_control(struct snd_gus_card *gus) + { +- int ret; +- +- if (!gus->ace_flag) { +- ret = +- snd_ctl_add(gus->card, +- snd_ctl_new1(&snd_gus_joystick_control, +- gus)); +- if (ret) +- snd_printk(KERN_ERR "gus: snd_ctl_add failed: %d\n", +- ret); +- } ++ if (!gus->ace_flag) ++ snd_ctl_add(gus->card, snd_ctl_new1(&snd_gus_joystick_control, gus)); + } + + /* +diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c +index 0768bbf8fd713..679f9f48370ff 100644 +--- a/sound/isa/sb/sb16_main.c ++++ b/sound/isa/sb/sb16_main.c +@@ -864,14 +864,10 @@ int snd_sb16dsp_pcm(struct snd_sb *chip, int device) + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb16_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb16_capture_ops); + +- if (chip->dma16 >= 0 && chip->dma8 != chip->dma16) { +- err = snd_ctl_add(card, snd_ctl_new1( +- &snd_sb16_dma_control, chip)); +- if (err) +- return err; +- } else { ++ if (chip->dma16 >= 0 && chip->dma8 != chip->dma16) ++ snd_ctl_add(card, snd_ctl_new1(&snd_sb16_dma_control, chip)); ++ else + pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; +- } + + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + card->dev, +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index d02c49e1686b6..b9fa2ee0a40cb 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -2593,6 +2593,28 @@ static const struct hda_model_fixup alc882_fixup_models[] = { + {} + }; + ++static const struct snd_hda_pin_quirk alc882_pin_fixup_tbl[] = { ++ SND_HDA_PIN_QUIRK(0x10ec1220, 0x1043, "ASUS", ALC1220_FIXUP_CLEVO_P950, ++ {0x14, 0x01014010}, ++ {0x15, 0x01011012}, ++ {0x16, 0x01016011}, ++ {0x18, 0x01a19040}, ++ {0x19, 0x02a19050}, ++ {0x1a, 0x0181304f}, ++ {0x1b, 0x0221401f}, ++ {0x1e, 0x01456130}), ++ SND_HDA_PIN_QUIRK(0x10ec1220, 0x1462, "MS-7C35", ALC1220_FIXUP_CLEVO_P950, ++ {0x14, 0x01015010}, ++ {0x15, 0x01011012}, ++ {0x16, 0x01011011}, ++ {0x18, 0x01a11040}, ++ {0x19, 0x02a19050}, ++ {0x1a, 0x0181104f}, ++ {0x1b, 0x0221401f}, ++ {0x1e, 0x01451130}), ++ {} ++}; ++ + /* + * BIOS auto configuration + */ +@@ -2634,6 +2656,7 @@ static int patch_alc882(struct hda_codec *codec) + + snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, + alc882_fixups); ++ snd_hda_pick_pin_fixup(codec, alc882_pin_fixup_tbl, alc882_fixups, true); + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); + + alc_auto_parse_customize_define(codec); +diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c +index 6042194d95d3e..8894369e329af 100644 +--- a/sound/soc/codecs/cs35l33.c ++++ b/sound/soc/codecs/cs35l33.c +@@ -1201,6 +1201,7 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client, + dev_err(&i2c_client->dev, + "CS35L33 Device ID (%X). Expected ID %X\n", + devid, CS35L33_CHIP_ID); ++ ret = -EINVAL; + goto err_enable; + } + +diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c +index dcd2acb2c3cef..5faf8877137ae 100644 +--- a/sound/soc/codecs/cs42l42.c ++++ b/sound/soc/codecs/cs42l42.c +@@ -398,6 +398,9 @@ static const struct regmap_config cs42l42_regmap = { + .reg_defaults = cs42l42_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(cs42l42_reg_defaults), + .cache_type = REGCACHE_RBTREE, ++ ++ .use_single_read = true, ++ .use_single_write = true, + }; + + static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, false); +diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c +index 7fb34422a2a4b..8f70dee958786 100644 +--- a/sound/soc/codecs/cs43130.c ++++ b/sound/soc/codecs/cs43130.c +@@ -1735,6 +1735,14 @@ static DEVICE_ATTR(hpload_dc_r, 0444, cs43130_show_dc_r, NULL); + static DEVICE_ATTR(hpload_ac_l, 0444, cs43130_show_ac_l, NULL); + static DEVICE_ATTR(hpload_ac_r, 0444, cs43130_show_ac_r, NULL); + ++static struct attribute *hpload_attrs[] = { ++ &dev_attr_hpload_dc_l.attr, ++ &dev_attr_hpload_dc_r.attr, ++ &dev_attr_hpload_ac_l.attr, ++ &dev_attr_hpload_ac_r.attr, ++}; ++ATTRIBUTE_GROUPS(hpload); ++ + static struct reg_sequence hp_en_cal_seq[] = { + {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL}, + {CS43130_HP_MEAS_LOAD_1, 0}, +@@ -2302,25 +2310,15 @@ static int cs43130_probe(struct snd_soc_component *component) + + cs43130->hpload_done = false; + if (cs43130->dc_meas) { +- ret = device_create_file(component->dev, &dev_attr_hpload_dc_l); +- if (ret < 0) +- return ret; +- +- ret = device_create_file(component->dev, &dev_attr_hpload_dc_r); +- if (ret < 0) +- return ret; +- +- ret = device_create_file(component->dev, &dev_attr_hpload_ac_l); +- if (ret < 0) +- return ret; +- +- ret = device_create_file(component->dev, &dev_attr_hpload_ac_r); +- if (ret < 0) ++ ret = sysfs_create_groups(&component->dev->kobj, hpload_groups); ++ if (ret) + return ret; + + cs43130->wq = create_singlethread_workqueue("cs43130_hp"); +- if (!cs43130->wq) ++ if (!cs43130->wq) { ++ sysfs_remove_groups(&component->dev->kobj, hpload_groups); + return -ENOMEM; ++ } + INIT_WORK(&cs43130->work, cs43130_imp_meas); + } + +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index 2040fecea17b3..5251818e10d33 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -2268,7 +2268,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) + case USB_ID(0x1235, 0x8203): /* Focusrite Scarlett 6i6 2nd Gen */ + case USB_ID(0x1235, 0x8204): /* Focusrite Scarlett 18i8 2nd Gen */ + case USB_ID(0x1235, 0x8201): /* Focusrite Scarlett 18i20 2nd Gen */ +- err = snd_scarlett_gen2_controls_create(mixer); ++ err = snd_scarlett_gen2_init(mixer); + break; + + case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */ +diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c +index 74c00c905d245..7a10c9e22c46c 100644 +--- a/sound/usb/mixer_scarlett_gen2.c ++++ b/sound/usb/mixer_scarlett_gen2.c +@@ -635,7 +635,7 @@ static int scarlett2_usb( + /* send a second message to get the response */ + + err = snd_usb_ctl_msg(mixer->chip->dev, +- usb_sndctrlpipe(mixer->chip->dev, 0), ++ usb_rcvctrlpipe(mixer->chip->dev, 0), + SCARLETT2_USB_VENDOR_SPECIFIC_CMD_RESP, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + 0, +@@ -1997,38 +1997,11 @@ static int scarlett2_mixer_status_create(struct usb_mixer_interface *mixer) + return usb_submit_urb(mixer->urb, GFP_KERNEL); + } + +-/* Entry point */ +-int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer) ++static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer, ++ const struct scarlett2_device_info *info) + { +- const struct scarlett2_device_info *info; + int err; + +- /* only use UAC_VERSION_2 */ +- if (!mixer->protocol) +- return 0; +- +- switch (mixer->chip->usb_id) { +- case USB_ID(0x1235, 0x8203): +- info = &s6i6_gen2_info; +- break; +- case USB_ID(0x1235, 0x8204): +- info = &s18i8_gen2_info; +- break; +- case USB_ID(0x1235, 0x8201): +- info = &s18i20_gen2_info; +- break; +- default: /* device not (yet) supported */ +- return -EINVAL; +- } +- +- if (!(mixer->chip->setup & SCARLETT2_ENABLE)) { +- usb_audio_err(mixer->chip, +- "Focusrite Scarlett Gen 2 Mixer Driver disabled; " +- "use options snd_usb_audio device_setup=1 " +- "to enable and report any issues to g@b4.vu"); +- return 0; +- } +- + /* Initialise private data, routing, sequence number */ + err = scarlett2_init_private(mixer, info); + if (err < 0) +@@ -2073,3 +2046,51 @@ int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer) + + return 0; + } ++ ++int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer) ++{ ++ struct snd_usb_audio *chip = mixer->chip; ++ const struct scarlett2_device_info *info; ++ int err; ++ ++ /* only use UAC_VERSION_2 */ ++ if (!mixer->protocol) ++ return 0; ++ ++ switch (chip->usb_id) { ++ case USB_ID(0x1235, 0x8203): ++ info = &s6i6_gen2_info; ++ break; ++ case USB_ID(0x1235, 0x8204): ++ info = &s18i8_gen2_info; ++ break; ++ case USB_ID(0x1235, 0x8201): ++ info = &s18i20_gen2_info; ++ break; ++ default: /* device not (yet) supported */ ++ return -EINVAL; ++ } ++ ++ if (!(chip->setup & SCARLETT2_ENABLE)) { ++ usb_audio_info(chip, ++ "Focusrite Scarlett Gen 2 Mixer Driver disabled; " ++ "use options snd_usb_audio vid=0x%04x pid=0x%04x " ++ "device_setup=1 to enable and report any issues " ++ "to g@b4.vu", ++ USB_ID_VENDOR(chip->usb_id), ++ USB_ID_PRODUCT(chip->usb_id)); ++ return 0; ++ } ++ ++ usb_audio_info(chip, ++ "Focusrite Scarlett Gen 2 Mixer Driver enabled pid=0x%04x", ++ USB_ID_PRODUCT(chip->usb_id)); ++ ++ err = snd_scarlett_gen2_controls_create(mixer, info); ++ if (err < 0) ++ usb_audio_err(mixer->chip, ++ "Error initialising Scarlett Mixer Driver: %d", ++ err); ++ ++ return err; ++} +diff --git a/sound/usb/mixer_scarlett_gen2.h b/sound/usb/mixer_scarlett_gen2.h +index 52e1dad77afd4..668c6b0cb50a6 100644 +--- a/sound/usb/mixer_scarlett_gen2.h ++++ b/sound/usb/mixer_scarlett_gen2.h +@@ -2,6 +2,6 @@ + #ifndef __USB_MIXER_SCARLETT_GEN2_H + #define __USB_MIXER_SCARLETT_GEN2_H + +-int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer); ++int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer); + + #endif /* __USB_MIXER_SCARLETT_GEN2_H */ +diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c +index f4a0d72246cb7..47f57f5829d3a 100644 +--- a/tools/perf/pmu-events/jevents.c ++++ b/tools/perf/pmu-events/jevents.c +@@ -862,7 +862,7 @@ static int get_maxfds(void) + struct rlimit rlim; + + if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) +- return min((int)rlim.rlim_max / 2, 512); ++ return min(rlim.rlim_max / 2, (rlim_t)512); + + return 512; + } +diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py +index 04217e8f535aa..01acf3ea7619d 100755 +--- a/tools/perf/scripts/python/exported-sql-viewer.py ++++ b/tools/perf/scripts/python/exported-sql-viewer.py +@@ -91,6 +91,11 @@ + from __future__ import print_function + + import sys ++# Only change warnings if the python -W option was not used ++if not sys.warnoptions: ++ import warnings ++ # PySide2 causes deprecation warnings, ignore them. ++ warnings.filterwarnings("ignore", category=DeprecationWarning) + import argparse + import weakref + import threading +@@ -122,8 +127,9 @@ if pyside_version_1: + from PySide.QtGui import * + from PySide.QtSql import * + +-from decimal import * +-from ctypes import * ++from decimal import Decimal, ROUND_HALF_UP ++from ctypes import CDLL, Structure, create_string_buffer, addressof, sizeof, \ ++ c_void_p, c_bool, c_byte, c_char, c_int, c_uint, c_longlong, c_ulonglong + from multiprocessing import Process, Array, Value, Event + + # xrange is range in Python3 +@@ -2495,7 +2501,7 @@ def CopyTableCellsToClipboard(view, as_csv=False, with_hdr=False): + if with_hdr: + model = indexes[0].model() + for col in range(min_col, max_col + 1): +- val = model.headerData(col, Qt.Horizontal) ++ val = model.headerData(col, Qt.Horizontal, Qt.DisplayRole) + if as_csv: + text += sep + ToCSValue(val) + sep = "," +diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +index 7f53b63088b2c..eab7e8ef67899 100644 +--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c ++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +@@ -1090,6 +1090,8 @@ static bool intel_pt_fup_event(struct intel_pt_decoder *decoder) + decoder->set_fup_tx_flags = false; + decoder->tx_flags = decoder->fup_tx_flags; + decoder->state.type = INTEL_PT_TRANSACTION; ++ if (decoder->fup_tx_flags & INTEL_PT_ABORT_TX) ++ decoder->state.type |= INTEL_PT_BRANCH; + decoder->state.from_ip = decoder->ip; + decoder->state.to_ip = 0; + decoder->state.flags = decoder->fup_tx_flags; +@@ -1164,8 +1166,10 @@ static int intel_pt_walk_fup(struct intel_pt_decoder *decoder) + return 0; + if (err == -EAGAIN || + intel_pt_fup_with_nlip(decoder, &intel_pt_insn, ip, err)) { ++ bool no_tip = decoder->pkt_state != INTEL_PT_STATE_FUP; ++ + decoder->pkt_state = INTEL_PT_STATE_IN_SYNC; +- if (intel_pt_fup_event(decoder)) ++ if (intel_pt_fup_event(decoder) && no_tip) + return 0; + return -EAGAIN; + } +diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c +index d0e0ce11faf58..9b7cc5f909b07 100644 +--- a/tools/perf/util/intel-pt.c ++++ b/tools/perf/util/intel-pt.c +@@ -602,8 +602,10 @@ static int intel_pt_walk_next_insn(struct intel_pt_insn *intel_pt_insn, + + *ip += intel_pt_insn->length; + +- if (to_ip && *ip == to_ip) ++ if (to_ip && *ip == to_ip) { ++ intel_pt_insn->length = 0; + goto out_no_cache; ++ } + + if (*ip >= al.map->end) + break; +@@ -991,6 +993,7 @@ static void intel_pt_set_pid_tid_cpu(struct intel_pt *pt, + + static void intel_pt_sample_flags(struct intel_pt_queue *ptq) + { ++ ptq->insn_len = 0; + if (ptq->state->flags & INTEL_PT_ABORT_TX) { + ptq->flags = PERF_IP_FLAG_BRANCH | PERF_IP_FLAG_TX_ABORT; + } else if (ptq->state->flags & INTEL_PT_ASYNC) { +diff --git a/tools/testing/selftests/gpio/Makefile b/tools/testing/selftests/gpio/Makefile +index 0bb80619db580..f270b6abd64c5 100644 +--- a/tools/testing/selftests/gpio/Makefile ++++ b/tools/testing/selftests/gpio/Makefile +@@ -11,22 +11,24 @@ LDLIBS += $(MOUNT_LDLIBS) + + TEST_PROGS := gpio-mockup.sh + TEST_FILES := gpio-mockup-sysfs.sh +-TEST_PROGS_EXTENDED := gpio-mockup-chardev ++TEST_GEN_PROGS_EXTENDED := gpio-mockup-chardev + +-GPIODIR := $(realpath ../../../gpio) +-GPIOOBJ := gpio-utils.o ++KSFT_KHDR_INSTALL := 1 ++include ../lib.mk + +-all: $(TEST_PROGS_EXTENDED) ++GPIODIR := $(realpath ../../../gpio) ++GPIOOUT := $(OUTPUT)/tools-gpio/ ++GPIOOBJ := $(GPIOOUT)/gpio-utils.o + + override define CLEAN +- $(RM) $(TEST_PROGS_EXTENDED) +- $(MAKE) -C $(GPIODIR) OUTPUT=$(GPIODIR)/ clean ++ $(RM) $(TEST_GEN_PROGS_EXTENDED) ++ $(RM) -rf $(GPIOOUT) + endef + +-KSFT_KHDR_INSTALL := 1 +-include ../lib.mk ++$(TEST_GEN_PROGS_EXTENDED): $(GPIOOBJ) + +-$(TEST_PROGS_EXTENDED): $(GPIODIR)/$(GPIOOBJ) ++$(GPIOOUT): ++ mkdir -p $@ + +-$(GPIODIR)/$(GPIOOBJ): +- $(MAKE) OUTPUT=$(GPIODIR)/ -C $(GPIODIR) ++$(GPIOOBJ): $(GPIOOUT) ++ $(MAKE) OUTPUT=$(GPIOOUT) -C $(GPIODIR) diff --git a/patch/kernel/archive/odroidxu4-5.4/patch-5.4.124-125.patch b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.124-125.patch new file mode 100644 index 0000000000..21a9802de4 --- /dev/null +++ b/patch/kernel/archive/odroidxu4-5.4/patch-5.4.124-125.patch @@ -0,0 +1,3019 @@ +diff --git a/Documentation/core-api/xarray.rst b/Documentation/core-api/xarray.rst +index fcedc5349ace4..2ad3c1fce5795 100644 +--- a/Documentation/core-api/xarray.rst ++++ b/Documentation/core-api/xarray.rst +@@ -461,13 +461,15 @@ or iterations will move the index to the first index in the range. + Each entry will only be returned once, no matter how many indices it + occupies. + +-Using xas_next() or xas_prev() with a multi-index xa_state +-is not supported. Using either of these functions on a multi-index entry +-will reveal sibling entries; these should be skipped over by the caller. +- +-Storing ``NULL`` into any index of a multi-index entry will set the entry +-at every index to ``NULL`` and dissolve the tie. Splitting a multi-index +-entry into entries occupying smaller ranges is not yet supported. ++Using xas_next() or xas_prev() with a multi-index xa_state is not ++supported. Using either of these functions on a multi-index entry will ++reveal sibling entries; these should be skipped over by the caller. ++ ++Storing ``NULL`` into any index of a multi-index entry will set the ++entry at every index to ``NULL`` and dissolve the tie. A multi-index ++entry can be split into entries occupying smaller ranges by calling ++xas_split_alloc() without the xa_lock held, followed by taking the lock ++and calling xas_split(). + + Functions and structures + ======================== +diff --git a/Makefile b/Makefile +index 22668742d3d04..43e7b07eea80e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 4 +-SUBLEVEL = 124 ++SUBLEVEL = 125 + EXTRAVERSION = + NAME = Kleptomaniac Octopus + +diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi +index e8d800fec6379..ce4a5a8074422 100644 +--- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi ++++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi +@@ -99,9 +99,13 @@ + phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + phy-reset-duration = <20>; + phy-supply = <&sw2_reg>; +- phy-handle = <ðphy0>; + status = "okay"; + ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ + mdio { + #address-cells = <1>; + #size-cells = <0>; +diff --git a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi +index 08a2e17e0539b..621894d13dcbc 100644 +--- a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi ++++ b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi +@@ -408,6 +408,18 @@ + vin-supply = <&sw1_reg>; + }; + ++®_pu { ++ vin-supply = <&sw1_reg>; ++}; ++ ++®_vdd1p1 { ++ vin-supply = <&sw2_reg>; ++}; ++ ++®_vdd2p5 { ++ vin-supply = <&sw2_reg>; ++}; ++ + &uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; +diff --git a/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi b/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi +index 828cf3e39784a..c4e146f3341bb 100644 +--- a/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi +@@ -126,7 +126,7 @@ + compatible = "nxp,pca8574"; + reg = <0x3a>; + gpio-controller; +- #gpio-cells = <1>; ++ #gpio-cells = <2>; + }; + }; + +diff --git a/arch/arm/boot/dts/imx7d-meerkat96.dts b/arch/arm/boot/dts/imx7d-meerkat96.dts +index 5339210b63d0f..dd8003bd1fc09 100644 +--- a/arch/arm/boot/dts/imx7d-meerkat96.dts ++++ b/arch/arm/boot/dts/imx7d-meerkat96.dts +@@ -193,7 +193,7 @@ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + keep-power-in-suspend; +- tuning-step = <2>; ++ fsl,tuning-step = <2>; + vmmc-supply = <®_3p3v>; + no-1-8-v; + broken-cd; +diff --git a/arch/arm/boot/dts/imx7d-pico.dtsi b/arch/arm/boot/dts/imx7d-pico.dtsi +index 6f50ebf31a0ab..8a8df54ff5639 100644 +--- a/arch/arm/boot/dts/imx7d-pico.dtsi ++++ b/arch/arm/boot/dts/imx7d-pico.dtsi +@@ -307,7 +307,7 @@ + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; + bus-width = <4>; +- tuning-step = <2>; ++ fsl,tuning-step = <2>; + vmmc-supply = <®_3p3v>; + wakeup-source; + no-1-8-v; +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +index bd99fa68b7630..5a2a188debd1d 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +@@ -151,8 +151,8 @@ + ddr: memory-controller@1080000 { + compatible = "fsl,qoriq-memory-controller"; + reg = <0x0 0x1080000 0x0 0x1000>; +- interrupts = ; +- big-endian; ++ interrupts = ; ++ little-endian; + }; + + dcfg: syscon@1e00000 { +diff --git a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi +index 32ce14936b013..f385b143b3086 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi +@@ -45,8 +45,8 @@ + reg_12p0_main: regulator-12p0-main { + compatible = "regulator-fixed"; + regulator-name = "12V_MAIN"; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + +diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c +index 98a177dd1f89f..da649e90240c8 100644 +--- a/arch/arm64/kvm/sys_regs.c ++++ b/arch/arm64/kvm/sys_regs.c +@@ -432,14 +432,14 @@ static bool trap_bvr(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *rd) + { +- u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg]; ++ u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; + + if (p->is_write) + reg_to_dbg(vcpu, p, dbg_reg); + else + dbg_to_reg(vcpu, p, dbg_reg); + +- trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); ++ trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg); + + return true; + } +@@ -447,7 +447,7 @@ static bool trap_bvr(struct kvm_vcpu *vcpu, + static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + const struct kvm_one_reg *reg, void __user *uaddr) + { +- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg]; ++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; + + if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) + return -EFAULT; +@@ -457,7 +457,7 @@ static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + const struct kvm_one_reg *reg, void __user *uaddr) + { +- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg]; ++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; + + if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) + return -EFAULT; +@@ -467,21 +467,21 @@ static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + static void reset_bvr(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd) + { +- vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg] = rd->val; ++ vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm] = rd->val; + } + + static bool trap_bcr(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *rd) + { +- u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg]; ++ u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; + + if (p->is_write) + reg_to_dbg(vcpu, p, dbg_reg); + else + dbg_to_reg(vcpu, p, dbg_reg); + +- trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); ++ trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg); + + return true; + } +@@ -489,7 +489,7 @@ static bool trap_bcr(struct kvm_vcpu *vcpu, + static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + const struct kvm_one_reg *reg, void __user *uaddr) + { +- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg]; ++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; + + if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) + return -EFAULT; +@@ -500,7 +500,7 @@ static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + const struct kvm_one_reg *reg, void __user *uaddr) + { +- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg]; ++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; + + if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) + return -EFAULT; +@@ -510,22 +510,22 @@ static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + static void reset_bcr(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd) + { +- vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg] = rd->val; ++ vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm] = rd->val; + } + + static bool trap_wvr(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *rd) + { +- u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]; ++ u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; + + if (p->is_write) + reg_to_dbg(vcpu, p, dbg_reg); + else + dbg_to_reg(vcpu, p, dbg_reg); + +- trace_trap_reg(__func__, rd->reg, p->is_write, +- vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]); ++ trace_trap_reg(__func__, rd->CRm, p->is_write, ++ vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]); + + return true; + } +@@ -533,7 +533,7 @@ static bool trap_wvr(struct kvm_vcpu *vcpu, + static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + const struct kvm_one_reg *reg, void __user *uaddr) + { +- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]; ++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; + + if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) + return -EFAULT; +@@ -543,7 +543,7 @@ static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + const struct kvm_one_reg *reg, void __user *uaddr) + { +- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]; ++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; + + if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) + return -EFAULT; +@@ -553,21 +553,21 @@ static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + static void reset_wvr(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd) + { +- vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg] = rd->val; ++ vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm] = rd->val; + } + + static bool trap_wcr(struct kvm_vcpu *vcpu, + struct sys_reg_params *p, + const struct sys_reg_desc *rd) + { +- u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg]; ++ u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; + + if (p->is_write) + reg_to_dbg(vcpu, p, dbg_reg); + else + dbg_to_reg(vcpu, p, dbg_reg); + +- trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); ++ trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg); + + return true; + } +@@ -575,7 +575,7 @@ static bool trap_wcr(struct kvm_vcpu *vcpu, + static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + const struct kvm_one_reg *reg, void __user *uaddr) + { +- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg]; ++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; + + if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) + return -EFAULT; +@@ -585,7 +585,7 @@ static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + const struct kvm_one_reg *reg, void __user *uaddr) + { +- __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg]; ++ __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; + + if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) + return -EFAULT; +@@ -595,7 +595,7 @@ static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + static void reset_wcr(struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd) + { +- vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg] = rd->val; ++ vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm] = rd->val; + } + + static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h +index 5bef1575708dc..a49b1aeb2147b 100644 +--- a/arch/x86/include/asm/apic.h ++++ b/arch/x86/include/asm/apic.h +@@ -174,6 +174,7 @@ static inline int apic_is_clustered_box(void) + extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask); + extern void lapic_assign_system_vectors(void); + extern void lapic_assign_legacy_vector(unsigned int isairq, bool replace); ++extern void lapic_update_legacy_vectors(void); + extern void lapic_online(void); + extern void lapic_offline(void); + extern bool apic_needs_pit(void); +diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h +index 9b4df6eaa11a6..f913f62eb6c35 100644 +--- a/arch/x86/include/asm/kvm_para.h ++++ b/arch/x86/include/asm/kvm_para.h +@@ -6,8 +6,6 @@ + #include + #include + +-extern void kvmclock_init(void); +- + #ifdef CONFIG_KVM_GUEST + bool kvm_check_and_clear_guest_paused(void); + #else +@@ -85,13 +83,14 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, + } + + #ifdef CONFIG_KVM_GUEST ++void kvmclock_init(void); ++void kvmclock_disable(void); + bool kvm_para_available(void); + unsigned int kvm_arch_para_features(void); + unsigned int kvm_arch_para_hints(void); + void kvm_async_pf_task_wait(u32 token, int interrupt_kernel); + void kvm_async_pf_task_wake(u32 token); + u32 kvm_read_and_reset_pf_reason(void); +-extern void kvm_disable_steal_time(void); + void do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address); + + #ifdef CONFIG_PARAVIRT_SPINLOCKS +@@ -125,11 +124,6 @@ static inline u32 kvm_read_and_reset_pf_reason(void) + { + return 0; + } +- +-static inline void kvm_disable_steal_time(void) +-{ +- return; +-} + #endif + + #endif /* _ASM_X86_KVM_PARA_H */ +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index 7fafa859e9f25..4e4476b832be2 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -2579,6 +2579,7 @@ static void __init apic_bsp_setup(bool upmode) + end_local_APIC_setup(); + irq_remap_enable_fault_handling(); + setup_IO_APIC(); ++ lapic_update_legacy_vectors(); + } + + #ifdef CONFIG_UP_LATE_INIT +diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c +index bf6662d37a334..6b8b6bf6c5d1c 100644 +--- a/arch/x86/kernel/apic/vector.c ++++ b/arch/x86/kernel/apic/vector.c +@@ -680,6 +680,26 @@ void lapic_assign_legacy_vector(unsigned int irq, bool replace) + irq_matrix_assign_system(vector_matrix, ISA_IRQ_VECTOR(irq), replace); + } + ++void __init lapic_update_legacy_vectors(void) ++{ ++ unsigned int i; ++ ++ if (IS_ENABLED(CONFIG_X86_IO_APIC) && nr_ioapics > 0) ++ return; ++ ++ /* ++ * If the IO/APIC is disabled via config, kernel command line or ++ * lack of enumeration then all legacy interrupts are routed ++ * through the PIC. Make sure that they are marked as legacy ++ * vectors. PIC_CASCADE_IRQ has already been marked in ++ * lapic_assign_system_vectors(). ++ */ ++ for (i = 0; i < nr_legacy_irqs(); i++) { ++ if (i != PIC_CASCADE_IR) ++ lapic_assign_legacy_vector(i, true); ++ } ++} ++ + void __init lapic_assign_system_vectors(void) + { + unsigned int i, vector = 0; +diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c +index e820568ed4d5c..6ff2c7cac4c46 100644 +--- a/arch/x86/kernel/kvm.c ++++ b/arch/x86/kernel/kvm.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -33,6 +34,7 @@ + #include + #include + #include ++#include + + static int kvmapf = 1; + +@@ -351,6 +353,14 @@ static void kvm_pv_disable_apf(void) + smp_processor_id()); + } + ++static void kvm_disable_steal_time(void) ++{ ++ if (!has_steal_clock) ++ return; ++ ++ wrmsr(MSR_KVM_STEAL_TIME, 0, 0); ++} ++ + static void kvm_pv_guest_cpu_reboot(void *unused) + { + /* +@@ -393,14 +403,6 @@ static u64 kvm_steal_clock(int cpu) + return steal; + } + +-void kvm_disable_steal_time(void) +-{ +- if (!has_steal_clock) +- return; +- +- wrmsr(MSR_KVM_STEAL_TIME, 0, 0); +-} +- + static inline void __set_percpu_decrypted(void *ptr, unsigned long size) + { + early_set_memory_decrypted((unsigned long) ptr, size); +@@ -428,6 +430,27 @@ static void __init sev_map_percpu_data(void) + } + } + ++static void kvm_guest_cpu_offline(bool shutdown) ++{ ++ kvm_disable_steal_time(); ++ if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) ++ wrmsrl(MSR_KVM_PV_EOI_EN, 0); ++ kvm_pv_disable_apf(); ++ if (!shutdown) ++ apf_task_wake_all(); ++ kvmclock_disable(); ++} ++ ++static int kvm_cpu_online(unsigned int cpu) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ kvm_guest_cpu_init(); ++ local_irq_restore(flags); ++ return 0; ++} ++ + #ifdef CONFIG_SMP + #define KVM_IPI_CLUSTER_SIZE (2 * BITS_PER_LONG) + +@@ -547,29 +570,46 @@ static void __init kvm_smp_prepare_boot_cpu(void) + kvm_spinlock_init(); + } + +-static void kvm_guest_cpu_offline(void) ++static int kvm_cpu_down_prepare(unsigned int cpu) + { +- kvm_disable_steal_time(); +- if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) +- wrmsrl(MSR_KVM_PV_EOI_EN, 0); +- kvm_pv_disable_apf(); +- apf_task_wake_all(); ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ kvm_guest_cpu_offline(false); ++ local_irq_restore(flags); ++ return 0; + } + +-static int kvm_cpu_online(unsigned int cpu) ++#endif ++ ++static int kvm_suspend(void) + { +- local_irq_disable(); +- kvm_guest_cpu_init(); +- local_irq_enable(); ++ kvm_guest_cpu_offline(false); ++ + return 0; + } + +-static int kvm_cpu_down_prepare(unsigned int cpu) ++static void kvm_resume(void) + { +- local_irq_disable(); +- kvm_guest_cpu_offline(); +- local_irq_enable(); +- return 0; ++ kvm_cpu_online(raw_smp_processor_id()); ++} ++ ++static struct syscore_ops kvm_syscore_ops = { ++ .suspend = kvm_suspend, ++ .resume = kvm_resume, ++}; ++ ++/* ++ * After a PV feature is registered, the host will keep writing to the ++ * registered memory location. If the guest happens to shutdown, this memory ++ * won't be valid. In cases like kexec, in which you install a new kernel, this ++ * means a random memory location will be kept being written. ++ */ ++#ifdef CONFIG_KEXEC_CORE ++static void kvm_crash_shutdown(struct pt_regs *regs) ++{ ++ kvm_guest_cpu_offline(true); ++ native_machine_crash_shutdown(regs); + } + #endif + +@@ -649,6 +689,12 @@ static void __init kvm_guest_init(void) + kvm_guest_cpu_init(); + #endif + ++#ifdef CONFIG_KEXEC_CORE ++ machine_ops.crash_shutdown = kvm_crash_shutdown; ++#endif ++ ++ register_syscore_ops(&kvm_syscore_ops); ++ + /* + * Hard lockup detection is enabled by default. Disable it, as guests + * can get false positives too easily, for example if the host is +diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c +index 904494b924c13..4a0802af2e3e0 100644 +--- a/arch/x86/kernel/kvmclock.c ++++ b/arch/x86/kernel/kvmclock.c +@@ -20,7 +20,6 @@ + #include + #include + #include +-#include + #include + + static int kvmclock __initdata = 1; +@@ -197,28 +196,9 @@ static void kvm_setup_secondary_clock(void) + } + #endif + +-/* +- * After the clock is registered, the host will keep writing to the +- * registered memory location. If the guest happens to shutdown, this memory +- * won't be valid. In cases like kexec, in which you install a new kernel, this +- * means a random memory location will be kept being written. So before any +- * kind of shutdown from our side, we unregister the clock by writing anything +- * that does not have the 'enable' bit set in the msr +- */ +-#ifdef CONFIG_KEXEC_CORE +-static void kvm_crash_shutdown(struct pt_regs *regs) +-{ +- native_write_msr(msr_kvm_system_time, 0, 0); +- kvm_disable_steal_time(); +- native_machine_crash_shutdown(regs); +-} +-#endif +- +-static void kvm_shutdown(void) ++void kvmclock_disable(void) + { + native_write_msr(msr_kvm_system_time, 0, 0); +- kvm_disable_steal_time(); +- native_machine_shutdown(); + } + + static void __init kvmclock_init_mem(void) +@@ -346,10 +326,6 @@ void __init kvmclock_init(void) + #endif + x86_platform.save_sched_clock_state = kvm_save_sched_clock_state; + x86_platform.restore_sched_clock_state = kvm_restore_sched_clock_state; +- machine_ops.shutdown = kvm_shutdown; +-#ifdef CONFIG_KEXEC_CORE +- machine_ops.crash_shutdown = kvm_crash_shutdown; +-#endif + kvm_get_preset_lpj(); + + /* +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index b9d14fdbd2d81..074cd170912aa 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -4057,7 +4057,7 @@ static int cr_interception(struct vcpu_svm *svm) + err = 0; + if (cr >= 16) { /* mov to cr */ + cr -= 16; +- val = kvm_register_read(&svm->vcpu, reg); ++ val = kvm_register_readl(&svm->vcpu, reg); + switch (cr) { + case 0: + if (!check_selective_cr0_intercepted(svm, val)) +@@ -4102,7 +4102,7 @@ static int cr_interception(struct vcpu_svm *svm) + kvm_queue_exception(&svm->vcpu, UD_VECTOR); + return 1; + } +- kvm_register_write(&svm->vcpu, reg, val); ++ kvm_register_writel(&svm->vcpu, reg, val); + } + return kvm_complete_insn_gp(&svm->vcpu, err); + } +@@ -4132,13 +4132,13 @@ static int dr_interception(struct vcpu_svm *svm) + if (dr >= 16) { /* mov to DRn */ + if (!kvm_require_dr(&svm->vcpu, dr - 16)) + return 1; +- val = kvm_register_read(&svm->vcpu, reg); ++ val = kvm_register_readl(&svm->vcpu, reg); + kvm_set_dr(&svm->vcpu, dr - 16, val); + } else { + if (!kvm_require_dr(&svm->vcpu, dr)) + return 1; + kvm_get_dr(&svm->vcpu, dr, &val); +- kvm_register_write(&svm->vcpu, reg, val); ++ kvm_register_writel(&svm->vcpu, reg, val); + } + + return kvm_skip_emulated_instruction(&svm->vcpu); +diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c +index 4c0d4e4341961..72d2c0b656339 100644 +--- a/drivers/acpi/acpica/utdelete.c ++++ b/drivers/acpi/acpica/utdelete.c +@@ -285,6 +285,14 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) + } + break; + ++ case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: ++ ++ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, ++ "***** Address handler %p\n", object)); ++ ++ acpi_os_delete_mutex(object->address_space.context_mutex); ++ break; ++ + default: + + break; +diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c +index d59e1ca9990b6..90053c4a8290d 100644 +--- a/drivers/bus/ti-sysc.c ++++ b/drivers/bus/ti-sysc.c +@@ -1376,9 +1376,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { + SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + /* Uarts on omap4 and later */ + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, +- SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), ++ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, +- SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), ++ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + + /* Quirks that need to be set based on the module address */ + SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, +diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c +index b1af0de2e1008..e48298687b76d 100644 +--- a/drivers/firmware/efi/cper.c ++++ b/drivers/firmware/efi/cper.c +@@ -263,8 +263,7 @@ static int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg) + if (!msg || !(mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE)) + return 0; + +- n = 0; +- len = CPER_REC_LEN - 1; ++ len = CPER_REC_LEN; + dmi_memdev_name(mem->mem_dev_handle, &bank, &device); + if (bank && device) + n = snprintf(msg, len, "DIMM location: %s %s ", bank, device); +@@ -273,7 +272,6 @@ static int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg) + "DIMM location: not present. DMI handle: 0x%.4x ", + mem->mem_dev_handle); + +- msg[n] = '\0'; + return n; + } + +diff --git a/drivers/firmware/efi/memattr.c b/drivers/firmware/efi/memattr.c +index 58452fde92cc0..5d343dc8e5354 100644 +--- a/drivers/firmware/efi/memattr.c ++++ b/drivers/firmware/efi/memattr.c +@@ -66,11 +66,6 @@ static bool entry_is_valid(const efi_memory_desc_t *in, efi_memory_desc_t *out) + return false; + } + +- if (!(in->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP))) { +- pr_warn("Entry attributes invalid: RO and XP bits both cleared\n"); +- return false; +- } +- + if (PAGE_SIZE > EFI_PAGE_SIZE && + (!PAGE_ALIGNED(in->phys_addr) || + !PAGE_ALIGNED(in->num_pages << EFI_PAGE_SHIFT))) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +index 2cdaf3b2a7217..39ca0718ced0c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +@@ -351,7 +351,6 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev, + { + struct amdgpu_ctx *ctx; + struct amdgpu_ctx_mgr *mgr; +- unsigned long ras_counter; + + if (!fpriv) + return -EINVAL; +@@ -376,21 +375,6 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev, + if (atomic_read(&ctx->guilty)) + out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY; + +- /*query ue count*/ +- ras_counter = amdgpu_ras_query_error_count(adev, false); +- /*ras counter is monotonic increasing*/ +- if (ras_counter != ctx->ras_counter_ue) { +- out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_UE; +- ctx->ras_counter_ue = ras_counter; +- } +- +- /*query ce count*/ +- ras_counter = amdgpu_ras_query_error_count(adev, true); +- if (ras_counter != ctx->ras_counter_ce) { +- out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_CE; +- ctx->ras_counter_ce = ras_counter; +- } +- + mutex_unlock(&mgr->lock); + return 0; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +index 217084d56ab8c..9deef20a02699 100644 +--- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +@@ -354,6 +354,7 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) + + error: + dma_fence_put(fence); ++ amdgpu_bo_unpin(bo); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); + return r; +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index abd86903875f0..fc4c074597539 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -597,7 +597,7 @@ static int magicmouse_probe(struct hid_device *hdev, + if (id->vendor == USB_VENDOR_ID_APPLE && + id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && + hdev->type != HID_TYPE_USBMOUSE) +- return 0; ++ return -ENODEV; + + msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); + if (msc == NULL) { +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index d91e6679afb18..f290ba856323a 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -611,9 +611,13 @@ static struct mt_report_data *mt_allocate_report_data(struct mt_device *td, + if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) + continue; + +- for (n = 0; n < field->report_count; n++) { +- if (field->usage[n].hid == HID_DG_CONTACTID) +- rdata->is_mt_collection = true; ++ if (field->logical == HID_DG_FINGER || td->hdev->group != HID_GROUP_MULTITOUCH_WIN_8) { ++ for (n = 0; n < field->report_count; n++) { ++ if (field->usage[n].hid == HID_DG_CONTACTID) { ++ rdata->is_mt_collection = true; ++ break; ++ } ++ } + } + } + +diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c +index 96898983db990..6f7a3702b5fba 100644 +--- a/drivers/hid/i2c-hid/i2c-hid-core.c ++++ b/drivers/hid/i2c-hid/i2c-hid-core.c +@@ -50,6 +50,7 @@ + #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) + #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) + #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6) ++#define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(7) + + + /* flags */ +@@ -185,6 +186,11 @@ static const struct i2c_hid_quirks { + I2C_HID_QUIRK_RESET_ON_RESUME }, + { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720, + I2C_HID_QUIRK_BAD_INPUT_SIZE }, ++ /* ++ * Sending the wakeup after reset actually break ELAN touchscreen controller ++ */ ++ { USB_VENDOR_ID_ELAN, HID_ANY_ID, ++ I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET }, + { 0, 0 } + }; + +@@ -468,7 +474,8 @@ static int i2c_hid_hwreset(struct i2c_client *client) + } + + /* At least some SIS devices need this after reset */ +- ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); ++ if (!(ihid->quirks & I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET)) ++ ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); + + out_unlock: + mutex_unlock(&ihid->reset_lock); +@@ -1114,8 +1121,8 @@ static int i2c_hid_probe(struct i2c_client *client, + hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); + hid->product = le16_to_cpu(ihid->hdesc.wProductID); + +- snprintf(hid->name, sizeof(hid->name), "%s %04hX:%04hX", +- client->name, hid->vendor, hid->product); ++ snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", ++ client->name, (u16)hid->vendor, (u16)hid->product); + strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys)); + + ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); +diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c +index fddac7c72f645..07a9fe97d2e05 100644 +--- a/drivers/hid/usbhid/hid-pidff.c ++++ b/drivers/hid/usbhid/hid-pidff.c +@@ -1292,6 +1292,7 @@ int hid_pidff_init(struct hid_device *hid) + + if (pidff->pool[PID_DEVICE_MANAGED_POOL].value && + pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) { ++ error = -EPERM; + hid_notice(hid, + "device does not support device managed pool\n"); + goto fail; +diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c +index 4212d022d2534..35c00420d855b 100644 +--- a/drivers/hwmon/dell-smm-hwmon.c ++++ b/drivers/hwmon/dell-smm-hwmon.c +@@ -792,10 +792,10 @@ static struct attribute *i8k_attrs[] = { + static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, + int index) + { +- if (disallow_fan_support && index >= 8) ++ if (disallow_fan_support && index >= 20) + return 0; + if (disallow_fan_type_call && +- (index == 9 || index == 12 || index == 15)) ++ (index == 21 || index == 25 || index == 28)) + return 0; + if (index >= 0 && index <= 1 && + !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1)) +diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c +index b56a427fb928f..c73b997899af8 100644 +--- a/drivers/i2c/busses/i2c-qcom-geni.c ++++ b/drivers/i2c/busses/i2c-qcom-geni.c +@@ -641,6 +641,14 @@ static int geni_i2c_remove(struct platform_device *pdev) + return 0; + } + ++static void geni_i2c_shutdown(struct platform_device *pdev) ++{ ++ struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev); ++ ++ /* Make client i2c transfers start failing */ ++ i2c_mark_adapter_suspended(&gi2c->adap); ++} ++ + static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev) + { + int ret; +@@ -677,6 +685,8 @@ static int __maybe_unused geni_i2c_suspend_noirq(struct device *dev) + { + struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); + ++ i2c_mark_adapter_suspended(&gi2c->adap); ++ + if (!gi2c->suspended) { + geni_i2c_runtime_suspend(dev); + pm_runtime_disable(dev); +@@ -686,8 +696,16 @@ static int __maybe_unused geni_i2c_suspend_noirq(struct device *dev) + return 0; + } + ++static int __maybe_unused geni_i2c_resume_noirq(struct device *dev) ++{ ++ struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); ++ ++ i2c_mark_adapter_resumed(&gi2c->adap); ++ return 0; ++} ++ + static const struct dev_pm_ops geni_i2c_pm_ops = { +- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(geni_i2c_suspend_noirq, NULL) ++ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(geni_i2c_suspend_noirq, geni_i2c_resume_noirq) + SET_RUNTIME_PM_OPS(geni_i2c_runtime_suspend, geni_i2c_runtime_resume, + NULL) + }; +@@ -701,6 +719,7 @@ MODULE_DEVICE_TABLE(of, geni_i2c_dt_match); + static struct platform_driver geni_i2c_driver = { + .probe = geni_i2c_probe, + .remove = geni_i2c_remove, ++ .shutdown = geni_i2c_shutdown, + .driver = { + .name = "geni_i2c", + .pm = &geni_i2c_pm_ops, +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 0dba28bb309a2..00ae7a9a42bfe 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -7003,7 +7003,6 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) + + pf->fw_fid = le16_to_cpu(resp->fid); + pf->port_id = le16_to_cpu(resp->port_id); +- bp->dev->dev_port = pf->port_id; + memcpy(pf->mac_addr, resp->mac_address, ETH_ALEN); + pf->first_vf_id = le16_to_cpu(resp->first_vf_id); + pf->max_vfs = le16_to_cpu(resp->max_vfs); +diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c +index 218aada8949d9..68a2fcf4c0bf5 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c +@@ -2233,15 +2233,20 @@ static struct sk_buff *i40e_run_xdp(struct i40e_ring *rx_ring, + case XDP_TX: + xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->queue_index]; + result = i40e_xmit_xdp_tx_ring(xdp, xdp_ring); ++ if (result == I40E_XDP_CONSUMED) ++ goto out_failure; + break; + case XDP_REDIRECT: + err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); +- result = !err ? I40E_XDP_REDIR : I40E_XDP_CONSUMED; ++ if (err) ++ goto out_failure; ++ result = I40E_XDP_REDIR; + break; + default: + bpf_warn_invalid_xdp_action(act); + /* fall through */ + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + /* fall through -- handle aborts by dropping packet */ + case XDP_DROP: +diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c b/drivers/net/ethernet/intel/i40e/i40e_xsk.c +index c9d4534fbdf02..a9ad788c4913d 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c +@@ -212,21 +212,28 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp) + + xdp->handle = xsk_umem_adjust_offset(umem, xdp->handle, offset); + ++ if (likely(act == XDP_REDIRECT)) { ++ err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); ++ if (err) ++ goto out_failure; ++ rcu_read_unlock(); ++ return I40E_XDP_REDIR; ++ } ++ + switch (act) { + case XDP_PASS: + break; + case XDP_TX: + xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->queue_index]; + result = i40e_xmit_xdp_tx_ring(xdp, xdp_ring); +- break; +- case XDP_REDIRECT: +- err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); +- result = !err ? I40E_XDP_REDIR : I40E_XDP_CONSUMED; ++ if (result == I40E_XDP_CONSUMED) ++ goto out_failure; + break; + default: + bpf_warn_invalid_xdp_action(act); + /* fall through */ + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + /* fallthrough -- handle aborts by dropping packet */ + case XDP_DROP: +diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +index 9138b19de87e0..f2bb83af4d9e8 100644 +--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h ++++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +@@ -34,6 +34,7 @@ + #define PF_FW_ATQLEN_ATQOVFL_M BIT(29) + #define PF_FW_ATQLEN_ATQCRIT_M BIT(30) + #define VF_MBX_ARQLEN(_VF) (0x0022BC00 + ((_VF) * 4)) ++#define VF_MBX_ATQLEN(_VF) (0x0022A800 + ((_VF) * 4)) + #define PF_FW_ATQLEN_ATQENABLE_M BIT(31) + #define PF_FW_ATQT 0x00080400 + #define PF_MBX_ARQBAH 0x0022E400 +diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c +index 33dd103035dcd..2b55efe5ed963 100644 +--- a/drivers/net/ethernet/intel/ice/ice_txrx.c ++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c +@@ -2109,6 +2109,7 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring) + struct ice_tx_offload_params offload = { 0 }; + struct ice_vsi *vsi = tx_ring->vsi; + struct ice_tx_buf *first; ++ struct ethhdr *eth; + unsigned int count; + int tso, csum; + +@@ -2156,7 +2157,9 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring) + goto out_drop; + + /* allow CONTROL frames egress from main VSI if FW LLDP disabled */ +- if (unlikely(skb->priority == TC_PRIO_CONTROL && ++ eth = (struct ethhdr *)skb_mac_header(skb); ++ if (unlikely((skb->priority == TC_PRIO_CONTROL || ++ eth->h_proto == htons(ETH_P_LLDP)) && + vsi->type == ICE_VSI_PF && + vsi->port_info->is_sw_lldp)) + offload.cd_qw1 |= (u64)(ICE_TX_DESC_DTYPE_CTX | +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +index e92a00a617556..5e97fdca5fab2 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +@@ -384,13 +384,15 @@ static void ice_trigger_vf_reset(struct ice_vf *vf, bool is_vflr, bool is_pfr) + */ + clear_bit(ICE_VF_STATE_INIT, vf->vf_states); + +- /* VF_MBX_ARQLEN is cleared by PFR, so the driver needs to clear it +- * in the case of VFR. If this is done for PFR, it can mess up VF +- * resets because the VF driver may already have started cleanup +- * by the time we get here. ++ /* VF_MBX_ARQLEN and VF_MBX_ATQLEN are cleared by PFR, so the driver ++ * needs to clear them in the case of VFR/VFLR. If this is done for ++ * PFR, it can mess up VF resets because the VF driver may already ++ * have started cleanup by the time we get here. + */ +- if (!is_pfr) +- wr32(hw, VF_MBX_ARQLEN(vf_abs_id), 0); ++ if (!is_pfr) { ++ wr32(hw, VF_MBX_ARQLEN(vf->vf_id), 0); ++ wr32(hw, VF_MBX_ATQLEN(vf->vf_id), 0); ++ } + + /* In the case of a VFLR, the HW has already reset the VF and we + * just need to clean up, so don't hit the VFRTRIG register. +diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +index 64ec0e7c64b49..be8e6d4e376ec 100644 +--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c ++++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +@@ -1079,11 +1079,14 @@ static struct sk_buff *ixgbevf_run_xdp(struct ixgbevf_adapter *adapter, + case XDP_TX: + xdp_ring = adapter->xdp_ring[rx_ring->queue_index]; + result = ixgbevf_xmit_xdp_ring(xdp_ring, xdp); ++ if (result == IXGBEVF_XDP_CONSUMED) ++ goto out_failure; + break; + default: + bpf_warn_invalid_xdp_action(act); + /* fallthrough */ + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + /* fallthrough -- handle aborts by dropping packet */ + case XDP_DROP: +diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c +index cbe7f35eac982..0646bcd269682 100644 +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -1589,6 +1589,15 @@ cdc_ncm_speed_change(struct usbnet *dev, + uint32_t rx_speed = le32_to_cpu(data->DLBitRRate); + uint32_t tx_speed = le32_to_cpu(data->ULBitRate); + ++ /* if the speed hasn't changed, don't report it. ++ * RTL8156 shipped before 2021 sends notification about every 32ms. ++ */ ++ if (dev->rx_speed == rx_speed && dev->tx_speed == tx_speed) ++ return; ++ ++ dev->rx_speed = rx_speed; ++ dev->tx_speed = tx_speed; ++ + /* + * Currently the USB-NET API does not support reporting the actual + * device speed. Do print it instead. +@@ -1629,7 +1638,8 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) + * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be + * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. + */ +- usbnet_link_change(dev, !!event->wValue, 0); ++ if (netif_carrier_ok(dev->net) != !!event->wValue) ++ usbnet_link_change(dev, !!event->wValue, 0); + break; + + case USB_CDC_NOTIFY_SPEED_CHANGE: +diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c +index 9da27ec22d588..44d74584c7275 100644 +--- a/drivers/usb/dwc2/core_intr.c ++++ b/drivers/usb/dwc2/core_intr.c +@@ -712,7 +712,11 @@ static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg, + dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); + + hsotg->hibernated = 0; ++ ++#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || \ ++ IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) + hsotg->bus_suspended = 0; ++#endif + + if (gpwrdn & GPWRDN_IDSTS) { + hsotg->op_state = OTG_STATE_B_PERIPHERAL; +diff --git a/drivers/vfio/pci/Kconfig b/drivers/vfio/pci/Kconfig +index 4abddbebd4b23..c691127bc805a 100644 +--- a/drivers/vfio/pci/Kconfig ++++ b/drivers/vfio/pci/Kconfig +@@ -2,6 +2,7 @@ + config VFIO_PCI + tristate "VFIO support for PCI devices" + depends on VFIO && PCI && EVENTFD ++ depends on MMU + select VFIO_VIRQFD + select IRQ_BYPASS_MANAGER + help +diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c +index bf32997c557ff..50cd17fcf7541 100644 +--- a/drivers/vfio/pci/vfio_pci_config.c ++++ b/drivers/vfio/pci/vfio_pci_config.c +@@ -1576,7 +1576,7 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev) + if (len == 0xFF) { + len = vfio_ext_cap_len(vdev, ecap, epos); + if (len < 0) +- return ret; ++ return len; + } + } + +diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c +index 152e5188183ce..6f727034679f1 100644 +--- a/drivers/vfio/platform/vfio_platform_common.c ++++ b/drivers/vfio/platform/vfio_platform_common.c +@@ -289,7 +289,7 @@ err_irq: + vfio_platform_regions_cleanup(vdev); + err_reg: + mutex_unlock(&driver_lock); +- module_put(THIS_MODULE); ++ module_put(vdev->parent_module); + return ret; + } + +diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c +index f6ba18191c0f9..30313084f06c1 100644 +--- a/drivers/xen/xen-pciback/vpci.c ++++ b/drivers/xen/xen-pciback/vpci.c +@@ -69,7 +69,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, + struct pci_dev *dev, int devid, + publish_pci_dev_cb publish_cb) + { +- int err = 0, slot, func = -1; ++ int err = 0, slot, func = PCI_FUNC(dev->devfn); + struct pci_dev_entry *t, *dev_entry; + struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; + +@@ -94,23 +94,26 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, + + /* + * Keep multi-function devices together on the virtual PCI bus, except +- * virtual functions. ++ * that we want to keep virtual functions at func 0 on their own. They ++ * aren't multi-function devices and hence their presence at func 0 ++ * may cause guests to not scan the other functions. + */ +- if (!dev->is_virtfn) { ++ if (!dev->is_virtfn || func) { + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { + if (list_empty(&vpci_dev->dev_list[slot])) + continue; + + t = list_entry(list_first(&vpci_dev->dev_list[slot]), + struct pci_dev_entry, list); ++ if (t->dev->is_virtfn && !PCI_FUNC(t->dev->devfn)) ++ continue; + + if (match_slot(dev, t->dev)) { + pr_info("vpci: %s: assign to virtual slot %d func %d\n", + pci_name(dev), slot, +- PCI_FUNC(dev->devfn)); ++ func); + list_add_tail(&dev_entry->list, + &vpci_dev->dev_list[slot]); +- func = PCI_FUNC(dev->devfn); + goto unlock; + } + } +@@ -123,7 +126,6 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, + pci_name(dev), slot); + list_add_tail(&dev_entry->list, + &vpci_dev->dev_list[slot]); +- func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn); + goto unlock; + } + } +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 6317394f02b86..832b40293907f 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -1338,16 +1338,20 @@ int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr, + for (i = 0; i < bbio->num_stripes; i++, stripe++) { + u64 bytes; + struct request_queue *req_q; ++ struct btrfs_device *device = stripe->dev; + +- if (!stripe->dev->bdev) { ++ if (!device->bdev) { + ASSERT(btrfs_test_opt(fs_info, DEGRADED)); + continue; + } +- req_q = bdev_get_queue(stripe->dev->bdev); ++ req_q = bdev_get_queue(device->bdev); + if (!blk_queue_discard(req_q)) + continue; + +- ret = btrfs_issue_discard(stripe->dev->bdev, ++ if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) ++ continue; ++ ++ ret = btrfs_issue_discard(device->bdev, + stripe->physical, + stripe->length, + &bytes); +@@ -1879,7 +1883,7 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans, + trace_run_delayed_ref_head(fs_info, head, 0); + btrfs_delayed_ref_unlock(head); + btrfs_put_delayed_ref_head(head); +- return 0; ++ return ret; + } + + static struct btrfs_delayed_ref_head *btrfs_obtain_ref_head( +diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c +index 2b8f29c07668b..61b82c69eed50 100644 +--- a/fs/btrfs/file-item.c ++++ b/fs/btrfs/file-item.c +@@ -599,7 +599,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + u64 end_byte = bytenr + len; + u64 csum_end; + struct extent_buffer *leaf; +- int ret; ++ int ret = 0; + u16 csum_size = btrfs_super_csum_size(fs_info->super_copy); + int blocksize_bits = fs_info->sb->s_blocksize_bits; + +@@ -618,6 +618,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + path->leave_spinning = 1; + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); + if (ret > 0) { ++ ret = 0; + if (path->slots[0] == 0) + break; + path->slots[0]--; +@@ -674,7 +675,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + ret = btrfs_del_items(trans, root, path, + path->slots[0], del_nr); + if (ret) +- goto out; ++ break; + if (key.offset == bytenr) + break; + } else if (key.offset < bytenr && csum_end > end_byte) { +@@ -718,8 +719,9 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + ret = btrfs_split_item(trans, root, path, &key, offset); + if (ret && ret != -EAGAIN) { + btrfs_abort_transaction(trans, ret); +- goto out; ++ break; + } ++ ret = 0; + + key.offset = end_byte - 1; + } else { +@@ -729,8 +731,6 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + } + btrfs_release_path(path); + } +- ret = 0; +-out: + btrfs_free_path(path); + return ret; + } +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 8ea9559c1919a..64dd702a5448c 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -3359,6 +3359,18 @@ out: + if (ret || truncated) { + u64 start, end; + ++ /* ++ * If we failed to finish this ordered extent for any reason we ++ * need to make sure BTRFS_ORDERED_IOERR is set on the ordered ++ * extent, and mark the inode with the error if it wasn't ++ * already set. Any error during writeback would have already ++ * set the mapping error, so we need to set it if we're the ones ++ * marking this ordered extent as failed. ++ */ ++ if (ret && !test_and_set_bit(BTRFS_ORDERED_IOERR, ++ &ordered_extent->flags)) ++ mapping_set_error(ordered_extent->inode->i_mapping, -EIO); ++ + if (truncated) + start = ordered_extent->file_offset + logical_len; + else +diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c +index 7d06842a3d747..368c43c6cbd08 100644 +--- a/fs/btrfs/tree-checker.c ++++ b/fs/btrfs/tree-checker.c +@@ -1285,22 +1285,14 @@ static int check_extent_data_ref(struct extent_buffer *leaf, + return -EUCLEAN; + } + for (; ptr < end; ptr += sizeof(*dref)) { +- u64 root_objectid; +- u64 owner; + u64 offset; +- u64 hash; + ++ /* ++ * We cannot check the extent_data_ref hash due to possible ++ * overflow from the leaf due to hash collisions. ++ */ + dref = (struct btrfs_extent_data_ref *)ptr; +- root_objectid = btrfs_extent_data_ref_root(leaf, dref); +- owner = btrfs_extent_data_ref_objectid(leaf, dref); + offset = btrfs_extent_data_ref_offset(leaf, dref); +- hash = hash_extent_data_ref(root_objectid, owner, offset); +- if (hash != key->offset) { +- extent_err(leaf, slot, +- "invalid extent data ref hash, item has 0x%016llx key has 0x%016llx", +- hash, key->offset); +- return -EUCLEAN; +- } + if (!IS_ALIGNED(offset, leaf->fs_info->sectorsize)) { + extent_err(leaf, slot, + "invalid extent data backref offset, have %llu expect aligned to %u", +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index 54647eb9c6ed2..4ff381c23cefc 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -1775,6 +1775,7 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + break; + + if (ret == 1) { ++ ret = 0; + if (path->slots[0] == 0) + break; + path->slots[0]--; +@@ -1787,17 +1788,19 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + + ret = btrfs_del_item(trans, root, path); + if (ret) +- goto out; ++ break; + + btrfs_release_path(path); + inode = read_one_inode(root, key.offset); +- if (!inode) +- return -EIO; ++ if (!inode) { ++ ret = -EIO; ++ break; ++ } + + ret = fixup_inode_link_count(trans, root, inode); + iput(inode); + if (ret) +- goto out; ++ break; + + /* + * fixup on a directory may create new entries, +@@ -1806,8 +1809,6 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + */ + key.offset = (u64)-1; + } +- ret = 0; +-out: + btrfs_release_path(path); + return ret; + } +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 3193f0b4a02d6..dbd0d7a101541 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -3378,7 +3378,10 @@ static int ext4_split_extent_at(handle_t *handle, + ext4_ext_mark_unwritten(ex2); + + err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags); +- if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { ++ if (err != -ENOSPC && err != -EDQUOT) ++ goto out; ++ ++ if (EXT4_EXT_MAY_ZEROOUT & split_flag) { + if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { + if (split_flag & EXT4_EXT_DATA_VALID1) { + err = ext4_ext_zeroout(inode, ex2); +@@ -3404,30 +3407,30 @@ static int ext4_split_extent_at(handle_t *handle, + ext4_ext_pblock(&orig_ex)); + } + +- if (err) +- goto fix_extent_len; +- /* update the extent length and mark as initialized */ +- ex->ee_len = cpu_to_le16(ee_len); +- ext4_ext_try_to_merge(handle, inode, path, ex); +- err = ext4_ext_dirty(handle, inode, path + path->p_depth); +- if (err) +- goto fix_extent_len; +- +- /* update extent status tree */ +- err = ext4_zeroout_es(inode, &zero_ex); +- +- goto out; +- } else if (err) +- goto fix_extent_len; +- +-out: +- ext4_ext_show_leaf(inode, path); +- return err; ++ if (!err) { ++ /* update the extent length and mark as initialized */ ++ ex->ee_len = cpu_to_le16(ee_len); ++ ext4_ext_try_to_merge(handle, inode, path, ex); ++ err = ext4_ext_dirty(handle, inode, path + path->p_depth); ++ if (!err) ++ /* update extent status tree */ ++ err = ext4_zeroout_es(inode, &zero_ex); ++ /* If we failed at this point, we don't know in which ++ * state the extent tree exactly is so don't try to fix ++ * length of the original extent as it may do even more ++ * damage. ++ */ ++ goto out; ++ } ++ } + + fix_extent_len: + ex->ee_len = orig_ex.ee_len; + ext4_ext_dirty(handle, inode, path + path->p_depth); + return err; ++out: ++ ext4_ext_show_leaf(inode, path); ++ return err; + } + + /* +diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c +index ab2b0d74ad03e..c2852d7cc14d4 100644 +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -1855,6 +1855,45 @@ out: + return ret; + } + ++/* ++ * zero out partial blocks of one cluster. ++ * ++ * start: file offset where zero starts, will be made upper block aligned. ++ * len: it will be trimmed to the end of current cluster if "start + len" ++ * is bigger than it. ++ */ ++static int ocfs2_zeroout_partial_cluster(struct inode *inode, ++ u64 start, u64 len) ++{ ++ int ret; ++ u64 start_block, end_block, nr_blocks; ++ u64 p_block, offset; ++ u32 cluster, p_cluster, nr_clusters; ++ struct super_block *sb = inode->i_sb; ++ u64 end = ocfs2_align_bytes_to_clusters(sb, start); ++ ++ if (start + len < end) ++ end = start + len; ++ ++ start_block = ocfs2_blocks_for_bytes(sb, start); ++ end_block = ocfs2_blocks_for_bytes(sb, end); ++ nr_blocks = end_block - start_block; ++ if (!nr_blocks) ++ return 0; ++ ++ cluster = ocfs2_bytes_to_clusters(sb, start); ++ ret = ocfs2_get_clusters(inode, cluster, &p_cluster, ++ &nr_clusters, NULL); ++ if (ret) ++ return ret; ++ if (!p_cluster) ++ return 0; ++ ++ offset = start_block - ocfs2_clusters_to_blocks(sb, cluster); ++ p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset; ++ return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS); ++} ++ + /* + * Parts of this function taken from xfs_change_file_space() + */ +@@ -1865,7 +1904,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + { + int ret; + s64 llen; +- loff_t size; ++ loff_t size, orig_isize; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + struct buffer_head *di_bh = NULL; + handle_t *handle; +@@ -1896,6 +1935,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + goto out_inode_unlock; + } + ++ orig_isize = i_size_read(inode); + switch (sr->l_whence) { + case 0: /*SEEK_SET*/ + break; +@@ -1903,7 +1943,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + sr->l_start += f_pos; + break; + case 2: /*SEEK_END*/ +- sr->l_start += i_size_read(inode); ++ sr->l_start += orig_isize; + break; + default: + ret = -EINVAL; +@@ -1957,6 +1997,14 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + default: + ret = -EINVAL; + } ++ ++ /* zeroout eof blocks in the cluster. */ ++ if (!ret && change_size && orig_isize < size) { ++ ret = ocfs2_zeroout_partial_cluster(inode, orig_isize, ++ size - orig_isize); ++ if (!ret) ++ i_size_write(inode, size); ++ } + up_write(&OCFS2_I(inode)->ip_alloc_sem); + if (ret) { + mlog_errno(ret); +@@ -1973,9 +2021,6 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + goto out_inode_unlock; + } + +- if (change_size && i_size_read(inode) < size) +- i_size_write(inode, size); +- + inode->i_ctime = inode->i_mtime = current_time(inode); + ret = ocfs2_mark_inode_dirty(handle, inode, di_bh); + if (ret < 0) +diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h +index 93d5cf0bc7168..d8b86fd391134 100644 +--- a/include/linux/huge_mm.h ++++ b/include/linux/huge_mm.h +@@ -231,6 +231,19 @@ static inline spinlock_t *pud_trans_huge_lock(pud_t *pud, + else + return NULL; + } ++ ++/** ++ * thp_order - Order of a transparent huge page. ++ * @page: Head page of a transparent huge page. ++ */ ++static inline unsigned int thp_order(struct page *page) ++{ ++ VM_BUG_ON_PGFLAGS(PageTail(page), page); ++ if (PageHead(page)) ++ return HPAGE_PMD_ORDER; ++ return 0; ++} ++ + static inline int hpage_nr_pages(struct page *page) + { + if (unlikely(PageTransHuge(page))) +@@ -290,6 +303,12 @@ static inline struct list_head *page_deferred_list(struct page *page) + #define HPAGE_PUD_MASK ({ BUILD_BUG(); 0; }) + #define HPAGE_PUD_SIZE ({ BUILD_BUG(); 0; }) + ++static inline unsigned int thp_order(struct page *page) ++{ ++ VM_BUG_ON_PGFLAGS(PageTail(page), page); ++ return 0; ++} ++ + #define hpage_nr_pages(x) 1 + + static inline bool __transparent_hugepage_enabled(struct vm_area_struct *vma) +diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h +index d8860f2d0976d..fc6ed1311589c 100644 +--- a/include/linux/usb/usbnet.h ++++ b/include/linux/usb/usbnet.h +@@ -83,6 +83,8 @@ struct usbnet { + # define EVENT_LINK_CHANGE 11 + # define EVENT_SET_RX_MODE 12 + # define EVENT_NO_IP_ALIGN 13 ++ u32 rx_speed; /* in bps - NOT Mbps */ ++ u32 tx_speed; /* in bps - NOT Mbps */ + }; + + static inline struct usb_driver *driver_of(struct usb_interface *intf) +diff --git a/include/linux/xarray.h b/include/linux/xarray.h +index 3b257c97837db..2903f25bff5e4 100644 +--- a/include/linux/xarray.h ++++ b/include/linux/xarray.h +@@ -1470,6 +1470,28 @@ void xas_pause(struct xa_state *); + + void xas_create_range(struct xa_state *); + ++#ifdef CONFIG_XARRAY_MULTI ++int xa_get_order(struct xarray *, unsigned long index); ++void xas_split(struct xa_state *, void *entry, unsigned int order); ++void xas_split_alloc(struct xa_state *, void *entry, unsigned int order, gfp_t); ++#else ++static inline int xa_get_order(struct xarray *xa, unsigned long index) ++{ ++ return 0; ++} ++ ++static inline void xas_split(struct xa_state *xas, void *entry, ++ unsigned int order) ++{ ++ xas_store(xas, entry); ++} ++ ++static inline void xas_split_alloc(struct xa_state *xas, void *entry, ++ unsigned int order, gfp_t gfp) ++{ ++} ++#endif ++ + /** + * xas_reload() - Refetch an entry from the xarray. + * @xas: XArray operation state. +diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h +index 48ecca8530ffa..b655d8666f555 100644 +--- a/include/net/caif/caif_dev.h ++++ b/include/net/caif/caif_dev.h +@@ -119,7 +119,7 @@ void caif_free_client(struct cflayer *adap_layer); + * The link_support layer is used to add any Link Layer specific + * framing. + */ +-void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, ++int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + struct cflayer *link_support, int head_room, + struct cflayer **layer, int (**rcv_func)( + struct sk_buff *, struct net_device *, +diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h +index 2aa5e91d84576..8819ff4db35a6 100644 +--- a/include/net/caif/cfcnfg.h ++++ b/include/net/caif/cfcnfg.h +@@ -62,7 +62,7 @@ void cfcnfg_remove(struct cfcnfg *cfg); + * @fcs: Specify if checksum is used in CAIF Framing Layer. + * @head_room: Head space needed by link specific protocol. + */ +-void ++int + cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + struct net_device *dev, struct cflayer *phy_layer, + enum cfcnfg_phy_preference pref, +diff --git a/include/net/caif/cfserl.h b/include/net/caif/cfserl.h +index 14a55e03bb3ce..67cce8757175a 100644 +--- a/include/net/caif/cfserl.h ++++ b/include/net/caif/cfserl.h +@@ -9,4 +9,5 @@ + #include + + struct cflayer *cfserl_create(int instance, bool use_stx); ++void cfserl_release(struct cflayer *layer); + #endif +diff --git a/init/main.c b/init/main.c +index fef9e610b74b7..e6a1fb14f3085 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -1174,7 +1174,7 @@ static noinline void __init kernel_init_freeable(void) + */ + set_mems_allowed(node_states[N_MEMORY]); + +- cad_pid = task_pid(current); ++ cad_pid = get_pid(task_pid(current)); + + smp_prepare_cpus(setup_max_cpus); + +diff --git a/lib/lz4/lz4_decompress.c b/lib/lz4/lz4_decompress.c +index 0c9d3ad17e0fc..4d0b59fa5550f 100644 +--- a/lib/lz4/lz4_decompress.c ++++ b/lib/lz4/lz4_decompress.c +@@ -260,7 +260,11 @@ static FORCE_INLINE int LZ4_decompress_generic( + } + } + +- memcpy(op, ip, length); ++ /* ++ * supports overlapping memory regions; only matters ++ * for in-place decompression scenarios ++ */ ++ LZ4_memmove(op, ip, length); + ip += length; + op += length; + +diff --git a/lib/lz4/lz4defs.h b/lib/lz4/lz4defs.h +index 1a7fa9d9170fb..369eb181d730c 100644 +--- a/lib/lz4/lz4defs.h ++++ b/lib/lz4/lz4defs.h +@@ -137,6 +137,8 @@ static FORCE_INLINE void LZ4_writeLE16(void *memPtr, U16 value) + return put_unaligned_le16(value, memPtr); + } + ++#define LZ4_memmove(dst, src, size) __builtin_memmove(dst, src, size) ++ + static FORCE_INLINE void LZ4_copy8(void *dst, const void *src) + { + #if LZ4_ARCH64 +diff --git a/lib/test_xarray.c b/lib/test_xarray.c +index d4f97925dbd8d..8262c3f05a5d3 100644 +--- a/lib/test_xarray.c ++++ b/lib/test_xarray.c +@@ -1503,6 +1503,49 @@ static noinline void check_store_range(struct xarray *xa) + } + } + ++#ifdef CONFIG_XARRAY_MULTI ++static void check_split_1(struct xarray *xa, unsigned long index, ++ unsigned int order) ++{ ++ XA_STATE(xas, xa, index); ++ void *entry; ++ unsigned int i = 0; ++ ++ xa_store_order(xa, index, order, xa, GFP_KERNEL); ++ ++ xas_split_alloc(&xas, xa, order, GFP_KERNEL); ++ xas_lock(&xas); ++ xas_split(&xas, xa, order); ++ xas_unlock(&xas); ++ ++ xa_for_each(xa, index, entry) { ++ XA_BUG_ON(xa, entry != xa); ++ i++; ++ } ++ XA_BUG_ON(xa, i != 1 << order); ++ ++ xa_set_mark(xa, index, XA_MARK_0); ++ XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0)); ++ ++ xa_destroy(xa); ++} ++ ++static noinline void check_split(struct xarray *xa) ++{ ++ unsigned int order; ++ ++ XA_BUG_ON(xa, !xa_empty(xa)); ++ ++ for (order = 1; order < 2 * XA_CHUNK_SHIFT; order++) { ++ check_split_1(xa, 0, order); ++ check_split_1(xa, 1UL << order, order); ++ check_split_1(xa, 3UL << order, order); ++ } ++} ++#else ++static void check_split(struct xarray *xa) { } ++#endif ++ + static void check_align_1(struct xarray *xa, char *name) + { + int i; +@@ -1649,6 +1692,26 @@ static noinline void check_account(struct xarray *xa) + #endif + } + ++static noinline void check_get_order(struct xarray *xa) ++{ ++ unsigned int max_order = IS_ENABLED(CONFIG_XARRAY_MULTI) ? 20 : 1; ++ unsigned int order; ++ unsigned long i, j; ++ ++ for (i = 0; i < 3; i++) ++ XA_BUG_ON(xa, xa_get_order(xa, i) != 0); ++ ++ for (order = 0; order < max_order; order++) { ++ for (i = 0; i < 10; i++) { ++ xa_store_order(xa, i << order, order, ++ xa_mk_index(i << order), GFP_KERNEL); ++ for (j = i << order; j < (i + 1) << order; j++) ++ XA_BUG_ON(xa, xa_get_order(xa, j) != order); ++ xa_erase(xa, i << order); ++ } ++ } ++} ++ + static noinline void check_destroy(struct xarray *xa) + { + unsigned long index; +@@ -1697,6 +1760,7 @@ static int xarray_checks(void) + check_reserve(&array); + check_reserve(&xa0); + check_multi_store(&array); ++ check_get_order(&array); + check_xa_alloc(); + check_find(&array); + check_find_entry(&array); +@@ -1708,6 +1772,7 @@ static int xarray_checks(void) + check_store_range(&array); + check_store_iter(&array); + check_align(&xa0); ++ check_split(&array); + + check_workingset(&array, 0); + check_workingset(&array, 64); +diff --git a/lib/xarray.c b/lib/xarray.c +index 08d71c7b75990..7d22b30591275 100644 +--- a/lib/xarray.c ++++ b/lib/xarray.c +@@ -266,13 +266,14 @@ static void xa_node_free(struct xa_node *node) + */ + static void xas_destroy(struct xa_state *xas) + { +- struct xa_node *node = xas->xa_alloc; ++ struct xa_node *next, *node = xas->xa_alloc; + +- if (!node) +- return; +- XA_NODE_BUG_ON(node, !list_empty(&node->private_list)); +- kmem_cache_free(radix_tree_node_cachep, node); +- xas->xa_alloc = NULL; ++ while (node) { ++ XA_NODE_BUG_ON(node, !list_empty(&node->private_list)); ++ next = rcu_dereference_raw(node->parent); ++ radix_tree_node_rcu_free(&node->rcu_head); ++ xas->xa_alloc = node = next; ++ } + } + + /** +@@ -304,6 +305,7 @@ bool xas_nomem(struct xa_state *xas, gfp_t gfp) + xas->xa_alloc = kmem_cache_alloc(radix_tree_node_cachep, gfp); + if (!xas->xa_alloc) + return false; ++ xas->xa_alloc->parent = NULL; + XA_NODE_BUG_ON(xas->xa_alloc, !list_empty(&xas->xa_alloc->private_list)); + xas->xa_node = XAS_RESTART; + return true; +@@ -339,6 +341,7 @@ static bool __xas_nomem(struct xa_state *xas, gfp_t gfp) + } + if (!xas->xa_alloc) + return false; ++ xas->xa_alloc->parent = NULL; + XA_NODE_BUG_ON(xas->xa_alloc, !list_empty(&xas->xa_alloc->private_list)); + xas->xa_node = XAS_RESTART; + return true; +@@ -403,7 +406,7 @@ static unsigned long xas_size(const struct xa_state *xas) + /* + * Use this to calculate the maximum index that will need to be created + * in order to add the entry described by @xas. Because we cannot store a +- * multiple-index entry at index 0, the calculation is a little more complex ++ * multi-index entry at index 0, the calculation is a little more complex + * than you might expect. + */ + static unsigned long xas_max(struct xa_state *xas) +@@ -946,6 +949,153 @@ void xas_init_marks(const struct xa_state *xas) + } + EXPORT_SYMBOL_GPL(xas_init_marks); + ++#ifdef CONFIG_XARRAY_MULTI ++static unsigned int node_get_marks(struct xa_node *node, unsigned int offset) ++{ ++ unsigned int marks = 0; ++ xa_mark_t mark = XA_MARK_0; ++ ++ for (;;) { ++ if (node_get_mark(node, offset, mark)) ++ marks |= 1 << (__force unsigned int)mark; ++ if (mark == XA_MARK_MAX) ++ break; ++ mark_inc(mark); ++ } ++ ++ return marks; ++} ++ ++static void node_set_marks(struct xa_node *node, unsigned int offset, ++ struct xa_node *child, unsigned int marks) ++{ ++ xa_mark_t mark = XA_MARK_0; ++ ++ for (;;) { ++ if (marks & (1 << (__force unsigned int)mark)) { ++ node_set_mark(node, offset, mark); ++ if (child) ++ node_mark_all(child, mark); ++ } ++ if (mark == XA_MARK_MAX) ++ break; ++ mark_inc(mark); ++ } ++} ++ ++/** ++ * xas_split_alloc() - Allocate memory for splitting an entry. ++ * @xas: XArray operation state. ++ * @entry: New entry which will be stored in the array. ++ * @order: New entry order. ++ * @gfp: Memory allocation flags. ++ * ++ * This function should be called before calling xas_split(). ++ * If necessary, it will allocate new nodes (and fill them with @entry) ++ * to prepare for the upcoming split of an entry of @order size into ++ * entries of the order stored in the @xas. ++ * ++ * Context: May sleep if @gfp flags permit. ++ */ ++void xas_split_alloc(struct xa_state *xas, void *entry, unsigned int order, ++ gfp_t gfp) ++{ ++ unsigned int sibs = (1 << (order % XA_CHUNK_SHIFT)) - 1; ++ unsigned int mask = xas->xa_sibs; ++ ++ /* XXX: no support for splitting really large entries yet */ ++ if (WARN_ON(xas->xa_shift + 2 * XA_CHUNK_SHIFT < order)) ++ goto nomem; ++ if (xas->xa_shift + XA_CHUNK_SHIFT > order) ++ return; ++ ++ do { ++ unsigned int i; ++ void *sibling; ++ struct xa_node *node; ++ ++ node = kmem_cache_alloc(radix_tree_node_cachep, gfp); ++ if (!node) ++ goto nomem; ++ node->array = xas->xa; ++ for (i = 0; i < XA_CHUNK_SIZE; i++) { ++ if ((i & mask) == 0) { ++ RCU_INIT_POINTER(node->slots[i], entry); ++ sibling = xa_mk_sibling(0); ++ } else { ++ RCU_INIT_POINTER(node->slots[i], sibling); ++ } ++ } ++ RCU_INIT_POINTER(node->parent, xas->xa_alloc); ++ xas->xa_alloc = node; ++ } while (sibs-- > 0); ++ ++ return; ++nomem: ++ xas_destroy(xas); ++ xas_set_err(xas, -ENOMEM); ++} ++EXPORT_SYMBOL_GPL(xas_split_alloc); ++ ++/** ++ * xas_split() - Split a multi-index entry into smaller entries. ++ * @xas: XArray operation state. ++ * @entry: New entry to store in the array. ++ * @order: New entry order. ++ * ++ * The value in the entry is copied to all the replacement entries. ++ * ++ * Context: Any context. The caller should hold the xa_lock. ++ */ ++void xas_split(struct xa_state *xas, void *entry, unsigned int order) ++{ ++ unsigned int sibs = (1 << (order % XA_CHUNK_SHIFT)) - 1; ++ unsigned int offset, marks; ++ struct xa_node *node; ++ void *curr = xas_load(xas); ++ int values = 0; ++ ++ node = xas->xa_node; ++ if (xas_top(node)) ++ return; ++ ++ marks = node_get_marks(node, xas->xa_offset); ++ ++ offset = xas->xa_offset + sibs; ++ do { ++ if (xas->xa_shift < node->shift) { ++ struct xa_node *child = xas->xa_alloc; ++ ++ xas->xa_alloc = rcu_dereference_raw(child->parent); ++ child->shift = node->shift - XA_CHUNK_SHIFT; ++ child->offset = offset; ++ child->count = XA_CHUNK_SIZE; ++ child->nr_values = xa_is_value(entry) ? ++ XA_CHUNK_SIZE : 0; ++ RCU_INIT_POINTER(child->parent, node); ++ node_set_marks(node, offset, child, marks); ++ rcu_assign_pointer(node->slots[offset], ++ xa_mk_node(child)); ++ if (xa_is_value(curr)) ++ values--; ++ } else { ++ unsigned int canon = offset - xas->xa_sibs; ++ ++ node_set_marks(node, canon, NULL, marks); ++ rcu_assign_pointer(node->slots[canon], entry); ++ while (offset > canon) ++ rcu_assign_pointer(node->slots[offset--], ++ xa_mk_sibling(canon)); ++ values += (xa_is_value(entry) - xa_is_value(curr)) * ++ (xas->xa_sibs + 1); ++ } ++ } while (offset-- > xas->xa_offset); ++ ++ node->nr_values += values; ++} ++EXPORT_SYMBOL_GPL(xas_split); ++#endif ++ + /** + * xas_pause() - Pause a walk to drop a lock. + * @xas: XArray operation state. +@@ -1407,7 +1557,7 @@ EXPORT_SYMBOL(__xa_store); + * @gfp: Memory allocation flags. + * + * After this function returns, loads from this index will return @entry. +- * Storing into an existing multislot entry updates the entry of every index. ++ * Storing into an existing multi-index entry updates the entry of every index. + * The marks associated with @index are unaffected unless @entry is %NULL. + * + * Context: Any context. Takes and releases the xa_lock. +@@ -1549,7 +1699,7 @@ static void xas_set_range(struct xa_state *xas, unsigned long first, + * + * After this function returns, loads from any index between @first and @last, + * inclusive will return @entry. +- * Storing into an existing multislot entry updates the entry of every index. ++ * Storing into an existing multi-index entry updates the entry of every index. + * The marks associated with @index are unaffected unless @entry is %NULL. + * + * Context: Process context. Takes and releases the xa_lock. May sleep +@@ -1592,6 +1742,46 @@ unlock: + return xas_result(&xas, NULL); + } + EXPORT_SYMBOL(xa_store_range); ++ ++/** ++ * xa_get_order() - Get the order of an entry. ++ * @xa: XArray. ++ * @index: Index of the entry. ++ * ++ * Return: A number between 0 and 63 indicating the order of the entry. ++ */ ++int xa_get_order(struct xarray *xa, unsigned long index) ++{ ++ XA_STATE(xas, xa, index); ++ void *entry; ++ int order = 0; ++ ++ rcu_read_lock(); ++ entry = xas_load(&xas); ++ ++ if (!entry) ++ goto unlock; ++ ++ if (!xas.xa_node) ++ goto unlock; ++ ++ for (;;) { ++ unsigned int slot = xas.xa_offset + (1 << order); ++ ++ if (slot >= XA_CHUNK_SIZE) ++ break; ++ if (!xa_is_sibling(xas.xa_node->slots[slot])) ++ break; ++ order++; ++ } ++ ++ order += xas.xa_node->shift; ++unlock: ++ rcu_read_unlock(); ++ ++ return order; ++} ++EXPORT_SYMBOL(xa_get_order); + #endif /* CONFIG_XARRAY_MULTI */ + + /** +diff --git a/mm/filemap.c b/mm/filemap.c +index db542b4948838..c10e237cc2c6e 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -856,7 +856,6 @@ noinline int __add_to_page_cache_locked(struct page *page, + int huge = PageHuge(page); + struct mem_cgroup *memcg; + int error; +- void *old; + + VM_BUG_ON_PAGE(!PageLocked(page), page); + VM_BUG_ON_PAGE(PageSwapBacked(page), page); +@@ -872,21 +871,41 @@ noinline int __add_to_page_cache_locked(struct page *page, + get_page(page); + page->mapping = mapping; + page->index = offset; ++ gfp_mask &= GFP_RECLAIM_MASK; + + do { ++ unsigned int order = xa_get_order(xas.xa, xas.xa_index); ++ void *entry, *old = NULL; ++ ++ if (order > thp_order(page)) ++ xas_split_alloc(&xas, xa_load(xas.xa, xas.xa_index), ++ order, gfp_mask); + xas_lock_irq(&xas); +- old = xas_load(&xas); +- if (old && !xa_is_value(old)) +- xas_set_err(&xas, -EEXIST); ++ xas_for_each_conflict(&xas, entry) { ++ old = entry; ++ if (!xa_is_value(entry)) { ++ xas_set_err(&xas, -EEXIST); ++ goto unlock; ++ } ++ } ++ ++ if (old) { ++ if (shadowp) ++ *shadowp = old; ++ /* entry may have been split before we acquired lock */ ++ order = xa_get_order(xas.xa, xas.xa_index); ++ if (order > thp_order(page)) { ++ xas_split(&xas, old, order); ++ xas_reset(&xas); ++ } ++ } ++ + xas_store(&xas, page); + if (xas_error(&xas)) + goto unlock; + +- if (xa_is_value(old)) { ++ if (old) + mapping->nrexceptional--; +- if (shadowp) +- *shadowp = old; +- } + mapping->nrpages++; + + /* hugetlb pages do not participate in page cache accounting */ +@@ -894,7 +913,7 @@ noinline int __add_to_page_cache_locked(struct page *page, + __inc_node_page_state(page, NR_FILE_PAGES); + unlock: + xas_unlock_irq(&xas); +- } while (xas_nomem(&xas, gfp_mask & GFP_RECLAIM_MASK)); ++ } while (xas_nomem(&xas, gfp_mask)); + + if (xas_error(&xas)) + goto error; +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 3b08e34a775df..fe15e7d8220ab 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -4338,10 +4338,20 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm, + struct page *page; + + if (!*pagep) { +- ret = -ENOMEM; ++ /* If a page already exists, then it's UFFDIO_COPY for ++ * a non-missing case. Return -EEXIST. ++ */ ++ if (vm_shared && ++ hugetlbfs_pagecache_present(h, dst_vma, dst_addr)) { ++ ret = -EEXIST; ++ goto out; ++ } ++ + page = alloc_huge_page(dst_vma, dst_addr, 0); +- if (IS_ERR(page)) ++ if (IS_ERR(page)) { ++ ret = -ENOMEM; + goto out; ++ } + + ret = copy_huge_page_from_user(page, + (const void __user *) src_addr, +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 83b324419ad3d..21a7ea9b70c8a 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -1561,8 +1561,13 @@ setup_failed: + } else { + /* Init failed, cleanup */ + flush_work(&hdev->tx_work); +- flush_work(&hdev->cmd_work); ++ ++ /* Since hci_rx_work() is possible to awake new cmd_work ++ * it should be flushed first to avoid unexpected call of ++ * hci_cmd_work() ++ */ + flush_work(&hdev->rx_work); ++ flush_work(&hdev->cmd_work); + + skb_queue_purge(&hdev->cmd_q); + skb_queue_purge(&hdev->rx_q); +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index 8159b344deef5..8d2c26c4b6d3d 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -755,7 +755,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) + /* Detach sockets from device */ + read_lock(&hci_sk_list.lock); + sk_for_each(sk, &hci_sk_list.head) { +- bh_lock_sock_nested(sk); ++ lock_sock(sk); + if (hci_pi(sk)->hdev == hdev) { + hci_pi(sk)->hdev = NULL; + sk->sk_err = EPIPE; +@@ -764,7 +764,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) + + hci_dev_put(hdev); + } +- bh_unlock_sock(sk); ++ release_sock(sk); + } + read_unlock(&hci_sk_list.lock); + } +diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c +index 03c7cdd8e4cbf..8a3c19b9a9958 100644 +--- a/net/caif/caif_dev.c ++++ b/net/caif/caif_dev.c +@@ -307,7 +307,7 @@ static void dev_flowctrl(struct net_device *dev, int on) + caifd_put(caifd); + } + +-void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, ++int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + struct cflayer *link_support, int head_room, + struct cflayer **layer, + int (**rcv_func)(struct sk_buff *, struct net_device *, +@@ -318,11 +318,12 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + enum cfcnfg_phy_preference pref; + struct cfcnfg *cfg = get_cfcnfg(dev_net(dev)); + struct caif_device_entry_list *caifdevs; ++ int res; + + caifdevs = caif_device_list(dev_net(dev)); + caifd = caif_device_alloc(dev); + if (!caifd) +- return; ++ return -ENOMEM; + *layer = &caifd->layer; + spin_lock_init(&caifd->flow_lock); + +@@ -343,7 +344,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + strlcpy(caifd->layer.name, dev->name, + sizeof(caifd->layer.name)); + caifd->layer.transmit = transmit; +- cfcnfg_add_phy_layer(cfg, ++ res = cfcnfg_add_phy_layer(cfg, + dev, + &caifd->layer, + pref, +@@ -353,6 +354,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + mutex_unlock(&caifdevs->lock); + if (rcv_func) + *rcv_func = receive; ++ return res; + } + EXPORT_SYMBOL(caif_enroll_dev); + +@@ -367,6 +369,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, + struct cflayer *layer, *link_support; + int head_room = 0; + struct caif_device_entry_list *caifdevs; ++ int res; + + cfg = get_cfcnfg(dev_net(dev)); + caifdevs = caif_device_list(dev_net(dev)); +@@ -392,8 +395,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, + break; + } + } +- caif_enroll_dev(dev, caifdev, link_support, head_room, ++ res = caif_enroll_dev(dev, caifdev, link_support, head_room, + &layer, NULL); ++ if (res) ++ cfserl_release(link_support); + caifdev->flowctrl = dev_flowctrl; + break; + +diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c +index 76bd67891fb39..46c62dd1479b8 100644 +--- a/net/caif/caif_usb.c ++++ b/net/caif/caif_usb.c +@@ -115,6 +115,11 @@ static struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN], + return (struct cflayer *) this; + } + ++static void cfusbl_release(struct cflayer *layer) ++{ ++ kfree(layer); ++} ++ + static struct packet_type caif_usb_type __read_mostly = { + .type = cpu_to_be16(ETH_P_802_EX1), + }; +@@ -127,6 +132,7 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, + struct cflayer *layer, *link_support; + struct usbnet *usbnet; + struct usb_device *usbdev; ++ int res; + + /* Check whether we have a NCM device, and find its VID/PID. */ + if (!(dev->dev.parent && dev->dev.parent->driver && +@@ -169,8 +175,11 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, + if (dev->num_tx_queues > 1) + pr_warn("USB device uses more than one tx queue\n"); + +- caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN, ++ res = caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN, + &layer, &caif_usb_type.func); ++ if (res) ++ goto err; ++ + if (!pack_added) + dev_add_pack(&caif_usb_type); + pack_added = true; +@@ -178,6 +187,9 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, + strlcpy(layer->name, dev->name, sizeof(layer->name)); + + return 0; ++err: ++ cfusbl_release(link_support); ++ return res; + } + + static struct notifier_block caif_device_notifier = { +diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c +index 399239a14420f..cac30e676ac94 100644 +--- a/net/caif/cfcnfg.c ++++ b/net/caif/cfcnfg.c +@@ -450,7 +450,7 @@ unlock: + rcu_read_unlock(); + } + +-void ++int + cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + struct net_device *dev, struct cflayer *phy_layer, + enum cfcnfg_phy_preference pref, +@@ -459,7 +459,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + { + struct cflayer *frml; + struct cfcnfg_phyinfo *phyinfo = NULL; +- int i; ++ int i, res = 0; + u8 phyid; + + mutex_lock(&cnfg->lock); +@@ -473,12 +473,15 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + goto got_phyid; + } + pr_warn("Too many CAIF Link Layers (max 6)\n"); ++ res = -EEXIST; + goto out; + + got_phyid: + phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC); +- if (!phyinfo) ++ if (!phyinfo) { ++ res = -ENOMEM; + goto out_err; ++ } + + phy_layer->id = phyid; + phyinfo->pref = pref; +@@ -492,8 +495,10 @@ got_phyid: + + frml = cffrml_create(phyid, fcs); + +- if (!frml) ++ if (!frml) { ++ res = -ENOMEM; + goto out_err; ++ } + phyinfo->frm_layer = frml; + layer_set_up(frml, cnfg->mux); + +@@ -511,11 +516,12 @@ got_phyid: + list_add_rcu(&phyinfo->node, &cnfg->phys); + out: + mutex_unlock(&cnfg->lock); +- return; ++ return res; + + out_err: + kfree(phyinfo); + mutex_unlock(&cnfg->lock); ++ return res; + } + EXPORT_SYMBOL(cfcnfg_add_phy_layer); + +diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c +index e11725a4bb0ed..40cd57ad0a0f4 100644 +--- a/net/caif/cfserl.c ++++ b/net/caif/cfserl.c +@@ -31,6 +31,11 @@ static int cfserl_transmit(struct cflayer *layr, struct cfpkt *pkt); + static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, + int phyid); + ++void cfserl_release(struct cflayer *layer) ++{ ++ kfree(layer); ++} ++ + struct cflayer *cfserl_create(int instance, bool use_stx) + { + struct cfserl *this = kzalloc(sizeof(struct cfserl), GFP_ATOMIC); +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 472a615775f32..f94d405358a21 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -239,6 +239,7 @@ static int neigh_forced_gc(struct neigh_table *tbl) + + write_lock(&n->lock); + if ((n->nud_state == NUD_FAILED) || ++ (n->nud_state == NUD_NOARP) || + (tbl->is_multicast && + tbl->is_multicast(n->primary_key)) || + time_after(tref, n->updated)) +diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c +index d19c40c684e80..71be751123210 100644 +--- a/net/ieee802154/nl-mac.c ++++ b/net/ieee802154/nl-mac.c +@@ -680,8 +680,10 @@ int ieee802154_llsec_getparams(struct sk_buff *skb, struct genl_info *info) + nla_put_u8(msg, IEEE802154_ATTR_LLSEC_SECLEVEL, params.out_level) || + nla_put_u32(msg, IEEE802154_ATTR_LLSEC_FRAME_COUNTER, + be32_to_cpu(params.frame_counter)) || +- ieee802154_llsec_fill_key_id(msg, ¶ms.out_key)) ++ ieee802154_llsec_fill_key_id(msg, ¶ms.out_key)) { ++ rc = -ENOBUFS; + goto out_free; ++ } + + dev_put(dev); + +diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c +index 2cdc7e63fe172..88215b5c93aa4 100644 +--- a/net/ieee802154/nl-phy.c ++++ b/net/ieee802154/nl-phy.c +@@ -241,8 +241,10 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) + } + + if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || +- nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) ++ nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) { ++ rc = -EMSGSIZE; + goto nla_put_failure; ++ } + dev_put(dev); + + wpan_phy_put(phy); +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 3a9bd9687e7d1..b903fe28ce507 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3688,11 +3688,11 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg, + if (nh) { + if (rt->fib6_src.plen) { + NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing"); +- goto out; ++ goto out_free; + } + if (!nexthop_get(nh)) { + NL_SET_ERR_MSG(extack, "Nexthop has been deleted"); +- goto out; ++ goto out_free; + } + rt->nh = nh; + fib6_nh = nexthop_fib6_nh(rt->nh); +@@ -3729,6 +3729,10 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg, + out: + fib6_info_release(rt); + return ERR_PTR(err); ++out_free: ++ ip_fib_metrics_put(rt->fib6_metrics); ++ kfree(rt); ++ return ERR_PTR(err); + } + + int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index 99168af0c28d9..f93fa0e210979 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -1340,7 +1340,7 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, + ip_vs_addr_copy(svc->af, &svc->addr, &u->addr); + svc->port = u->port; + svc->fwmark = u->fwmark; +- svc->flags = u->flags; ++ svc->flags = u->flags & ~IP_VS_SVC_F_HASHED; + svc->timeout = u->timeout * HZ; + svc->netmask = u->netmask; + svc->ipvs = ipvs; +diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c +index aaf4293ddd459..75e6b429635da 100644 +--- a/net/netfilter/nf_conntrack_proto.c ++++ b/net/netfilter/nf_conntrack_proto.c +@@ -660,7 +660,7 @@ int nf_conntrack_proto_init(void) + + #if IS_ENABLED(CONFIG_IPV6) + cleanup_sockopt: +- nf_unregister_sockopt(&so_getorigdst6); ++ nf_unregister_sockopt(&so_getorigdst); + #endif + return ret; + } +diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c +index 81406b93f126d..3d5fc07b2530b 100644 +--- a/net/netfilter/nfnetlink_cthelper.c ++++ b/net/netfilter/nfnetlink_cthelper.c +@@ -380,10 +380,14 @@ static int + nfnl_cthelper_update(const struct nlattr * const tb[], + struct nf_conntrack_helper *helper) + { ++ u32 size; + int ret; + +- if (tb[NFCTH_PRIV_DATA_LEN]) +- return -EBUSY; ++ if (tb[NFCTH_PRIV_DATA_LEN]) { ++ size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN])); ++ if (size != helper->data_len) ++ return -EBUSY; ++ } + + if (tb[NFCTH_POLICY]) { + ret = nfnl_cthelper_update_policy(helper, tb[NFCTH_POLICY]); +diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c +index 2042c6f4629cc..28991730728b9 100644 +--- a/net/netfilter/nft_ct.c ++++ b/net/netfilter/nft_ct.c +@@ -1218,7 +1218,7 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj, + struct nf_conn *ct; + + ct = nf_ct_get(pkt->skb, &ctinfo); +- if (!ct || ctinfo == IP_CT_UNTRACKED) { ++ if (!ct || nf_ct_is_confirmed(ct) || nf_ct_is_template(ct)) { + regs->verdict.code = NFT_BREAK; + return; + } +diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c +index 0d4246af6c02b..a7e861eede2d9 100644 +--- a/net/nfc/llcp_sock.c ++++ b/net/nfc/llcp_sock.c +@@ -110,6 +110,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) + if (!llcp_sock->service_name) { + nfc_llcp_local_put(llcp_sock->local); + llcp_sock->local = NULL; ++ llcp_sock->dev = NULL; + ret = -ENOMEM; + goto put_dev; + } +@@ -119,6 +120,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) + llcp_sock->local = NULL; + kfree(llcp_sock->service_name); + llcp_sock->service_name = NULL; ++ llcp_sock->dev = NULL; + ret = -EADDRINUSE; + goto put_dev; + } +diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c +index 6119c31dcd072..31eb8eefc8681 100644 +--- a/net/sched/act_ct.c ++++ b/net/sched/act_ct.c +@@ -648,9 +648,6 @@ static int tcf_ct_fill_params(struct net *net, + sizeof(p->zone)); + } + +- if (p->zone == NF_CT_DEFAULT_ZONE_ID) +- return 0; +- + nf_ct_zone_init(&zone, p->zone, NF_CT_DEFAULT_ZONE_DIR, 0); + tmpl = nf_ct_tmpl_alloc(net, &zone, GFP_KERNEL); + if (!tmpl) { +diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c +index 0214aa1c44278..8bd2454cc89dc 100644 +--- a/net/tipc/bearer.c ++++ b/net/tipc/bearer.c +@@ -233,7 +233,8 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest) + */ + static int tipc_enable_bearer(struct net *net, const char *name, + u32 disc_domain, u32 prio, +- struct nlattr *attr[]) ++ struct nlattr *attr[], ++ struct netlink_ext_ack *extack) + { + struct tipc_net *tn = tipc_net(net); + struct tipc_bearer_names b_names; +@@ -244,20 +245,24 @@ static int tipc_enable_bearer(struct net *net, const char *name, + int bearer_id = 0; + int res = -EINVAL; + char *errstr = ""; ++ u32 i; + + if (!bearer_name_validate(name, &b_names)) { + errstr = "illegal name"; ++ NL_SET_ERR_MSG(extack, "Illegal name"); + goto rejected; + } + + if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) { + errstr = "illegal priority"; ++ NL_SET_ERR_MSG(extack, "Illegal priority"); + goto rejected; + } + + m = tipc_media_find(b_names.media_name); + if (!m) { + errstr = "media not registered"; ++ NL_SET_ERR_MSG(extack, "Media not registered"); + goto rejected; + } + +@@ -265,33 +270,43 @@ static int tipc_enable_bearer(struct net *net, const char *name, + prio = m->priority; + + /* Check new bearer vs existing ones and find free bearer id if any */ +- while (bearer_id < MAX_BEARERS) { +- b = rtnl_dereference(tn->bearer_list[bearer_id]); +- if (!b) +- break; ++ bearer_id = MAX_BEARERS; ++ i = MAX_BEARERS; ++ while (i-- != 0) { ++ b = rtnl_dereference(tn->bearer_list[i]); ++ if (!b) { ++ bearer_id = i; ++ continue; ++ } + if (!strcmp(name, b->name)) { + errstr = "already enabled"; ++ NL_SET_ERR_MSG(extack, "Already enabled"); + goto rejected; + } +- bearer_id++; +- if (b->priority != prio) +- continue; +- if (++with_this_prio <= 2) +- continue; +- pr_warn("Bearer <%s>: already 2 bearers with priority %u\n", +- name, prio); +- if (prio == TIPC_MIN_LINK_PRI) { +- errstr = "cannot adjust to lower"; +- goto rejected; ++ ++ if (b->priority == prio && ++ (++with_this_prio > 2)) { ++ pr_warn("Bearer <%s>: already 2 bearers with priority %u\n", ++ name, prio); ++ ++ if (prio == TIPC_MIN_LINK_PRI) { ++ errstr = "cannot adjust to lower"; ++ NL_SET_ERR_MSG(extack, "Cannot adjust to lower"); ++ goto rejected; ++ } ++ ++ pr_warn("Bearer <%s>: trying with adjusted priority\n", ++ name); ++ prio--; ++ bearer_id = MAX_BEARERS; ++ i = MAX_BEARERS; ++ with_this_prio = 1; + } +- pr_warn("Bearer <%s>: trying with adjusted priority\n", name); +- prio--; +- bearer_id = 0; +- with_this_prio = 1; + } + + if (bearer_id >= MAX_BEARERS) { + errstr = "max 3 bearers permitted"; ++ NL_SET_ERR_MSG(extack, "Max 3 bearers permitted"); + goto rejected; + } + +@@ -305,6 +320,7 @@ static int tipc_enable_bearer(struct net *net, const char *name, + if (res) { + kfree(b); + errstr = "failed to enable media"; ++ NL_SET_ERR_MSG(extack, "Failed to enable media"); + goto rejected; + } + +@@ -320,6 +336,7 @@ static int tipc_enable_bearer(struct net *net, const char *name, + if (res) { + bearer_disable(net, b); + errstr = "failed to create discoverer"; ++ NL_SET_ERR_MSG(extack, "Failed to create discoverer"); + goto rejected; + } + +@@ -862,6 +879,7 @@ int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info) + bearer = tipc_bearer_find(net, name); + if (!bearer) { + err = -EINVAL; ++ NL_SET_ERR_MSG(info->extack, "Bearer not found"); + goto err_out; + } + +@@ -901,8 +919,10 @@ int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) + name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); + + bearer = tipc_bearer_find(net, name); +- if (!bearer) ++ if (!bearer) { ++ NL_SET_ERR_MSG(info->extack, "Bearer not found"); + return -EINVAL; ++ } + + bearer_disable(net, bearer); + +@@ -960,7 +980,8 @@ int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) + prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); + } + +- return tipc_enable_bearer(net, bearer, domain, prio, attrs); ++ return tipc_enable_bearer(net, bearer, domain, prio, attrs, ++ info->extack); + } + + int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) +@@ -999,6 +1020,7 @@ int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info) + b = tipc_bearer_find(net, name); + if (!b) { + rtnl_unlock(); ++ NL_SET_ERR_MSG(info->extack, "Bearer not found"); + return -EINVAL; + } + +@@ -1039,8 +1061,10 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) + name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); + + b = tipc_bearer_find(net, name); +- if (!b) ++ if (!b) { ++ NL_SET_ERR_MSG(info->extack, "Bearer not found"); + return -EINVAL; ++ } + + if (attrs[TIPC_NLA_BEARER_PROP]) { + struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; +@@ -1059,12 +1083,18 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) + if (props[TIPC_NLA_PROP_WIN]) + b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); + if (props[TIPC_NLA_PROP_MTU]) { +- if (b->media->type_id != TIPC_MEDIA_TYPE_UDP) ++ if (b->media->type_id != TIPC_MEDIA_TYPE_UDP) { ++ NL_SET_ERR_MSG(info->extack, ++ "MTU property is unsupported"); + return -EINVAL; ++ } + #ifdef CONFIG_TIPC_MEDIA_UDP + if (tipc_udp_mtu_bad(nla_get_u32 +- (props[TIPC_NLA_PROP_MTU]))) ++ (props[TIPC_NLA_PROP_MTU]))) { ++ NL_SET_ERR_MSG(info->extack, ++ "MTU value is out-of-range"); + return -EINVAL; ++ } + b->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]); + tipc_node_apply_property(net, b, TIPC_NLA_PROP_MTU); + #endif +@@ -1192,6 +1222,7 @@ int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info) + rtnl_lock(); + media = tipc_media_find(name); + if (!media) { ++ NL_SET_ERR_MSG(info->extack, "Media not found"); + err = -EINVAL; + goto err_out; + } +@@ -1228,9 +1259,10 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) + name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]); + + m = tipc_media_find(name); +- if (!m) ++ if (!m) { ++ NL_SET_ERR_MSG(info->extack, "Media not found"); + return -EINVAL; +- ++ } + if (attrs[TIPC_NLA_MEDIA_PROP]) { + struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; + +@@ -1246,12 +1278,18 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) + if (props[TIPC_NLA_PROP_WIN]) + m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]); + if (props[TIPC_NLA_PROP_MTU]) { +- if (m->type_id != TIPC_MEDIA_TYPE_UDP) ++ if (m->type_id != TIPC_MEDIA_TYPE_UDP) { ++ NL_SET_ERR_MSG(info->extack, ++ "MTU property is unsupported"); + return -EINVAL; ++ } + #ifdef CONFIG_TIPC_MEDIA_UDP + if (tipc_udp_mtu_bad(nla_get_u32 +- (props[TIPC_NLA_PROP_MTU]))) ++ (props[TIPC_NLA_PROP_MTU]))) { ++ NL_SET_ERR_MSG(info->extack, ++ "MTU value is out-of-range"); + return -EINVAL; ++ } + m->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]); + #endif + } +diff --git a/net/wireless/core.h b/net/wireless/core.h +index d83c8e009448a..17621d22fb175 100644 +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -433,6 +433,8 @@ void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev); + + /* internal helpers */ + bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); ++bool cfg80211_valid_key_idx(struct cfg80211_registered_device *rdev, ++ int key_idx, bool pairwise); + int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, + struct key_params *params, int key_idx, + bool pairwise, const u8 *mac_addr); +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index 5bb2316befb98..7b170ed6923e7 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3979,9 +3979,6 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) + if (err) + return err; + +- if (key.idx < 0) +- return -EINVAL; +- + if (info->attrs[NL80211_ATTR_MAC]) + mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); + +@@ -3997,6 +3994,10 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) + key.type != NL80211_KEYTYPE_GROUP) + return -EINVAL; + ++ if (!cfg80211_valid_key_idx(rdev, key.idx, ++ key.type == NL80211_KEYTYPE_PAIRWISE)) ++ return -EINVAL; ++ + if (!rdev->ops->del_key) + return -EOPNOTSUPP; + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index 82244e2fc1f54..4eae6ad328514 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -229,11 +229,48 @@ bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher) + return false; + } + ++static bool ++cfg80211_igtk_cipher_supported(struct cfg80211_registered_device *rdev) ++{ ++ struct wiphy *wiphy = &rdev->wiphy; ++ int i; ++ ++ for (i = 0; i < wiphy->n_cipher_suites; i++) { ++ switch (wiphy->cipher_suites[i]) { ++ case WLAN_CIPHER_SUITE_AES_CMAC: ++ case WLAN_CIPHER_SUITE_BIP_CMAC_256: ++ case WLAN_CIPHER_SUITE_BIP_GMAC_128: ++ case WLAN_CIPHER_SUITE_BIP_GMAC_256: ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++bool cfg80211_valid_key_idx(struct cfg80211_registered_device *rdev, ++ int key_idx, bool pairwise) ++{ ++ int max_key_idx; ++ ++ if (pairwise) ++ max_key_idx = 3; ++ else if (cfg80211_igtk_cipher_supported(rdev)) ++ max_key_idx = 5; ++ else ++ max_key_idx = 3; ++ ++ if (key_idx < 0 || key_idx > max_key_idx) ++ return false; ++ ++ return true; ++} ++ + int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, + struct key_params *params, int key_idx, + bool pairwise, const u8 *mac_addr) + { +- if (key_idx < 0 || key_idx > 5) ++ if (!cfg80211_valid_key_idx(rdev, key_idx, pairwise)) + return -EINVAL; + + if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) +diff --git a/samples/vfio-mdev/mdpy-fb.c b/samples/vfio-mdev/mdpy-fb.c +index 2719bb2596530..a760e130bd0d6 100644 +--- a/samples/vfio-mdev/mdpy-fb.c ++++ b/samples/vfio-mdev/mdpy-fb.c +@@ -117,22 +117,27 @@ static int mdpy_fb_probe(struct pci_dev *pdev, + if (format != DRM_FORMAT_XRGB8888) { + pci_err(pdev, "format mismatch (0x%x != 0x%x)\n", + format, DRM_FORMAT_XRGB8888); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_release_regions; + } + if (width < 100 || width > 10000) { + pci_err(pdev, "width (%d) out of range\n", width); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_release_regions; + } + if (height < 100 || height > 10000) { + pci_err(pdev, "height (%d) out of range\n", height); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_release_regions; + } + pci_info(pdev, "mdpy found: %dx%d framebuffer\n", + width, height); + + info = framebuffer_alloc(sizeof(struct mdpy_fb_par), &pdev->dev); +- if (!info) ++ if (!info) { ++ ret = -ENOMEM; + goto err_release_regions; ++ } + pci_set_drvdata(pdev, info); + par = info->par; + +diff --git a/sound/core/timer.c b/sound/core/timer.c +index 013f0e69ff0f7..b5a0ba79bf746 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -491,9 +491,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) + return; + if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) + return; ++ event += 10; /* convert to SNDRV_TIMER_EVENT_MXXX */ + list_for_each_entry(ts, &ti->slave_active_head, active_list) + if (ts->ccallback) +- ts->ccallback(ts, event + 100, &tstamp, resolution); ++ ts->ccallback(ts, event, &tstamp, resolution); + } + + /* start/continue a master timer */ +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index b9fa2ee0a40cb..de40bb99b6793 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -8062,6 +8062,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), ++ SND_PCI_QUIRK(0x103c, 0x841c, "HP Pavilion 15-CK0xx", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN), + SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), +diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c +index 5251818e10d33..d926869c031b1 100644 +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -1697,7 +1697,7 @@ static struct snd_kcontrol_new snd_microii_mixer_spdif[] = { + static int snd_microii_controls_create(struct usb_mixer_interface *mixer) + { + int err, i; +- const static usb_mixer_elem_resume_func_t resume_funcs[] = { ++ static const usb_mixer_elem_resume_func_t resume_funcs[] = { + snd_microii_spdif_default_update, + NULL, + snd_microii_spdif_switch_update diff --git a/patch/kernel/archive/sunxi-5.12/patch-5.12.9-10.patch b/patch/kernel/archive/sunxi-5.12/patch-5.12.9-10.patch new file mode 100644 index 0000000000..d2017851fe --- /dev/null +++ b/patch/kernel/archive/sunxi-5.12/patch-5.12.9-10.patch @@ -0,0 +1,6796 @@ +diff --git a/Makefile b/Makefile +index d53577db10858..ebc02c56db03c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 5 + PATCHLEVEL = 12 +-SUBLEVEL = 9 ++SUBLEVEL = 10 + EXTRAVERSION = + NAME = Frozen Wasteland + +diff --git a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi +index 7d2c72562c735..9148a01ed6d9f 100644 +--- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi ++++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi +@@ -105,9 +105,13 @@ + phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + phy-reset-duration = <20>; + phy-supply = <&sw2_reg>; +- phy-handle = <ðphy0>; + status = "okay"; + ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ + mdio { + #address-cells = <1>; + #size-cells = <0>; +diff --git a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi +index 236fc205c3890..d0768ae429faa 100644 +--- a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi ++++ b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi +@@ -406,6 +406,18 @@ + vin-supply = <&sw1_reg>; + }; + ++®_pu { ++ vin-supply = <&sw1_reg>; ++}; ++ ++®_vdd1p1 { ++ vin-supply = <&sw2_reg>; ++}; ++ ++®_vdd2p5 { ++ vin-supply = <&sw2_reg>; ++}; ++ + &uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; +diff --git a/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi b/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi +index 828cf3e39784a..c4e146f3341bb 100644 +--- a/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi +@@ -126,7 +126,7 @@ + compatible = "nxp,pca8574"; + reg = <0x3a>; + gpio-controller; +- #gpio-cells = <1>; ++ #gpio-cells = <2>; + }; + }; + +diff --git a/arch/arm/boot/dts/imx7d-meerkat96.dts b/arch/arm/boot/dts/imx7d-meerkat96.dts +index 5339210b63d0f..dd8003bd1fc09 100644 +--- a/arch/arm/boot/dts/imx7d-meerkat96.dts ++++ b/arch/arm/boot/dts/imx7d-meerkat96.dts +@@ -193,7 +193,7 @@ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + keep-power-in-suspend; +- tuning-step = <2>; ++ fsl,tuning-step = <2>; + vmmc-supply = <®_3p3v>; + no-1-8-v; + broken-cd; +diff --git a/arch/arm/boot/dts/imx7d-pico.dtsi b/arch/arm/boot/dts/imx7d-pico.dtsi +index e57da0d32b98d..e519897fae082 100644 +--- a/arch/arm/boot/dts/imx7d-pico.dtsi ++++ b/arch/arm/boot/dts/imx7d-pico.dtsi +@@ -351,7 +351,7 @@ + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; + bus-width = <4>; +- tuning-step = <2>; ++ fsl,tuning-step = <2>; + vmmc-supply = <®_3p3v>; + wakeup-source; + no-1-8-v; +diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c +index c40cf5ef86079..977b0b744c22a 100644 +--- a/arch/arm/mach-omap1/board-h2.c ++++ b/arch/arm/mach-omap1/board-h2.c +@@ -320,7 +320,7 @@ static int tps_setup(struct i2c_client *client, void *context) + { + if (!IS_BUILTIN(CONFIG_TPS65010)) + return -ENOSYS; +- ++ + tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V | + TPS_LDO1_ENABLE | TPS_VLDO1_3_0V); + +@@ -394,6 +394,8 @@ static void __init h2_init(void) + BUG_ON(gpio_request(H2_NAND_RB_GPIO_PIN, "NAND ready") < 0); + gpio_direction_input(H2_NAND_RB_GPIO_PIN); + ++ gpiod_add_lookup_table(&isp1301_gpiod_table); ++ + omap_cfg_reg(L3_1610_FLASH_CS2B_OE); + omap_cfg_reg(M8_1610_FLASH_CS2B_WE); + +diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms +index cdfd5fed457ff..a3fdffcd1ce8b 100644 +--- a/arch/arm64/Kconfig.platforms ++++ b/arch/arm64/Kconfig.platforms +@@ -168,6 +168,7 @@ config ARCH_MEDIATEK + + config ARCH_MESON + bool "Amlogic Platforms" ++ select COMMON_CLK + select MESON_IRQ_GPIO + help + This enables support for the arm64 based Amlogic SoCs +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts +index 6c309b97587df..e8d31279b7a34 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dts +@@ -46,7 +46,8 @@ + eee-broken-100tx; + qca,clk-out-frequency = <125000000>; + qca,clk-out-strength = ; +- vddio-supply = <&vddh>; ++ qca,keep-pll-enabled; ++ vddio-supply = <&vddio>; + + vddio: vddio-regulator { + regulator-name = "VDDIO"; +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts +index df212ed5bb942..e65d1c477e2ce 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dts +@@ -31,11 +31,10 @@ + reg = <0x4>; + eee-broken-1000t; + eee-broken-100tx; +- + qca,clk-out-frequency = <125000000>; + qca,clk-out-strength = ; +- +- vddio-supply = <&vddh>; ++ qca,keep-pll-enabled; ++ vddio-supply = <&vddio>; + + vddio: vddio-regulator { + regulator-name = "VDDIO"; +diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +index 262fbad8f0ec5..1b264e5e947ac 100644 +--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi ++++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +@@ -201,8 +201,8 @@ + ddr: memory-controller@1080000 { + compatible = "fsl,qoriq-memory-controller"; + reg = <0x0 0x1080000 0x0 0x1000>; +- interrupts = ; +- big-endian; ++ interrupts = ; ++ little-endian; + }; + + dcfg: syscon@1e00000 { +diff --git a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dts b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dts +index 631e01c1b9fd4..be1e7d6f0ecb5 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dts ++++ b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dts +@@ -88,11 +88,11 @@ + pinctrl-0 = <&pinctrl_codec2>; + reg = <0x18>; + #sound-dai-cells = <0>; +- HPVDD-supply = <®_3p3v>; +- SPRVDD-supply = <®_3p3v>; +- SPLVDD-supply = <®_3p3v>; +- AVDD-supply = <®_3p3v>; +- IOVDD-supply = <®_3p3v>; ++ HPVDD-supply = <®_gen_3p3>; ++ SPRVDD-supply = <®_gen_3p3>; ++ SPLVDD-supply = <®_gen_3p3>; ++ AVDD-supply = <®_gen_3p3>; ++ IOVDD-supply = <®_gen_3p3>; + DVDD-supply = <&vgen4_reg>; + reset-gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>; + }; +diff --git a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi +index 4dc8383478ee2..a08a568c31d92 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi +@@ -45,8 +45,8 @@ + reg_12p0_main: regulator-12p0-main { + compatible = "regulator-fixed"; + regulator-name = "12V_MAIN"; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; ++ regulator-min-microvolt = <12000000>; ++ regulator-max-microvolt = <12000000>; + regulator-always-on; + }; + +@@ -77,15 +77,6 @@ + regulator-always-on; + }; + +- reg_3p3v: regulator-3p3v { +- compatible = "regulator-fixed"; +- vin-supply = <®_3p3_main>; +- regulator-name = "GEN_3V3"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-always-on; +- }; +- + reg_usdhc2_vmmc: regulator-vsd-3v3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2>; +@@ -415,11 +406,11 @@ + pinctrl-0 = <&pinctrl_codec1>; + reg = <0x18>; + #sound-dai-cells = <0>; +- HPVDD-supply = <®_3p3v>; +- SPRVDD-supply = <®_3p3v>; +- SPLVDD-supply = <®_3p3v>; +- AVDD-supply = <®_3p3v>; +- IOVDD-supply = <®_3p3v>; ++ HPVDD-supply = <®_gen_3p3>; ++ SPRVDD-supply = <®_gen_3p3>; ++ SPLVDD-supply = <®_gen_3p3>; ++ AVDD-supply = <®_gen_3p3>; ++ IOVDD-supply = <®_gen_3p3>; + DVDD-supply = <&vgen4_reg>; + reset-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>; + }; +diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +index 17477ab0fd8e1..3398f174f09b3 100644 +--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +@@ -85,6 +85,8 @@ + #size-cells = <2>; + ranges = <0x00 0x30000000 0x00 0x30000000 0x00 0x0c400000>; + ti,sci-dev-id = <199>; ++ dma-coherent; ++ dma-ranges; + + main_navss_intr: interrupt-controller1 { + compatible = "ti,sci-intr"; +diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h +index a8578d650bb67..f362f72bcb508 100644 +--- a/arch/arm64/include/asm/kvm_asm.h ++++ b/arch/arm64/include/asm/kvm_asm.h +@@ -57,6 +57,7 @@ + #define __KVM_HOST_SMCCC_FUNC___kvm_get_mdcr_el2 12 + #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs 13 + #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs 14 ++#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc 15 + + #ifndef __ASSEMBLY__ + +diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c +index 84b5f79c9eab4..7730b81aad6d1 100644 +--- a/arch/arm64/kvm/arm.c ++++ b/arch/arm64/kvm/arm.c +@@ -715,11 +715,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) + return ret; + } + +- if (run->immediate_exit) +- return -EINTR; +- + vcpu_load(vcpu); + ++ if (run->immediate_exit) { ++ ret = -EINTR; ++ goto out; ++ } ++ + kvm_sigset_activate(vcpu); + + ret = 1; +@@ -892,6 +894,18 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) + + kvm_sigset_deactivate(vcpu); + ++out: ++ /* ++ * In the unlikely event that we are returning to userspace ++ * with pending exceptions or PC adjustment, commit these ++ * adjustments in order to give userspace a consistent view of ++ * the vcpu state. Note that this relies on __kvm_adjust_pc() ++ * being preempt-safe on VHE. ++ */ ++ if (unlikely(vcpu->arch.flags & (KVM_ARM64_PENDING_EXCEPTION | ++ KVM_ARM64_INCREMENT_PC))) ++ kvm_call_hyp(__kvm_adjust_pc, vcpu); ++ + vcpu_put(vcpu); + return ret; + } +diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c +index 0812a496725f6..11541b94b328f 100644 +--- a/arch/arm64/kvm/hyp/exception.c ++++ b/arch/arm64/kvm/hyp/exception.c +@@ -331,8 +331,8 @@ static void kvm_inject_exception(struct kvm_vcpu *vcpu) + } + + /* +- * Adjust the guest PC on entry, depending on flags provided by EL1 +- * for the purpose of emulation (MMIO, sysreg) or exception injection. ++ * Adjust the guest PC (and potentially exception state) depending on ++ * flags provided by the emulation code. + */ + void __kvm_adjust_pc(struct kvm_vcpu *vcpu) + { +diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c +index 936328207bde0..e52582e140873 100644 +--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c ++++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c +@@ -25,6 +25,13 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt) + cpu_reg(host_ctxt, 1) = __kvm_vcpu_run(kern_hyp_va(vcpu)); + } + ++static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt) ++{ ++ DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); ++ ++ __kvm_adjust_pc(kern_hyp_va(vcpu)); ++} ++ + static void handle___kvm_flush_vm_context(struct kvm_cpu_context *host_ctxt) + { + __kvm_flush_vm_context(); +@@ -112,6 +119,7 @@ typedef void (*hcall_t)(struct kvm_cpu_context *); + + static const hcall_t host_hcall[] = { + HANDLE_FUNC(__kvm_vcpu_run), ++ HANDLE_FUNC(__kvm_adjust_pc), + HANDLE_FUNC(__kvm_flush_vm_context), + HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa), + HANDLE_FUNC(__kvm_tlb_flush_vmid), +diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c +index 7719d632df8df..1754498b07174 100644 +--- a/arch/mips/mm/cache.c ++++ b/arch/mips/mm/cache.c +@@ -157,31 +157,29 @@ unsigned long _page_cachable_default; + EXPORT_SYMBOL(_page_cachable_default); + + #define PM(p) __pgprot(_page_cachable_default | (p)) +-#define PVA(p) PM(_PAGE_VALID | _PAGE_ACCESSED | (p)) + + static inline void setup_protection_map(void) + { + protection_map[0] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ); +- protection_map[1] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC); +- protection_map[2] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ); +- protection_map[3] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC); +- protection_map[4] = PVA(_PAGE_PRESENT); +- protection_map[5] = PVA(_PAGE_PRESENT); +- protection_map[6] = PVA(_PAGE_PRESENT); +- protection_map[7] = PVA(_PAGE_PRESENT); ++ protection_map[1] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC); ++ protection_map[2] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ); ++ protection_map[3] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC); ++ protection_map[4] = PM(_PAGE_PRESENT); ++ protection_map[5] = PM(_PAGE_PRESENT); ++ protection_map[6] = PM(_PAGE_PRESENT); ++ protection_map[7] = PM(_PAGE_PRESENT); + + protection_map[8] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ); +- protection_map[9] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC); +- protection_map[10] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | ++ protection_map[9] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC); ++ protection_map[10] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | + _PAGE_NO_READ); +- protection_map[11] = PVA(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE); +- protection_map[12] = PVA(_PAGE_PRESENT); +- protection_map[13] = PVA(_PAGE_PRESENT); +- protection_map[14] = PVA(_PAGE_PRESENT); +- protection_map[15] = PVA(_PAGE_PRESENT); ++ protection_map[11] = PM(_PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE); ++ protection_map[12] = PM(_PAGE_PRESENT); ++ protection_map[13] = PM(_PAGE_PRESENT); ++ protection_map[14] = PM(_PAGE_PRESENT | _PAGE_WRITE); ++ protection_map[15] = PM(_PAGE_PRESENT | _PAGE_WRITE); + } + +-#undef _PVA + #undef PM + + void cpu_cache_init(void) +diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c +index 01ab2163659e4..e8c2a6373157d 100644 +--- a/arch/powerpc/kernel/kprobes.c ++++ b/arch/powerpc/kernel/kprobes.c +@@ -108,7 +108,6 @@ int arch_prepare_kprobe(struct kprobe *p) + int ret = 0; + struct kprobe *prev; + struct ppc_inst insn = ppc_inst_read((struct ppc_inst *)p->addr); +- struct ppc_inst prefix = ppc_inst_read((struct ppc_inst *)(p->addr - 1)); + + if ((unsigned long)p->addr & 0x03) { + printk("Attempt to register kprobe at an unaligned address\n"); +@@ -116,7 +115,8 @@ int arch_prepare_kprobe(struct kprobe *p) + } else if (IS_MTMSRD(insn) || IS_RFID(insn) || IS_RFI(insn)) { + printk("Cannot register a kprobe on rfi/rfid or mtmsr[d]\n"); + ret = -EINVAL; +- } else if (ppc_inst_prefixed(prefix)) { ++ } else if ((unsigned long)p->addr & ~PAGE_MASK && ++ ppc_inst_prefixed(ppc_inst_read((struct ppc_inst *)(p->addr - 1)))) { + printk("Cannot register a kprobe on the second word of prefixed instruction\n"); + ret = -EINVAL; + } +diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c +index 208a053c9adfd..60c5bc0c130cf 100644 +--- a/arch/powerpc/kvm/book3s_hv.c ++++ b/arch/powerpc/kvm/book3s_hv.c +@@ -4418,7 +4418,6 @@ static int kvmppc_vcpu_run_hv(struct kvm_vcpu *vcpu) + mtspr(SPRN_EBBRR, ebb_regs[1]); + mtspr(SPRN_BESCR, ebb_regs[2]); + mtspr(SPRN_TAR, user_tar); +- mtspr(SPRN_FSCR, current->thread.fscr); + } + mtspr(SPRN_VRSAVE, user_vrsave); + +diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S +index 5e634db4809bf..004f0d4e665f8 100644 +--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S ++++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S +@@ -59,6 +59,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) + #define STACK_SLOT_UAMOR (SFS-88) + #define STACK_SLOT_DAWR1 (SFS-96) + #define STACK_SLOT_DAWRX1 (SFS-104) ++#define STACK_SLOT_FSCR (SFS-112) + /* the following is used by the P9 short path */ + #define STACK_SLOT_NVGPRS (SFS-152) /* 18 gprs */ + +@@ -686,6 +687,8 @@ BEGIN_FTR_SECTION + std r6, STACK_SLOT_DAWR0(r1) + std r7, STACK_SLOT_DAWRX0(r1) + std r8, STACK_SLOT_IAMR(r1) ++ mfspr r5, SPRN_FSCR ++ std r5, STACK_SLOT_FSCR(r1) + END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) + BEGIN_FTR_SECTION + mfspr r6, SPRN_DAWR1 +@@ -1663,6 +1666,10 @@ FTR_SECTION_ELSE + ld r7, STACK_SLOT_HFSCR(r1) + mtspr SPRN_HFSCR, r7 + ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300) ++BEGIN_FTR_SECTION ++ ld r5, STACK_SLOT_FSCR(r1) ++ mtspr SPRN_FSCR, r5 ++END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) + /* + * Restore various registers to 0, where non-zero values + * set by the guest could disrupt the host. +diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile +index ca2b40dfd24b8..24d936c147cdf 100644 +--- a/arch/riscv/kernel/vdso/Makefile ++++ b/arch/riscv/kernel/vdso/Makefile +@@ -23,7 +23,7 @@ ifneq ($(c-gettimeofday-y),) + endif + + # Build rules +-targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds vdso-dummy.o ++targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds vdso-syms.S + obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) + + obj-y += vdso.o vdso-syms.o +@@ -41,7 +41,7 @@ KASAN_SANITIZE := n + $(obj)/vdso.o: $(obj)/vdso.so + + # link rule for the .so file, .lds has to be first +-$(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE ++$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE + $(call if_changed,vdsold) + LDFLAGS_vdso.so.dbg = -shared -s -soname=linux-vdso.so.1 \ + --build-id=sha1 --hash-style=both --eh-frame-hdr +diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h +index 412b51e059c80..48067af946785 100644 +--- a/arch/x86/include/asm/apic.h ++++ b/arch/x86/include/asm/apic.h +@@ -174,6 +174,7 @@ static inline int apic_is_clustered_box(void) + extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask); + extern void lapic_assign_system_vectors(void); + extern void lapic_assign_legacy_vector(unsigned int isairq, bool replace); ++extern void lapic_update_legacy_vectors(void); + extern void lapic_online(void); + extern void lapic_offline(void); + extern bool apic_needs_pit(void); +diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h +index b7dd944dc8673..8f28fafa98b32 100644 +--- a/arch/x86/include/asm/disabled-features.h ++++ b/arch/x86/include/asm/disabled-features.h +@@ -56,11 +56,8 @@ + # define DISABLE_PTI (1 << (X86_FEATURE_PTI & 31)) + #endif + +-#ifdef CONFIG_IOMMU_SUPPORT +-# define DISABLE_ENQCMD 0 +-#else +-# define DISABLE_ENQCMD (1 << (X86_FEATURE_ENQCMD & 31)) +-#endif ++/* Force disable because it's broken beyond repair */ ++#define DISABLE_ENQCMD (1 << (X86_FEATURE_ENQCMD & 31)) + + #ifdef CONFIG_X86_SGX + # define DISABLE_SGX 0 +diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h +index ed33a14188f66..23bef08a83880 100644 +--- a/arch/x86/include/asm/fpu/api.h ++++ b/arch/x86/include/asm/fpu/api.h +@@ -106,10 +106,6 @@ extern int cpu_has_xfeatures(u64 xfeatures_mask, const char **feature_name); + */ + #define PASID_DISABLED 0 + +-#ifdef CONFIG_IOMMU_SUPPORT +-/* Update current's PASID MSR/state by mm's PASID. */ +-void update_pasid(void); +-#else + static inline void update_pasid(void) { } +-#endif ++ + #endif /* _ASM_X86_FPU_API_H */ +diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h +index 8d33ad80704f2..ceeba9f631722 100644 +--- a/arch/x86/include/asm/fpu/internal.h ++++ b/arch/x86/include/asm/fpu/internal.h +@@ -584,13 +584,6 @@ static inline void switch_fpu_finish(struct fpu *new_fpu) + pkru_val = pk->pkru; + } + __write_pkru(pkru_val); +- +- /* +- * Expensive PASID MSR write will be avoided in update_pasid() because +- * TIF_NEED_FPU_LOAD was set. And the PASID state won't be updated +- * unless it's different from mm->pasid to reduce overhead. +- */ +- update_pasid(); + } + + #endif /* _ASM_X86_FPU_INTERNAL_H */ +diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h +index 3381198525126..69299878b200a 100644 +--- a/arch/x86/include/asm/kvm_para.h ++++ b/arch/x86/include/asm/kvm_para.h +@@ -7,8 +7,6 @@ + #include + #include + +-extern void kvmclock_init(void); +- + #ifdef CONFIG_KVM_GUEST + bool kvm_check_and_clear_guest_paused(void); + #else +@@ -86,13 +84,14 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, + } + + #ifdef CONFIG_KVM_GUEST ++void kvmclock_init(void); ++void kvmclock_disable(void); + bool kvm_para_available(void); + unsigned int kvm_arch_para_features(void); + unsigned int kvm_arch_para_hints(void); + void kvm_async_pf_task_wait_schedule(u32 token); + void kvm_async_pf_task_wake(u32 token); + u32 kvm_read_and_reset_apf_flags(void); +-void kvm_disable_steal_time(void); + bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token); + + DECLARE_STATIC_KEY_FALSE(kvm_async_pf_enabled); +@@ -137,11 +136,6 @@ static inline u32 kvm_read_and_reset_apf_flags(void) + return 0; + } + +-static inline void kvm_disable_steal_time(void) +-{ +- return; +-} +- + static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token) + { + return false; +diff --git a/arch/x86/include/asm/thermal.h b/arch/x86/include/asm/thermal.h +index ddbdefd5b94f1..91a7b6687c3b9 100644 +--- a/arch/x86/include/asm/thermal.h ++++ b/arch/x86/include/asm/thermal.h +@@ -3,11 +3,13 @@ + #define _ASM_X86_THERMAL_H + + #ifdef CONFIG_X86_THERMAL_VECTOR ++void therm_lvt_init(void); + void intel_init_thermal(struct cpuinfo_x86 *c); + bool x86_thermal_enabled(void); + void intel_thermal_interrupt(void); + #else +-static inline void intel_init_thermal(struct cpuinfo_x86 *c) { } ++static inline void therm_lvt_init(void) { } ++static inline void intel_init_thermal(struct cpuinfo_x86 *c) { } + #endif + + #endif /* _ASM_X86_THERMAL_H */ +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index 4f26700f314d9..b967a2ba7494a 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -2604,6 +2604,7 @@ static void __init apic_bsp_setup(bool upmode) + end_local_APIC_setup(); + irq_remap_enable_fault_handling(); + setup_IO_APIC(); ++ lapic_update_legacy_vectors(); + } + + #ifdef CONFIG_UP_LATE_INIT +diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c +index 3c9c7492252f8..8c97a3468affa 100644 +--- a/arch/x86/kernel/apic/vector.c ++++ b/arch/x86/kernel/apic/vector.c +@@ -730,6 +730,26 @@ void lapic_assign_legacy_vector(unsigned int irq, bool replace) + irq_matrix_assign_system(vector_matrix, ISA_IRQ_VECTOR(irq), replace); + } + ++void __init lapic_update_legacy_vectors(void) ++{ ++ unsigned int i; ++ ++ if (IS_ENABLED(CONFIG_X86_IO_APIC) && nr_ioapics > 0) ++ return; ++ ++ /* ++ * If the IO/APIC is disabled via config, kernel command line or ++ * lack of enumeration then all legacy interrupts are routed ++ * through the PIC. Make sure that they are marked as legacy ++ * vectors. PIC_CASCADE_IRQ has already been marked in ++ * lapic_assign_system_vectors(). ++ */ ++ for (i = 0; i < nr_legacy_irqs(); i++) { ++ if (i != PIC_CASCADE_IR) ++ lapic_assign_legacy_vector(i, true); ++ } ++} ++ + void __init lapic_assign_system_vectors(void) + { + unsigned int i, vector = 0; +diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c +index 683749b80ae28..2ad57cc14b83f 100644 +--- a/arch/x86/kernel/fpu/xstate.c ++++ b/arch/x86/kernel/fpu/xstate.c +@@ -1402,60 +1402,3 @@ int proc_pid_arch_status(struct seq_file *m, struct pid_namespace *ns, + return 0; + } + #endif /* CONFIG_PROC_PID_ARCH_STATUS */ +- +-#ifdef CONFIG_IOMMU_SUPPORT +-void update_pasid(void) +-{ +- u64 pasid_state; +- u32 pasid; +- +- if (!cpu_feature_enabled(X86_FEATURE_ENQCMD)) +- return; +- +- if (!current->mm) +- return; +- +- pasid = READ_ONCE(current->mm->pasid); +- /* Set the valid bit in the PASID MSR/state only for valid pasid. */ +- pasid_state = pasid == PASID_DISABLED ? +- pasid : pasid | MSR_IA32_PASID_VALID; +- +- /* +- * No need to hold fregs_lock() since the task's fpstate won't +- * be changed by others (e.g. ptrace) while the task is being +- * switched to or is in IPI. +- */ +- if (!test_thread_flag(TIF_NEED_FPU_LOAD)) { +- /* The MSR is active and can be directly updated. */ +- wrmsrl(MSR_IA32_PASID, pasid_state); +- } else { +- struct fpu *fpu = ¤t->thread.fpu; +- struct ia32_pasid_state *ppasid_state; +- struct xregs_state *xsave; +- +- /* +- * The CPU's xstate registers are not currently active. Just +- * update the PASID state in the memory buffer here. The +- * PASID MSR will be loaded when returning to user mode. +- */ +- xsave = &fpu->state.xsave; +- xsave->header.xfeatures |= XFEATURE_MASK_PASID; +- ppasid_state = get_xsave_addr(xsave, XFEATURE_PASID); +- /* +- * Since XFEATURE_MASK_PASID is set in xfeatures, ppasid_state +- * won't be NULL and no need to check its value. +- * +- * Only update the task's PASID state when it's different +- * from the mm's pasid. +- */ +- if (ppasid_state->pasid != pasid_state) { +- /* +- * Invalid fpregs so that state restoring will pick up +- * the PASID state. +- */ +- __fpu_invalidate_fpregs_state(fpu); +- ppasid_state->pasid = pasid_state; +- } +- } +-} +-#endif /* CONFIG_IOMMU_SUPPORT */ +diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c +index 78bb0fae39826..919411a0117df 100644 +--- a/arch/x86/kernel/kvm.c ++++ b/arch/x86/kernel/kvm.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -37,6 +38,7 @@ + #include + #include + #include ++#include + #include + + DEFINE_STATIC_KEY_FALSE(kvm_async_pf_enabled); +@@ -374,6 +376,14 @@ static void kvm_pv_disable_apf(void) + pr_info("Unregister pv shared memory for cpu %d\n", smp_processor_id()); + } + ++static void kvm_disable_steal_time(void) ++{ ++ if (!has_steal_clock) ++ return; ++ ++ wrmsr(MSR_KVM_STEAL_TIME, 0, 0); ++} ++ + static void kvm_pv_guest_cpu_reboot(void *unused) + { + /* +@@ -416,14 +426,6 @@ static u64 kvm_steal_clock(int cpu) + return steal; + } + +-void kvm_disable_steal_time(void) +-{ +- if (!has_steal_clock) +- return; +- +- wrmsr(MSR_KVM_STEAL_TIME, 0, 0); +-} +- + static inline void __set_percpu_decrypted(void *ptr, unsigned long size) + { + early_set_memory_decrypted((unsigned long) ptr, size); +@@ -460,6 +462,27 @@ static bool pv_tlb_flush_supported(void) + + static DEFINE_PER_CPU(cpumask_var_t, __pv_cpu_mask); + ++static void kvm_guest_cpu_offline(bool shutdown) ++{ ++ kvm_disable_steal_time(); ++ if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) ++ wrmsrl(MSR_KVM_PV_EOI_EN, 0); ++ kvm_pv_disable_apf(); ++ if (!shutdown) ++ apf_task_wake_all(); ++ kvmclock_disable(); ++} ++ ++static int kvm_cpu_online(unsigned int cpu) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ kvm_guest_cpu_init(); ++ local_irq_restore(flags); ++ return 0; ++} ++ + #ifdef CONFIG_SMP + + static bool pv_ipi_supported(void) +@@ -587,29 +610,46 @@ static void __init kvm_smp_prepare_boot_cpu(void) + kvm_spinlock_init(); + } + +-static void kvm_guest_cpu_offline(void) ++static int kvm_cpu_down_prepare(unsigned int cpu) + { +- kvm_disable_steal_time(); +- if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) +- wrmsrl(MSR_KVM_PV_EOI_EN, 0); +- kvm_pv_disable_apf(); +- apf_task_wake_all(); ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ kvm_guest_cpu_offline(false); ++ local_irq_restore(flags); ++ return 0; + } + +-static int kvm_cpu_online(unsigned int cpu) ++#endif ++ ++static int kvm_suspend(void) + { +- local_irq_disable(); +- kvm_guest_cpu_init(); +- local_irq_enable(); ++ kvm_guest_cpu_offline(false); ++ + return 0; + } + +-static int kvm_cpu_down_prepare(unsigned int cpu) ++static void kvm_resume(void) + { +- local_irq_disable(); +- kvm_guest_cpu_offline(); +- local_irq_enable(); +- return 0; ++ kvm_cpu_online(raw_smp_processor_id()); ++} ++ ++static struct syscore_ops kvm_syscore_ops = { ++ .suspend = kvm_suspend, ++ .resume = kvm_resume, ++}; ++ ++/* ++ * After a PV feature is registered, the host will keep writing to the ++ * registered memory location. If the guest happens to shutdown, this memory ++ * won't be valid. In cases like kexec, in which you install a new kernel, this ++ * means a random memory location will be kept being written. ++ */ ++#ifdef CONFIG_KEXEC_CORE ++static void kvm_crash_shutdown(struct pt_regs *regs) ++{ ++ kvm_guest_cpu_offline(true); ++ native_machine_crash_shutdown(regs); + } + #endif + +@@ -681,6 +721,12 @@ static void __init kvm_guest_init(void) + kvm_guest_cpu_init(); + #endif + ++#ifdef CONFIG_KEXEC_CORE ++ machine_ops.crash_shutdown = kvm_crash_shutdown; ++#endif ++ ++ register_syscore_ops(&kvm_syscore_ops); ++ + /* + * Hard lockup detection is enabled by default. Disable it, as guests + * can get false positives too easily, for example if the host is +diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c +index 1fc0962c89c08..b825c87c12ef7 100644 +--- a/arch/x86/kernel/kvmclock.c ++++ b/arch/x86/kernel/kvmclock.c +@@ -20,7 +20,6 @@ + #include + #include + #include +-#include + #include + + static int kvmclock __initdata = 1; +@@ -203,28 +202,9 @@ static void kvm_setup_secondary_clock(void) + } + #endif + +-/* +- * After the clock is registered, the host will keep writing to the +- * registered memory location. If the guest happens to shutdown, this memory +- * won't be valid. In cases like kexec, in which you install a new kernel, this +- * means a random memory location will be kept being written. So before any +- * kind of shutdown from our side, we unregister the clock by writing anything +- * that does not have the 'enable' bit set in the msr +- */ +-#ifdef CONFIG_KEXEC_CORE +-static void kvm_crash_shutdown(struct pt_regs *regs) +-{ +- native_write_msr(msr_kvm_system_time, 0, 0); +- kvm_disable_steal_time(); +- native_machine_crash_shutdown(regs); +-} +-#endif +- +-static void kvm_shutdown(void) ++void kvmclock_disable(void) + { + native_write_msr(msr_kvm_system_time, 0, 0); +- kvm_disable_steal_time(); +- native_machine_shutdown(); + } + + static void __init kvmclock_init_mem(void) +@@ -351,10 +331,6 @@ void __init kvmclock_init(void) + #endif + x86_platform.save_sched_clock_state = kvm_save_sched_clock_state; + x86_platform.restore_sched_clock_state = kvm_restore_sched_clock_state; +- machine_ops.shutdown = kvm_shutdown; +-#ifdef CONFIG_KEXEC_CORE +- machine_ops.crash_shutdown = kvm_crash_shutdown; +-#endif + kvm_get_preset_lpj(); + + /* +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index ccab6cf91283d..e79f21d13a0d7 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1220,6 +1221,14 @@ void __init setup_arch(char **cmdline_p) + + x86_init.timers.wallclock_init(); + ++ /* ++ * This needs to run before setup_local_APIC() which soft-disables the ++ * local APIC temporarily and that masks the thermal LVT interrupt, ++ * leading to softlockups on machines which have configured SMI ++ * interrupt delivery. ++ */ ++ therm_lvt_init(); ++ + mcheck_init(); + + register_refined_jiffies(CLOCK_TICK_RATE); +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index 9a6825feaf53f..30569bbbca9ac 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -2532,7 +2532,7 @@ static int cr_interception(struct vcpu_svm *svm) + err = 0; + if (cr >= 16) { /* mov to cr */ + cr -= 16; +- val = kvm_register_read(&svm->vcpu, reg); ++ val = kvm_register_readl(&svm->vcpu, reg); + trace_kvm_cr_write(cr, val); + switch (cr) { + case 0: +@@ -2578,7 +2578,7 @@ static int cr_interception(struct vcpu_svm *svm) + kvm_queue_exception(&svm->vcpu, UD_VECTOR); + return 1; + } +- kvm_register_write(&svm->vcpu, reg, val); ++ kvm_register_writel(&svm->vcpu, reg, val); + trace_kvm_cr_read(cr, val); + } + return kvm_complete_insn_gp(&svm->vcpu, err); +@@ -2643,11 +2643,11 @@ static int dr_interception(struct vcpu_svm *svm) + dr = svm->vmcb->control.exit_code - SVM_EXIT_READ_DR0; + if (dr >= 16) { /* mov to DRn */ + dr -= 16; +- val = kvm_register_read(&svm->vcpu, reg); ++ val = kvm_register_readl(&svm->vcpu, reg); + err = kvm_set_dr(&svm->vcpu, dr, val); + } else { + kvm_get_dr(&svm->vcpu, dr, &val); +- kvm_register_write(&svm->vcpu, reg, val); ++ kvm_register_writel(&svm->vcpu, reg, val); + } + + return kvm_complete_insn_gp(&svm->vcpu, err); +diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c +index a73347e2cdfc5..ea3d0b73731bc 100644 +--- a/arch/x86/mm/fault.c ++++ b/arch/x86/mm/fault.c +@@ -836,8 +836,8 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, + + if (si_code == SEGV_PKUERR) + force_sig_pkuerr((void __user *)address, pkey); +- +- force_sig_fault(SIGSEGV, si_code, (void __user *)address); ++ else ++ force_sig_fault(SIGSEGV, si_code, (void __user *)address); + + local_irq_disable(); + } +diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c +index a19374d261013..65f599e9075bc 100644 +--- a/arch/x86/mm/mem_encrypt_identity.c ++++ b/arch/x86/mm/mem_encrypt_identity.c +@@ -504,10 +504,6 @@ void __init sme_enable(struct boot_params *bp) + #define AMD_SME_BIT BIT(0) + #define AMD_SEV_BIT BIT(1) + +- /* Check the SEV MSR whether SEV or SME is enabled */ +- sev_status = __rdmsr(MSR_AMD64_SEV); +- feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT; +- + /* + * Check for the SME/SEV feature: + * CPUID Fn8000_001F[EAX] +@@ -519,11 +515,16 @@ void __init sme_enable(struct boot_params *bp) + eax = 0x8000001f; + ecx = 0; + native_cpuid(&eax, &ebx, &ecx, &edx); +- if (!(eax & feature_mask)) ++ /* Check whether SEV or SME is supported */ ++ if (!(eax & (AMD_SEV_BIT | AMD_SME_BIT))) + return; + + me_mask = 1UL << (ebx & 0x3f); + ++ /* Check the SEV MSR whether SEV or SME is enabled */ ++ sev_status = __rdmsr(MSR_AMD64_SEV); ++ feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT; ++ + /* Check if memory encryption is enabled */ + if (feature_mask == AMD_SME_BIT) { + /* +diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c +index 624a26794d558..e5ba9795ec696 100644 +--- a/drivers/acpi/acpica/utdelete.c ++++ b/drivers/acpi/acpica/utdelete.c +@@ -285,6 +285,14 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) + } + break; + ++ case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: ++ ++ ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, ++ "***** Address handler %p\n", object)); ++ ++ acpi_os_delete_mutex(object->address_space.context_mutex); ++ break; ++ + default: + + break; +diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c +index 68145e326eb90..30e9b700273e1 100644 +--- a/drivers/bus/ti-sysc.c ++++ b/drivers/bus/ti-sysc.c +@@ -1334,6 +1334,34 @@ err_allow_idle: + return error; + } + ++static int sysc_reinit_module(struct sysc *ddata, bool leave_enabled) ++{ ++ struct device *dev = ddata->dev; ++ int error; ++ ++ /* Disable target module if it is enabled */ ++ if (ddata->enabled) { ++ error = sysc_runtime_suspend(dev); ++ if (error) ++ dev_warn(dev, "reinit suspend failed: %i\n", error); ++ } ++ ++ /* Enable target module */ ++ error = sysc_runtime_resume(dev); ++ if (error) ++ dev_warn(dev, "reinit resume failed: %i\n", error); ++ ++ if (leave_enabled) ++ return error; ++ ++ /* Disable target module if no leave_enabled was set */ ++ error = sysc_runtime_suspend(dev); ++ if (error) ++ dev_warn(dev, "reinit suspend failed: %i\n", error); ++ ++ return error; ++} ++ + static int __maybe_unused sysc_noirq_suspend(struct device *dev) + { + struct sysc *ddata; +@@ -1344,12 +1372,18 @@ static int __maybe_unused sysc_noirq_suspend(struct device *dev) + (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE)) + return 0; + +- return pm_runtime_force_suspend(dev); ++ if (!ddata->enabled) ++ return 0; ++ ++ ddata->needs_resume = 1; ++ ++ return sysc_runtime_suspend(dev); + } + + static int __maybe_unused sysc_noirq_resume(struct device *dev) + { + struct sysc *ddata; ++ int error = 0; + + ddata = dev_get_drvdata(dev); + +@@ -1357,7 +1391,19 @@ static int __maybe_unused sysc_noirq_resume(struct device *dev) + (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE)) + return 0; + +- return pm_runtime_force_resume(dev); ++ if (ddata->cfg.quirks & SYSC_QUIRK_REINIT_ON_RESUME) { ++ error = sysc_reinit_module(ddata, ddata->needs_resume); ++ if (error) ++ dev_warn(dev, "noirq_resume failed: %i\n", error); ++ } else if (ddata->needs_resume) { ++ error = sysc_runtime_resume(dev); ++ if (error) ++ dev_warn(dev, "noirq_resume failed: %i\n", error); ++ } ++ ++ ddata->needs_resume = 0; ++ ++ return error; + } + + static const struct dev_pm_ops sysc_pm_ops = { +@@ -1408,9 +1454,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { + SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + /* Uarts on omap4 and later */ + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, +- SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), ++ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, +- SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), ++ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + + /* Quirks that need to be set based on the module address */ + SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, +@@ -1466,7 +1512,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { + SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050, + 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), + SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -ENODEV, 0x4ea2080d, 0xffffffff, +- SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), ++ SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY | ++ SYSC_QUIRK_REINIT_ON_RESUME), + SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, + SYSC_MODULE_QUIRK_WDT), + /* PRUSS on am3, am4 and am5 */ +diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c +index 07cf7977a0450..59f2104ffc771 100644 +--- a/drivers/dma/idxd/init.c ++++ b/drivers/dma/idxd/init.c +@@ -675,12 +675,12 @@ static int __init idxd_init_module(void) + * If the CPU does not support MOVDIR64B or ENQCMDS, there's no point in + * enumerating the device. We can not utilize it. + */ +- if (!boot_cpu_has(X86_FEATURE_MOVDIR64B)) { ++ if (!cpu_feature_enabled(X86_FEATURE_MOVDIR64B)) { + pr_warn("idxd driver failed to load without MOVDIR64B.\n"); + return -ENODEV; + } + +- if (!boot_cpu_has(X86_FEATURE_ENQCMD)) ++ if (!cpu_feature_enabled(X86_FEATURE_ENQCMD)) + pr_warn("Platform does not have ENQCMD(S) support.\n"); + else + support_enqcmd = true; +diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c +index e15d484b6a5a7..ea7ca74fc1730 100644 +--- a/drivers/firmware/efi/cper.c ++++ b/drivers/firmware/efi/cper.c +@@ -276,8 +276,7 @@ static int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg) + if (!msg || !(mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE)) + return 0; + +- n = 0; +- len = CPER_REC_LEN - 1; ++ len = CPER_REC_LEN; + dmi_memdev_name(mem->mem_dev_handle, &bank, &device); + if (bank && device) + n = snprintf(msg, len, "DIMM location: %s %s ", bank, device); +@@ -286,7 +285,6 @@ static int cper_dimm_err_location(struct cper_mem_err_compact *mem, char *msg) + "DIMM location: not present. DMI handle: 0x%.4x ", + mem->mem_dev_handle); + +- msg[n] = '\0'; + return n; + } + +diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c +index bb042ab7c2be6..e901f8564ca0c 100644 +--- a/drivers/firmware/efi/fdtparams.c ++++ b/drivers/firmware/efi/fdtparams.c +@@ -98,6 +98,9 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) + BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); + BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(dt_params[0].params)); + ++ if (!fdt) ++ return 0; ++ + for (i = 0; i < ARRAY_SIZE(dt_params); i++) { + node = fdt_path_offset(fdt, dt_params[i].path); + if (node < 0) +diff --git a/drivers/firmware/efi/libstub/file.c b/drivers/firmware/efi/libstub/file.c +index 4e81c6077188e..dd95f330fe6e1 100644 +--- a/drivers/firmware/efi/libstub/file.c ++++ b/drivers/firmware/efi/libstub/file.c +@@ -103,7 +103,7 @@ static int find_file_option(const efi_char16_t *cmdline, int cmdline_len, + return 0; + + /* Skip any leading slashes */ +- while (cmdline[i] == L'/' || cmdline[i] == L'\\') ++ while (i < cmdline_len && (cmdline[i] == L'/' || cmdline[i] == L'\\')) + i++; + + while (--result_len > 0 && i < cmdline_len) { +diff --git a/drivers/firmware/efi/memattr.c b/drivers/firmware/efi/memattr.c +index 5737cb0fcd44e..0a9aba5f9ceff 100644 +--- a/drivers/firmware/efi/memattr.c ++++ b/drivers/firmware/efi/memattr.c +@@ -67,11 +67,6 @@ static bool entry_is_valid(const efi_memory_desc_t *in, efi_memory_desc_t *out) + return false; + } + +- if (!(in->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP))) { +- pr_warn("Entry attributes invalid: RO and XP bits both cleared\n"); +- return false; +- } +- + if (PAGE_SIZE > EFI_PAGE_SIZE && + (!PAGE_ALIGNED(in->phys_addr) || + !PAGE_ALIGNED(in->num_pages << EFI_PAGE_SHIFT))) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +index 0350205c48974..6819fe5612d9e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +@@ -337,7 +337,6 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev, + { + struct amdgpu_ctx *ctx; + struct amdgpu_ctx_mgr *mgr; +- unsigned long ras_counter; + + if (!fpriv) + return -EINVAL; +@@ -362,21 +361,6 @@ static int amdgpu_ctx_query2(struct amdgpu_device *adev, + if (atomic_read(&ctx->guilty)) + out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY; + +- /*query ue count*/ +- ras_counter = amdgpu_ras_query_error_count(adev, false); +- /*ras counter is monotonic increasing*/ +- if (ras_counter != ctx->ras_counter_ue) { +- out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_UE; +- ctx->ras_counter_ue = ras_counter; +- } +- +- /*query ce count*/ +- ras_counter = amdgpu_ras_query_error_count(adev, true); +- if (ras_counter != ctx->ras_counter_ce) { +- out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_CE; +- ctx->ras_counter_ce = ras_counter; +- } +- + mutex_unlock(&mgr->lock); + return 0; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +index a2ac44cc2a6da..e80cc2928b583 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +@@ -944,6 +944,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, + domains = amdgpu_display_supported_domains(drm_to_adev(dev), bo->flags); + if (obj->import_attach && !(domains & AMDGPU_GEM_DOMAIN_GTT)) { + drm_dbg_kms(dev, "Cannot create framebuffer from imported dma_buf\n"); ++ drm_gem_object_put(obj); + return ERR_PTR(-EINVAL); + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c +index dc947c8ffe213..e6c4a36eaf9ae 100644 +--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c ++++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c +@@ -187,14 +187,14 @@ static int jpeg_v2_5_hw_init(void *handle) + static int jpeg_v2_5_hw_fini(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; +- struct amdgpu_ring *ring; + int i; + ++ cancel_delayed_work_sync(&adev->vcn.idle_work); ++ + for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) { + if (adev->jpeg.harvest_config & (1 << i)) + continue; + +- ring = &adev->jpeg.inst[i].ring_dec; + if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && + RREG32_SOC15(JPEG, i, mmUVD_JRBC_STATUS)) + jpeg_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE); +diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c +index 1d354245678d5..2ea68c84e6b48 100644 +--- a/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c +@@ -159,9 +159,9 @@ static int jpeg_v3_0_hw_init(void *handle) + static int jpeg_v3_0_hw_fini(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; +- struct amdgpu_ring *ring; + +- ring = &adev->jpeg.inst->ring_dec; ++ cancel_delayed_work_sync(&adev->vcn.idle_work); ++ + if (adev->jpeg.cur_state != AMD_PG_STATE_GATE && + RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS)) + jpeg_v3_0_set_powergating_state(adev, AMD_PG_STATE_GATE); +diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +index 760859880c1ed..4eebf973a0658 100644 +--- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +@@ -357,6 +357,7 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) + + error: + dma_fence_put(fence); ++ amdgpu_bo_unpin(bo); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); + return r; +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +index ebbc04ff5da06..90138469648a9 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +@@ -367,15 +367,14 @@ done: + static int vcn_v3_0_hw_fini(void *handle) + { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; +- struct amdgpu_ring *ring; + int i; + ++ cancel_delayed_work_sync(&adev->vcn.idle_work); ++ + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { + if (adev->vcn.harvest_config & (1 << i)) + continue; + +- ring = &adev->vcn.inst[i].ring_dec; +- + if (!amdgpu_sriov_vf(adev)) { + if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || + (adev->vcn.cur_state != AMD_PG_STATE_GATE && +diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c +index d2a678a2497e4..411494005f0ec 100644 +--- a/drivers/gpu/drm/i915/selftests/i915_request.c ++++ b/drivers/gpu/drm/i915/selftests/i915_request.c +@@ -1392,8 +1392,8 @@ static int live_breadcrumbs_smoketest(void *arg) + + for (n = 0; n < smoke[0].ncontexts; n++) { + smoke[0].contexts[n] = live_context(i915, file); +- if (!smoke[0].contexts[n]) { +- ret = -ENOMEM; ++ if (IS_ERR(smoke[0].contexts[n])) { ++ ret = PTR_ERR(smoke[0].contexts[n]); + goto out_contexts; + } + } +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +index 85f2c3564c966..fb061e666faa7 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +@@ -933,8 +933,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) + DPU_DEBUG("REG_DMA is not defined"); + } + +- if (of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) +- dpu_kms_parse_data_bus_icc_path(dpu_kms); ++ dpu_kms_parse_data_bus_icc_path(dpu_kms); + + pm_runtime_get_sync(&dpu_kms->pdev->dev); + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +index cd4078807db1b..3416e9617ee9a 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +@@ -31,40 +31,8 @@ struct dpu_mdss { + void __iomem *mmio; + struct dss_module_power mp; + struct dpu_irq_controller irq_controller; +- struct icc_path *path[2]; +- u32 num_paths; + }; + +-static int dpu_mdss_parse_data_bus_icc_path(struct drm_device *dev, +- struct dpu_mdss *dpu_mdss) +-{ +- struct icc_path *path0 = of_icc_get(dev->dev, "mdp0-mem"); +- struct icc_path *path1 = of_icc_get(dev->dev, "mdp1-mem"); +- +- if (IS_ERR_OR_NULL(path0)) +- return PTR_ERR_OR_ZERO(path0); +- +- dpu_mdss->path[0] = path0; +- dpu_mdss->num_paths = 1; +- +- if (!IS_ERR_OR_NULL(path1)) { +- dpu_mdss->path[1] = path1; +- dpu_mdss->num_paths++; +- } +- +- return 0; +-} +- +-static void dpu_mdss_icc_request_bw(struct msm_mdss *mdss) +-{ +- struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); +- int i; +- u64 avg_bw = dpu_mdss->num_paths ? MAX_BW / dpu_mdss->num_paths : 0; +- +- for (i = 0; i < dpu_mdss->num_paths; i++) +- icc_set_bw(dpu_mdss->path[i], avg_bw, kBps_to_icc(MAX_BW)); +-} +- + static void dpu_mdss_irq(struct irq_desc *desc) + { + struct dpu_mdss *dpu_mdss = irq_desc_get_handler_data(desc); +@@ -178,8 +146,6 @@ static int dpu_mdss_enable(struct msm_mdss *mdss) + struct dss_module_power *mp = &dpu_mdss->mp; + int ret; + +- dpu_mdss_icc_request_bw(mdss); +- + ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); + if (ret) { + DPU_ERROR("clock enable failed, ret:%d\n", ret); +@@ -213,15 +179,12 @@ static int dpu_mdss_disable(struct msm_mdss *mdss) + { + struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss); + struct dss_module_power *mp = &dpu_mdss->mp; +- int ret, i; ++ int ret; + + ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false); + if (ret) + DPU_ERROR("clock disable failed, ret:%d\n", ret); + +- for (i = 0; i < dpu_mdss->num_paths; i++) +- icc_set_bw(dpu_mdss->path[i], 0, 0); +- + return ret; + } + +@@ -232,7 +195,6 @@ static void dpu_mdss_destroy(struct drm_device *dev) + struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss); + struct dss_module_power *mp = &dpu_mdss->mp; + int irq; +- int i; + + pm_runtime_suspend(dev->dev); + pm_runtime_disable(dev->dev); +@@ -242,9 +204,6 @@ static void dpu_mdss_destroy(struct drm_device *dev) + msm_dss_put_clk(mp->clk_config, mp->num_clk); + devm_kfree(&pdev->dev, mp->clk_config); + +- for (i = 0; i < dpu_mdss->num_paths; i++) +- icc_put(dpu_mdss->path[i]); +- + if (dpu_mdss->mmio) + devm_iounmap(&pdev->dev, dpu_mdss->mmio); + dpu_mdss->mmio = NULL; +@@ -276,12 +235,6 @@ int dpu_mdss_init(struct drm_device *dev) + + DRM_DEBUG("mapped mdss address space @%pK\n", dpu_mdss->mmio); + +- if (!of_device_is_compatible(dev->dev->of_node, "qcom,sc7180-mdss")) { +- ret = dpu_mdss_parse_data_bus_icc_path(dev, dpu_mdss); +- if (ret) +- return ret; +- } +- + mp = &dpu_mdss->mp; + ret = msm_dss_parse_clock(pdev, mp); + if (ret) { +@@ -307,8 +260,6 @@ int dpu_mdss_init(struct drm_device *dev) + + pm_runtime_enable(dev->dev); + +- dpu_mdss_icc_request_bw(priv->mdss); +- + return ret; + + irq_error: +diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c +index 2ab38b7153477..ea9a4913932d6 100644 +--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c ++++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c +@@ -88,6 +88,7 @@ static void amd_sfh_work(struct work_struct *work) + sensor_index = req_node->sensor_idx; + report_id = req_node->report_id; + node_type = req_node->report_type; ++ kfree(req_node); + + if (node_type == HID_FEATURE_REPORT) { + report_size = get_feature_report(sensor_index, report_id, +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index d459e2dbe6474..f7710fb2f48d2 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -1262,6 +1262,7 @@ static int hidpp20_battery_map_status_voltage(u8 data[3], int *voltage, + int status; + + long flags = (long) data[2]; ++ *level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; + + if (flags & 0x80) + switch (flags & 0x07) { +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index abd86903875f0..fc4c074597539 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -597,7 +597,7 @@ static int magicmouse_probe(struct hid_device *hdev, + if (id->vendor == USB_VENDOR_ID_APPLE && + id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && + hdev->type != HID_TYPE_USBMOUSE) +- return 0; ++ return -ENODEV; + + msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); + if (msc == NULL) { +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 9d9f3e1bd5f41..55dcb8536286b 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -604,9 +604,13 @@ static struct mt_report_data *mt_allocate_report_data(struct mt_device *td, + if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) + continue; + +- for (n = 0; n < field->report_count; n++) { +- if (field->usage[n].hid == HID_DG_CONTACTID) +- rdata->is_mt_collection = true; ++ if (field->logical == HID_DG_FINGER || td->hdev->group != HID_GROUP_MULTITOUCH_WIN_8) { ++ for (n = 0; n < field->report_count; n++) { ++ if (field->usage[n].hid == HID_DG_CONTACTID) { ++ rdata->is_mt_collection = true; ++ break; ++ } ++ } + } + } + +diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c +index 9993133989a58..46474612e73c6 100644 +--- a/drivers/hid/i2c-hid/i2c-hid-core.c ++++ b/drivers/hid/i2c-hid/i2c-hid-core.c +@@ -45,6 +45,7 @@ + #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) + #define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) + #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6) ++#define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(7) + + + /* flags */ +@@ -178,6 +179,11 @@ static const struct i2c_hid_quirks { + I2C_HID_QUIRK_RESET_ON_RESUME }, + { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720, + I2C_HID_QUIRK_BAD_INPUT_SIZE }, ++ /* ++ * Sending the wakeup after reset actually break ELAN touchscreen controller ++ */ ++ { USB_VENDOR_ID_ELAN, HID_ANY_ID, ++ I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET }, + { 0, 0 } + }; + +@@ -461,7 +467,8 @@ static int i2c_hid_hwreset(struct i2c_client *client) + } + + /* At least some SIS devices need this after reset */ +- ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); ++ if (!(ihid->quirks & I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET)) ++ ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); + + out_unlock: + mutex_unlock(&ihid->reset_lock); +@@ -990,8 +997,8 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, + hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); + hid->product = le16_to_cpu(ihid->hdesc.wProductID); + +- snprintf(hid->name, sizeof(hid->name), "%s %04hX:%04hX", +- client->name, hid->vendor, hid->product); ++ snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", ++ client->name, (u16)hid->vendor, (u16)hid->product); + strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys)); + + ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); +diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c +index fddac7c72f645..07a9fe97d2e05 100644 +--- a/drivers/hid/usbhid/hid-pidff.c ++++ b/drivers/hid/usbhid/hid-pidff.c +@@ -1292,6 +1292,7 @@ int hid_pidff_init(struct hid_device *hid) + + if (pidff->pool[PID_DEVICE_MANAGED_POOL].value && + pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) { ++ error = -EPERM; + hid_notice(hid, + "device does not support device managed pool\n"); + goto fail; +diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c +index 73b9db9e3aab6..63b74e781c5d9 100644 +--- a/drivers/hwmon/dell-smm-hwmon.c ++++ b/drivers/hwmon/dell-smm-hwmon.c +@@ -838,10 +838,10 @@ static struct attribute *i8k_attrs[] = { + static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, + int index) + { +- if (disallow_fan_support && index >= 8) ++ if (disallow_fan_support && index >= 20) + return 0; + if (disallow_fan_type_call && +- (index == 9 || index == 12 || index == 15)) ++ (index == 21 || index == 25 || index == 28)) + return 0; + if (index >= 0 && index <= 1 && + !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1)) +diff --git a/drivers/hwmon/pmbus/isl68137.c b/drivers/hwmon/pmbus/isl68137.c +index 2bee930d39002..789242ed72e5d 100644 +--- a/drivers/hwmon/pmbus/isl68137.c ++++ b/drivers/hwmon/pmbus/isl68137.c +@@ -244,8 +244,8 @@ static int isl68137_probe(struct i2c_client *client) + info->read_word_data = raa_dmpvr2_read_word_data; + break; + case raa_dmpvr2_2rail_nontc: +- info->func[0] &= ~PMBUS_HAVE_TEMP; +- info->func[1] &= ~PMBUS_HAVE_TEMP; ++ info->func[0] &= ~PMBUS_HAVE_TEMP3; ++ info->func[1] &= ~PMBUS_HAVE_TEMP3; + fallthrough; + case raa_dmpvr2_2rail: + info->pages = 2; +diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c +index 214b4c913a139..671f4a52275ec 100644 +--- a/drivers/i2c/busses/i2c-qcom-geni.c ++++ b/drivers/i2c/busses/i2c-qcom-geni.c +@@ -650,6 +650,14 @@ static int geni_i2c_remove(struct platform_device *pdev) + return 0; + } + ++static void geni_i2c_shutdown(struct platform_device *pdev) ++{ ++ struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev); ++ ++ /* Make client i2c transfers start failing */ ++ i2c_mark_adapter_suspended(&gi2c->adap); ++} ++ + static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev) + { + int ret; +@@ -690,6 +698,8 @@ static int __maybe_unused geni_i2c_suspend_noirq(struct device *dev) + { + struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); + ++ i2c_mark_adapter_suspended(&gi2c->adap); ++ + if (!gi2c->suspended) { + geni_i2c_runtime_suspend(dev); + pm_runtime_disable(dev); +@@ -699,8 +709,16 @@ static int __maybe_unused geni_i2c_suspend_noirq(struct device *dev) + return 0; + } + ++static int __maybe_unused geni_i2c_resume_noirq(struct device *dev) ++{ ++ struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); ++ ++ i2c_mark_adapter_resumed(&gi2c->adap); ++ return 0; ++} ++ + static const struct dev_pm_ops geni_i2c_pm_ops = { +- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(geni_i2c_suspend_noirq, NULL) ++ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(geni_i2c_suspend_noirq, geni_i2c_resume_noirq) + SET_RUNTIME_PM_OPS(geni_i2c_runtime_suspend, geni_i2c_runtime_resume, + NULL) + }; +@@ -714,6 +732,7 @@ MODULE_DEVICE_TABLE(of, geni_i2c_dt_match); + static struct platform_driver geni_i2c_driver = { + .probe = geni_i2c_probe, + .remove = geni_i2c_remove, ++ .shutdown = geni_i2c_shutdown, + .driver = { + .name = "geni_i2c", + .pm = &geni_i2c_pm_ops, +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +index 314f8d8067231..9058f09f921ee 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +@@ -2177,8 +2177,6 @@ int cxgb4_update_mac_filt(struct port_info *pi, unsigned int viid, + bool persistent, u8 *smt_idx); + int cxgb4_get_msix_idx_from_bmap(struct adapter *adap); + void cxgb4_free_msix_idx_in_bmap(struct adapter *adap, u32 msix_idx); +-int cxgb_open(struct net_device *dev); +-int cxgb_close(struct net_device *dev); + void cxgb4_enable_rx(struct adapter *adap, struct sge_rspq *q); + void cxgb4_quiesce_rx(struct sge_rspq *q); + int cxgb4_port_mirror_alloc(struct net_device *dev); +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +index 421bd9b88028d..1f601de02e706 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +@@ -2834,7 +2834,7 @@ static void cxgb_down(struct adapter *adapter) + /* + * net_device operations + */ +-int cxgb_open(struct net_device *dev) ++static int cxgb_open(struct net_device *dev) + { + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; +@@ -2882,7 +2882,7 @@ out_unlock: + return err; + } + +-int cxgb_close(struct net_device *dev) ++static int cxgb_close(struct net_device *dev) + { + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c +index 1b88bd1c2dbe4..dd9be229819a5 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c +@@ -997,20 +997,16 @@ int cxgb4_tc_flower_destroy(struct net_device *dev, + if (!ch_flower) + return -ENOENT; + ++ rhashtable_remove_fast(&adap->flower_tbl, &ch_flower->node, ++ adap->flower_ht_params); ++ + ret = cxgb4_flow_rule_destroy(dev, ch_flower->fs.tc_prio, + &ch_flower->fs, ch_flower->filter_id); + if (ret) +- goto err; ++ netdev_err(dev, "Flow rule destroy failed for tid: %u, ret: %d", ++ ch_flower->filter_id, ret); + +- ret = rhashtable_remove_fast(&adap->flower_tbl, &ch_flower->node, +- adap->flower_ht_params); +- if (ret) { +- netdev_err(dev, "Flow remove from rhashtable failed"); +- goto err; +- } + kfree_rcu(ch_flower, rcu); +- +-err: + return ret; + } + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_mqprio.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_mqprio.c +index 6c259de96f969..338b04f339b3d 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_mqprio.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_mqprio.c +@@ -589,7 +589,8 @@ int cxgb4_setup_tc_mqprio(struct net_device *dev, + * down before configuring tc params. + */ + if (netif_running(dev)) { +- cxgb_close(dev); ++ netif_tx_stop_all_queues(dev); ++ netif_carrier_off(dev); + needs_bring_up = true; + } + +@@ -615,8 +616,10 @@ int cxgb4_setup_tc_mqprio(struct net_device *dev, + } + + out: +- if (needs_bring_up) +- cxgb_open(dev); ++ if (needs_bring_up) { ++ netif_tx_start_all_queues(dev); ++ netif_carrier_on(dev); ++ } + + mutex_unlock(&adap->tc_mqprio->mqprio_mutex); + return ret; +diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c +index 1e5f2edb70cf4..6a099cb34b122 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c +@@ -2556,6 +2556,12 @@ int cxgb4_ethofld_send_flowc(struct net_device *dev, u32 eotid, u32 tc) + if (!eosw_txq) + return -ENOMEM; + ++ if (!(adap->flags & CXGB4_FW_OK)) { ++ /* Don't stall caller when access to FW is lost */ ++ complete(&eosw_txq->completion); ++ return -EIO; ++ } ++ + skb = alloc_skb(len, GFP_KERNEL); + if (!skb) + return -ENOMEM; +diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c +index 70b515049540f..c358d90498813 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c +@@ -2313,15 +2313,20 @@ static int i40e_run_xdp(struct i40e_ring *rx_ring, struct xdp_buff *xdp) + case XDP_TX: + xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->queue_index]; + result = i40e_xmit_xdp_tx_ring(xdp, xdp_ring); ++ if (result == I40E_XDP_CONSUMED) ++ goto out_failure; + break; + case XDP_REDIRECT: + err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); +- result = !err ? I40E_XDP_REDIR : I40E_XDP_CONSUMED; ++ if (err) ++ goto out_failure; ++ result = I40E_XDP_REDIR; + break; + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + fallthrough; /* handle aborts by dropping packet */ + case XDP_DROP: +diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c b/drivers/net/ethernet/intel/i40e/i40e_xsk.c +index 12ca84113587d..5b39c457bd77b 100644 +--- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c +@@ -160,21 +160,28 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp) + xdp_prog = READ_ONCE(rx_ring->xdp_prog); + act = bpf_prog_run_xdp(xdp_prog, xdp); + ++ if (likely(act == XDP_REDIRECT)) { ++ err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); ++ if (err) ++ goto out_failure; ++ rcu_read_unlock(); ++ return I40E_XDP_REDIR; ++ } ++ + switch (act) { + case XDP_PASS: + break; + case XDP_TX: + xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->queue_index]; + result = i40e_xmit_xdp_tx_ring(xdp, xdp_ring); +- break; +- case XDP_REDIRECT: +- err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); +- result = !err ? I40E_XDP_REDIR : I40E_XDP_CONSUMED; ++ if (result == I40E_XDP_CONSUMED) ++ goto out_failure; + break; + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + fallthrough; /* handle aborts by dropping packet */ + case XDP_DROP: +diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h +index 17101c45cbcd8..f668296ca6779 100644 +--- a/drivers/net/ethernet/intel/ice/ice.h ++++ b/drivers/net/ethernet/intel/ice/ice.h +@@ -325,6 +325,7 @@ struct ice_vsi { + struct ice_tc_cfg tc_cfg; + struct bpf_prog *xdp_prog; + struct ice_ring **xdp_rings; /* XDP ring array */ ++ unsigned long *af_xdp_zc_qps; /* tracks AF_XDP ZC enabled qps */ + u16 num_xdp_txq; /* Used XDP queues */ + u8 xdp_mapping_mode; /* ICE_MAP_MODE_[CONTIG|SCATTER] */ + +@@ -534,15 +535,16 @@ static inline void ice_set_ring_xdp(struct ice_ring *ring) + */ + static inline struct xsk_buff_pool *ice_xsk_pool(struct ice_ring *ring) + { ++ struct ice_vsi *vsi = ring->vsi; + u16 qid = ring->q_index; + + if (ice_ring_is_xdp(ring)) +- qid -= ring->vsi->num_xdp_txq; ++ qid -= vsi->num_xdp_txq; + +- if (!ice_is_xdp_ena_vsi(ring->vsi)) ++ if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps)) + return NULL; + +- return xsk_get_pool_from_qid(ring->vsi->netdev, qid); ++ return xsk_get_pool_from_qid(vsi->netdev, qid); + } + + /** +diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c +index 32ba71a161652..f80fff97d8dce 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c ++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c +@@ -1797,49 +1797,6 @@ ice_phy_type_to_ethtool(struct net_device *netdev, + ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB, + 100000baseKR4_Full); + } +- +- /* Autoneg PHY types */ +- if (phy_types_low & ICE_PHY_TYPE_LOW_100BASE_TX || +- phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_T || +- phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_KX || +- phy_types_low & ICE_PHY_TYPE_LOW_2500BASE_T || +- phy_types_low & ICE_PHY_TYPE_LOW_2500BASE_KX || +- phy_types_low & ICE_PHY_TYPE_LOW_5GBASE_T || +- phy_types_low & ICE_PHY_TYPE_LOW_5GBASE_KR || +- phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_T || +- phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_KR_CR1 || +- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_T || +- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_CR || +- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_CR_S || +- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_CR1 || +- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_KR || +- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_KR_S || +- phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_KR1 || +- phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_CR4 || +- phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_KR4) { +- ethtool_link_ksettings_add_link_mode(ks, supported, +- Autoneg); +- ethtool_link_ksettings_add_link_mode(ks, advertising, +- Autoneg); +- } +- if (phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_CR2 || +- phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_KR2 || +- phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_CP || +- phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4) { +- ethtool_link_ksettings_add_link_mode(ks, supported, +- Autoneg); +- ethtool_link_ksettings_add_link_mode(ks, advertising, +- Autoneg); +- } +- if (phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_CR4 || +- phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_KR4 || +- phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4 || +- phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_CP2) { +- ethtool_link_ksettings_add_link_mode(ks, supported, +- Autoneg); +- ethtool_link_ksettings_add_link_mode(ks, advertising, +- Autoneg); +- } + } + + #define TEST_SET_BITS_TIMEOUT 50 +@@ -1996,9 +1953,7 @@ ice_get_link_ksettings(struct net_device *netdev, + ks->base.port = PORT_TP; + break; + case ICE_MEDIA_BACKPLANE: +- ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg); + ethtool_link_ksettings_add_link_mode(ks, supported, Backplane); +- ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg); + ethtool_link_ksettings_add_link_mode(ks, advertising, + Backplane); + ks->base.port = PORT_NONE; +@@ -2073,6 +2028,12 @@ ice_get_link_ksettings(struct net_device *netdev, + if (caps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN) + ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS); + ++ /* Set supported and advertised autoneg */ ++ if (ice_is_phy_caps_an_enabled(caps)) { ++ ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg); ++ ethtool_link_ksettings_add_link_mode(ks, advertising, Autoneg); ++ } ++ + done: + kfree(caps); + return err; +diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +index 093a1818a3929..1998821896c0f 100644 +--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h ++++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +@@ -31,6 +31,7 @@ + #define PF_FW_ATQLEN_ATQOVFL_M BIT(29) + #define PF_FW_ATQLEN_ATQCRIT_M BIT(30) + #define VF_MBX_ARQLEN(_VF) (0x0022BC00 + ((_VF) * 4)) ++#define VF_MBX_ATQLEN(_VF) (0x0022A800 + ((_VF) * 4)) + #define PF_FW_ATQLEN_ATQENABLE_M BIT(31) + #define PF_FW_ATQT 0x00080400 + #define PF_MBX_ARQBAH 0x0022E400 +diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c +index 195d122c9cb22..27e439853c3b0 100644 +--- a/drivers/net/ethernet/intel/ice/ice_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_lib.c +@@ -105,8 +105,14 @@ static int ice_vsi_alloc_arrays(struct ice_vsi *vsi) + if (!vsi->q_vectors) + goto err_vectors; + ++ vsi->af_xdp_zc_qps = bitmap_zalloc(max_t(int, vsi->alloc_txq, vsi->alloc_rxq), GFP_KERNEL); ++ if (!vsi->af_xdp_zc_qps) ++ goto err_zc_qps; ++ + return 0; + ++err_zc_qps: ++ devm_kfree(dev, vsi->q_vectors); + err_vectors: + devm_kfree(dev, vsi->rxq_map); + err_rxq_map: +@@ -192,6 +198,8 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id) + break; + case ICE_VSI_VF: + vf = &pf->vf[vsi->vf_id]; ++ if (vf->num_req_qs) ++ vf->num_vf_qs = vf->num_req_qs; + vsi->alloc_txq = vf->num_vf_qs; + vsi->alloc_rxq = vf->num_vf_qs; + /* pf->num_msix_per_vf includes (VF miscellaneous vector + +@@ -286,6 +294,10 @@ static void ice_vsi_free_arrays(struct ice_vsi *vsi) + + dev = ice_pf_to_dev(pf); + ++ if (vsi->af_xdp_zc_qps) { ++ bitmap_free(vsi->af_xdp_zc_qps); ++ vsi->af_xdp_zc_qps = NULL; ++ } + /* free the ring and vector containers */ + if (vsi->q_vectors) { + devm_kfree(dev, vsi->q_vectors); +diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c +index b91dcfd12727d..113e53efffd71 100644 +--- a/drivers/net/ethernet/intel/ice/ice_txrx.c ++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c +@@ -523,7 +523,7 @@ ice_run_xdp(struct ice_ring *rx_ring, struct xdp_buff *xdp, + struct bpf_prog *xdp_prog) + { + struct ice_ring *xdp_ring; +- int err; ++ int err, result; + u32 act; + + act = bpf_prog_run_xdp(xdp_prog, xdp); +@@ -532,14 +532,20 @@ ice_run_xdp(struct ice_ring *rx_ring, struct xdp_buff *xdp, + return ICE_XDP_PASS; + case XDP_TX: + xdp_ring = rx_ring->vsi->xdp_rings[smp_processor_id()]; +- return ice_xmit_xdp_buff(xdp, xdp_ring); ++ result = ice_xmit_xdp_buff(xdp, xdp_ring); ++ if (result == ICE_XDP_CONSUMED) ++ goto out_failure; ++ return result; + case XDP_REDIRECT: + err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); +- return !err ? ICE_XDP_REDIR : ICE_XDP_CONSUMED; ++ if (err) ++ goto out_failure; ++ return ICE_XDP_REDIR; + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + fallthrough; + case XDP_DROP: +@@ -2331,6 +2337,7 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring) + struct ice_tx_offload_params offload = { 0 }; + struct ice_vsi *vsi = tx_ring->vsi; + struct ice_tx_buf *first; ++ struct ethhdr *eth; + unsigned int count; + int tso, csum; + +@@ -2377,7 +2384,9 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_ring *tx_ring) + goto out_drop; + + /* allow CONTROL frames egress from main VSI if FW LLDP disabled */ +- if (unlikely(skb->priority == TC_PRIO_CONTROL && ++ eth = (struct ethhdr *)skb_mac_header(skb); ++ if (unlikely((skb->priority == TC_PRIO_CONTROL || ++ eth->h_proto == htons(ETH_P_LLDP)) && + vsi->type == ICE_VSI_PF && + vsi->port_info->qos_cfg.is_sw_lldp)) + offload.cd_qw1 |= (u64)(ICE_TX_DESC_DTYPE_CTX | +diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +index 1f38a8d0c5254..48dee9c5d534b 100644 +--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +@@ -435,13 +435,15 @@ static void ice_trigger_vf_reset(struct ice_vf *vf, bool is_vflr, bool is_pfr) + */ + clear_bit(ICE_VF_STATE_INIT, vf->vf_states); + +- /* VF_MBX_ARQLEN is cleared by PFR, so the driver needs to clear it +- * in the case of VFR. If this is done for PFR, it can mess up VF +- * resets because the VF driver may already have started cleanup +- * by the time we get here. ++ /* VF_MBX_ARQLEN and VF_MBX_ATQLEN are cleared by PFR, so the driver ++ * needs to clear them in the case of VFR/VFLR. If this is done for ++ * PFR, it can mess up VF resets because the VF driver may already ++ * have started cleanup by the time we get here. + */ +- if (!is_pfr) ++ if (!is_pfr) { + wr32(hw, VF_MBX_ARQLEN(vf->vf_id), 0); ++ wr32(hw, VF_MBX_ATQLEN(vf->vf_id), 0); ++ } + + /* In the case of a VFLR, the HW has already reset the VF and we + * just need to clean up, so don't hit the VFRTRIG register. +@@ -1375,7 +1377,12 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr) + } + + ice_vf_pre_vsi_rebuild(vf); +- ice_vf_rebuild_vsi_with_release(vf); ++ ++ if (ice_vf_rebuild_vsi_with_release(vf)) { ++ dev_err(dev, "Failed to release and setup the VF%u's VSI\n", vf->vf_id); ++ return false; ++ } ++ + ice_vf_post_vsi_rebuild(vf); + + return true; +diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c +index 9f94d9159acde..f1d4240e57df3 100644 +--- a/drivers/net/ethernet/intel/ice/ice_xsk.c ++++ b/drivers/net/ethernet/intel/ice/ice_xsk.c +@@ -273,6 +273,7 @@ static int ice_xsk_pool_disable(struct ice_vsi *vsi, u16 qid) + if (!pool) + return -EINVAL; + ++ clear_bit(qid, vsi->af_xdp_zc_qps); + xsk_pool_dma_unmap(pool, ICE_RX_DMA_ATTR); + + return 0; +@@ -303,6 +304,8 @@ ice_xsk_pool_enable(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid) + if (err) + return err; + ++ set_bit(qid, vsi->af_xdp_zc_qps); ++ + return 0; + } + +@@ -473,21 +476,29 @@ ice_run_xdp_zc(struct ice_ring *rx_ring, struct xdp_buff *xdp) + xdp_prog = READ_ONCE(rx_ring->xdp_prog); + + act = bpf_prog_run_xdp(xdp_prog, xdp); ++ ++ if (likely(act == XDP_REDIRECT)) { ++ err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); ++ if (err) ++ goto out_failure; ++ rcu_read_unlock(); ++ return ICE_XDP_REDIR; ++ } ++ + switch (act) { + case XDP_PASS: + break; + case XDP_TX: + xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->q_index]; + result = ice_xmit_xdp_buff(xdp, xdp_ring); +- break; +- case XDP_REDIRECT: +- err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); +- result = !err ? ICE_XDP_REDIR : ICE_XDP_CONSUMED; ++ if (result == ICE_XDP_CONSUMED) ++ goto out_failure; + break; + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + fallthrough; + case XDP_DROP: +diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h +index 7bda8c5edea5d..2d3daf022651c 100644 +--- a/drivers/net/ethernet/intel/igb/igb.h ++++ b/drivers/net/ethernet/intel/igb/igb.h +@@ -749,7 +749,7 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter); + void igb_ptp_tx_hang(struct igb_adapter *adapter); + void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb); + int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, +- struct sk_buff *skb); ++ ktime_t *timestamp); + int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr); + int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr); + void igb_set_flag_queue_pairs(struct igb_adapter *, const u32); +diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c +index a45cd2b416c89..caa8929289ae7 100644 +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -8281,7 +8281,7 @@ static void igb_add_rx_frag(struct igb_ring *rx_ring, + static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring, + struct igb_rx_buffer *rx_buffer, + struct xdp_buff *xdp, +- union e1000_adv_rx_desc *rx_desc) ++ ktime_t timestamp) + { + #if (PAGE_SIZE < 8192) + unsigned int truesize = igb_rx_pg_size(rx_ring) / 2; +@@ -8301,12 +8301,8 @@ static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring, + if (unlikely(!skb)) + return NULL; + +- if (unlikely(igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP))) { +- if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, xdp->data, skb)) { +- xdp->data += IGB_TS_HDR_LEN; +- size -= IGB_TS_HDR_LEN; +- } +- } ++ if (timestamp) ++ skb_hwtstamps(skb)->hwtstamp = timestamp; + + /* Determine available headroom for copy */ + headlen = size; +@@ -8337,7 +8333,7 @@ static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring, + static struct sk_buff *igb_build_skb(struct igb_ring *rx_ring, + struct igb_rx_buffer *rx_buffer, + struct xdp_buff *xdp, +- union e1000_adv_rx_desc *rx_desc) ++ ktime_t timestamp) + { + #if (PAGE_SIZE < 8192) + unsigned int truesize = igb_rx_pg_size(rx_ring) / 2; +@@ -8364,11 +8360,8 @@ static struct sk_buff *igb_build_skb(struct igb_ring *rx_ring, + if (metasize) + skb_metadata_set(skb, metasize); + +- /* pull timestamp out of packet data */ +- if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { +- if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb)) +- __skb_pull(skb, IGB_TS_HDR_LEN); +- } ++ if (timestamp) ++ skb_hwtstamps(skb)->hwtstamp = timestamp; + + /* update buffer offset */ + #if (PAGE_SIZE < 8192) +@@ -8402,18 +8395,20 @@ static struct sk_buff *igb_run_xdp(struct igb_adapter *adapter, + break; + case XDP_TX: + result = igb_xdp_xmit_back(adapter, xdp); ++ if (result == IGB_XDP_CONSUMED) ++ goto out_failure; + break; + case XDP_REDIRECT: + err = xdp_do_redirect(adapter->netdev, xdp, xdp_prog); +- if (!err) +- result = IGB_XDP_REDIR; +- else +- result = IGB_XDP_CONSUMED; ++ if (err) ++ goto out_failure; ++ result = IGB_XDP_REDIR; + break; + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + fallthrough; + case XDP_DROP: +@@ -8683,7 +8678,10 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) + while (likely(total_packets < budget)) { + union e1000_adv_rx_desc *rx_desc; + struct igb_rx_buffer *rx_buffer; ++ ktime_t timestamp = 0; ++ int pkt_offset = 0; + unsigned int size; ++ void *pktbuf; + + /* return some buffers to hardware, one at a time is too slow */ + if (cleaned_count >= IGB_RX_BUFFER_WRITE) { +@@ -8703,14 +8701,24 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) + dma_rmb(); + + rx_buffer = igb_get_rx_buffer(rx_ring, size, &rx_buf_pgcnt); ++ pktbuf = page_address(rx_buffer->page) + rx_buffer->page_offset; ++ ++ /* pull rx packet timestamp if available and valid */ ++ if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) { ++ int ts_hdr_len; ++ ++ ts_hdr_len = igb_ptp_rx_pktstamp(rx_ring->q_vector, ++ pktbuf, ×tamp); ++ ++ pkt_offset += ts_hdr_len; ++ size -= ts_hdr_len; ++ } + + /* retrieve a buffer from the ring */ + if (!skb) { +- unsigned int offset = igb_rx_offset(rx_ring); +- unsigned char *hard_start; ++ unsigned char *hard_start = pktbuf - igb_rx_offset(rx_ring); ++ unsigned int offset = pkt_offset + igb_rx_offset(rx_ring); + +- hard_start = page_address(rx_buffer->page) + +- rx_buffer->page_offset - offset; + xdp_prepare_buff(&xdp, hard_start, offset, size, true); + #if (PAGE_SIZE > 4096) + /* At larger PAGE_SIZE, frame_sz depend on len size */ +@@ -8733,10 +8741,11 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget) + } else if (skb) + igb_add_rx_frag(rx_ring, rx_buffer, skb, size); + else if (ring_uses_build_skb(rx_ring)) +- skb = igb_build_skb(rx_ring, rx_buffer, &xdp, rx_desc); ++ skb = igb_build_skb(rx_ring, rx_buffer, &xdp, ++ timestamp); + else + skb = igb_construct_skb(rx_ring, rx_buffer, +- &xdp, rx_desc); ++ &xdp, timestamp); + + /* exit if we failed to retrieve a buffer */ + if (!skb) { +diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c +index 86a576201f5ff..58b25f26ea7f2 100644 +--- a/drivers/net/ethernet/intel/igb/igb_ptp.c ++++ b/drivers/net/ethernet/intel/igb/igb_ptp.c +@@ -856,30 +856,28 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter) + dev_kfree_skb_any(skb); + } + +-#define IGB_RET_PTP_DISABLED 1 +-#define IGB_RET_PTP_INVALID 2 +- + /** + * igb_ptp_rx_pktstamp - retrieve Rx per packet timestamp + * @q_vector: Pointer to interrupt specific structure + * @va: Pointer to address containing Rx buffer +- * @skb: Buffer containing timestamp and packet ++ * @timestamp: Pointer where timestamp will be stored + * + * This function is meant to retrieve a timestamp from the first buffer of an + * incoming frame. The value is stored in little endian format starting on + * byte 8 + * +- * Returns: 0 if success, nonzero if failure ++ * Returns: The timestamp header length or 0 if not available + **/ + int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, +- struct sk_buff *skb) ++ ktime_t *timestamp) + { + struct igb_adapter *adapter = q_vector->adapter; ++ struct skb_shared_hwtstamps ts; + __le64 *regval = (__le64 *)va; + int adjust = 0; + + if (!(adapter->ptp_flags & IGB_PTP_ENABLED)) +- return IGB_RET_PTP_DISABLED; ++ return 0; + + /* The timestamp is recorded in little endian format. + * DWORD: 0 1 2 3 +@@ -888,10 +886,9 @@ int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, + + /* check reserved dwords are zero, be/le doesn't matter for zero */ + if (regval[0]) +- return IGB_RET_PTP_INVALID; ++ return 0; + +- igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), +- le64_to_cpu(regval[1])); ++ igb_ptp_systim_to_hwtstamp(adapter, &ts, le64_to_cpu(regval[1])); + + /* adjust timestamp for the RX latency based on link speed */ + if (adapter->hw.mac.type == e1000_i210) { +@@ -907,10 +904,10 @@ int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va, + break; + } + } +- skb_hwtstamps(skb)->hwtstamp = +- ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust); + +- return 0; ++ *timestamp = ktime_sub_ns(ts.hwtstamp, adjust); ++ ++ return IGB_TS_HDR_LEN; + } + + /** +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +index cffb95f8f6326..c194158a421c7 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +@@ -2213,23 +2213,23 @@ static struct sk_buff *ixgbe_run_xdp(struct ixgbe_adapter *adapter, + break; + case XDP_TX: + xdpf = xdp_convert_buff_to_frame(xdp); +- if (unlikely(!xdpf)) { +- result = IXGBE_XDP_CONSUMED; +- break; +- } ++ if (unlikely(!xdpf)) ++ goto out_failure; + result = ixgbe_xmit_xdp_ring(adapter, xdpf); ++ if (result == IXGBE_XDP_CONSUMED) ++ goto out_failure; + break; + case XDP_REDIRECT: + err = xdp_do_redirect(adapter->netdev, xdp, xdp_prog); +- if (!err) +- result = IXGBE_XDP_REDIR; +- else +- result = IXGBE_XDP_CONSUMED; ++ if (err) ++ goto out_failure; ++ result = IXGBE_XDP_REDIR; + break; + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + fallthrough; /* handle aborts by dropping packet */ + case XDP_DROP: +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +index 3771857cf887c..f72d2978263b9 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +@@ -104,25 +104,30 @@ static int ixgbe_run_xdp_zc(struct ixgbe_adapter *adapter, + xdp_prog = READ_ONCE(rx_ring->xdp_prog); + act = bpf_prog_run_xdp(xdp_prog, xdp); + ++ if (likely(act == XDP_REDIRECT)) { ++ err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); ++ if (err) ++ goto out_failure; ++ rcu_read_unlock(); ++ return IXGBE_XDP_REDIR; ++ } ++ + switch (act) { + case XDP_PASS: + break; + case XDP_TX: + xdpf = xdp_convert_buff_to_frame(xdp); +- if (unlikely(!xdpf)) { +- result = IXGBE_XDP_CONSUMED; +- break; +- } ++ if (unlikely(!xdpf)) ++ goto out_failure; + result = ixgbe_xmit_xdp_ring(adapter, xdpf); +- break; +- case XDP_REDIRECT: +- err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); +- result = !err ? IXGBE_XDP_REDIR : IXGBE_XDP_CONSUMED; ++ if (result == IXGBE_XDP_CONSUMED) ++ goto out_failure; + break; + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + fallthrough; /* handle aborts by dropping packet */ + case XDP_DROP: +diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +index 449d7d5b280dd..b38860c485986 100644 +--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c ++++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +@@ -1067,11 +1067,14 @@ static struct sk_buff *ixgbevf_run_xdp(struct ixgbevf_adapter *adapter, + case XDP_TX: + xdp_ring = adapter->xdp_ring[rx_ring->queue_index]; + result = ixgbevf_xmit_xdp_ring(xdp_ring, xdp); ++ if (result == IXGBEVF_XDP_CONSUMED) ++ goto out_failure; + break; + default: + bpf_warn_invalid_xdp_action(act); + fallthrough; + case XDP_ABORTED: ++out_failure: + trace_xdp_exception(rx_ring->netdev, xdp_prog, act); + fallthrough; /* handle aborts by dropping packet */ + case XDP_DROP: +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +index 53802e18af900..04b49cb3adb32 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +@@ -1632,12 +1632,13 @@ static int mlx5e_set_fecparam(struct net_device *netdev, + { + struct mlx5e_priv *priv = netdev_priv(netdev); + struct mlx5_core_dev *mdev = priv->mdev; ++ unsigned long fec_bitmap; + u16 fec_policy = 0; + int mode; + int err; + +- if (bitmap_weight((unsigned long *)&fecparam->fec, +- ETHTOOL_FEC_LLRS_BIT + 1) > 1) ++ bitmap_from_arr32(&fec_bitmap, &fecparam->fec, sizeof(fecparam->fec) * BITS_PER_BYTE); ++ if (bitmap_weight(&fec_bitmap, ETHTOOL_FEC_LLRS_BIT + 1) > 1) + return -EOPNOTSUPP; + + for (mode = 0; mode < ARRAY_SIZE(pplm_fec_2_ethtool); mode++) { +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +index 78a1403c98026..b633f669ea57f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +@@ -1964,11 +1964,13 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, + misc_parameters); + struct flow_rule *rule = flow_cls_offload_flow_rule(f); + struct flow_dissector *dissector = rule->match.dissector; ++ enum fs_flow_table_type fs_type; + u16 addr_type = 0; + u8 ip_proto = 0; + u8 *match_level; + int err; + ++ fs_type = mlx5e_is_eswitch_flow(flow) ? FS_FT_FDB : FS_FT_NIC_RX; + match_level = outer_match_level; + + if (dissector->used_keys & +@@ -2093,6 +2095,13 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, + if (match.mask->vlan_id || + match.mask->vlan_priority || + match.mask->vlan_tpid) { ++ if (!MLX5_CAP_FLOWTABLE_TYPE(priv->mdev, ft_field_support.outer_second_vid, ++ fs_type)) { ++ NL_SET_ERR_MSG_MOD(extack, ++ "Matching on CVLAN is not supported"); ++ return -EOPNOTSUPP; ++ } ++ + if (match.key->vlan_tpid == htons(ETH_P_8021AD)) { + MLX5_SET(fte_match_set_misc, misc_c, + outer_second_svlan_tag, 1); +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +index d4a2f8d1ee9f1..3719452a78035 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +@@ -349,7 +349,8 @@ esw_setup_slow_path_dest(struct mlx5_flow_destination *dest, + struct mlx5_fs_chains *chains, + int i) + { +- flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL; ++ if (mlx5_chains_ignore_flow_level_supported(chains)) ++ flow_act->flags |= FLOW_ACT_IGNORE_FLOW_LEVEL; + dest[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; + dest[i].ft = mlx5_chains_get_tc_end_ft(chains); + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +index f9042e147c7f6..ee710ce007950 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +@@ -354,6 +354,9 @@ static void mlx5_sync_reset_abort_event(struct work_struct *work) + reset_abort_work); + struct mlx5_core_dev *dev = fw_reset->dev; + ++ if (!test_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags)) ++ return; ++ + mlx5_sync_reset_clear_reset_requested(dev, true); + mlx5_core_warn(dev, "PCI Sync FW Update Reset Aborted.\n"); + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c +index 381325b4a863e..b607ed5a74bb4 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c +@@ -111,7 +111,7 @@ bool mlx5_chains_prios_supported(struct mlx5_fs_chains *chains) + return chains->flags & MLX5_CHAINS_AND_PRIOS_SUPPORTED; + } + +-static bool mlx5_chains_ignore_flow_level_supported(struct mlx5_fs_chains *chains) ++bool mlx5_chains_ignore_flow_level_supported(struct mlx5_fs_chains *chains) + { + return chains->flags & MLX5_CHAINS_IGNORE_FLOW_LEVEL_SUPPORTED; + } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.h +index 6d5be31b05dd7..9f53a08235582 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.h ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.h +@@ -27,6 +27,7 @@ struct mlx5_chains_attr { + + bool + mlx5_chains_prios_supported(struct mlx5_fs_chains *chains); ++bool mlx5_chains_ignore_flow_level_supported(struct mlx5_fs_chains *chains); + bool + mlx5_chains_backwards_supported(struct mlx5_fs_chains *chains); + u32 +@@ -72,6 +73,10 @@ mlx5_chains_set_end_ft(struct mlx5_fs_chains *chains, + + #else /* CONFIG_MLX5_CLS_ACT */ + ++static inline bool ++mlx5_chains_ignore_flow_level_supported(struct mlx5_fs_chains *chains) ++{ return false; } ++ + static inline struct mlx5_flow_table * + mlx5_chains_get_table(struct mlx5_fs_chains *chains, u32 chain, u32 prio, + u32 level) { return ERR_PTR(-EOPNOTSUPP); } +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_fw.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_fw.c +index 1fbcd012bb855..7ccfd40586cee 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_fw.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_fw.c +@@ -112,7 +112,8 @@ int mlx5dr_fw_create_md_tbl(struct mlx5dr_domain *dmn, + int ret; + + ft_attr.table_type = MLX5_FLOW_TABLE_TYPE_FDB; +- ft_attr.level = dmn->info.caps.max_ft_level - 2; ++ ft_attr.level = min_t(int, dmn->info.caps.max_ft_level - 2, ++ MLX5_FT_MAX_MULTIPATH_LEVEL); + ft_attr.reformat_en = reformat_req; + ft_attr.decap_en = reformat_req; + +diff --git a/drivers/net/wireguard/Makefile b/drivers/net/wireguard/Makefile +index fc52b2cb500b3..dbe1f8514efc3 100644 +--- a/drivers/net/wireguard/Makefile ++++ b/drivers/net/wireguard/Makefile +@@ -1,5 +1,4 @@ +-ccflags-y := -O3 +-ccflags-y += -D'pr_fmt(fmt)=KBUILD_MODNAME ": " fmt' ++ccflags-y := -D'pr_fmt(fmt)=KBUILD_MODNAME ": " fmt' + ccflags-$(CONFIG_WIREGUARD_DEBUG) += -DDEBUG + wireguard-y := main.o + wireguard-y += noise.o +diff --git a/drivers/net/wireguard/allowedips.c b/drivers/net/wireguard/allowedips.c +index 3725e9cd85f4f..b7197e80f2264 100644 +--- a/drivers/net/wireguard/allowedips.c ++++ b/drivers/net/wireguard/allowedips.c +@@ -6,6 +6,8 @@ + #include "allowedips.h" + #include "peer.h" + ++static struct kmem_cache *node_cache; ++ + static void swap_endian(u8 *dst, const u8 *src, u8 bits) + { + if (bits == 32) { +@@ -28,8 +30,11 @@ static void copy_and_assign_cidr(struct allowedips_node *node, const u8 *src, + node->bitlen = bits; + memcpy(node->bits, src, bits / 8U); + } +-#define CHOOSE_NODE(parent, key) \ +- parent->bit[(key[parent->bit_at_a] >> parent->bit_at_b) & 1] ++ ++static inline u8 choose(struct allowedips_node *node, const u8 *key) ++{ ++ return (key[node->bit_at_a] >> node->bit_at_b) & 1; ++} + + static void push_rcu(struct allowedips_node **stack, + struct allowedips_node __rcu *p, unsigned int *len) +@@ -40,6 +45,11 @@ static void push_rcu(struct allowedips_node **stack, + } + } + ++static void node_free_rcu(struct rcu_head *rcu) ++{ ++ kmem_cache_free(node_cache, container_of(rcu, struct allowedips_node, rcu)); ++} ++ + static void root_free_rcu(struct rcu_head *rcu) + { + struct allowedips_node *node, *stack[128] = { +@@ -49,7 +59,7 @@ static void root_free_rcu(struct rcu_head *rcu) + while (len > 0 && (node = stack[--len])) { + push_rcu(stack, node->bit[0], &len); + push_rcu(stack, node->bit[1], &len); +- kfree(node); ++ kmem_cache_free(node_cache, node); + } + } + +@@ -66,60 +76,6 @@ static void root_remove_peer_lists(struct allowedips_node *root) + } + } + +-static void walk_remove_by_peer(struct allowedips_node __rcu **top, +- struct wg_peer *peer, struct mutex *lock) +-{ +-#define REF(p) rcu_access_pointer(p) +-#define DEREF(p) rcu_dereference_protected(*(p), lockdep_is_held(lock)) +-#define PUSH(p) ({ \ +- WARN_ON(IS_ENABLED(DEBUG) && len >= 128); \ +- stack[len++] = p; \ +- }) +- +- struct allowedips_node __rcu **stack[128], **nptr; +- struct allowedips_node *node, *prev; +- unsigned int len; +- +- if (unlikely(!peer || !REF(*top))) +- return; +- +- for (prev = NULL, len = 0, PUSH(top); len > 0; prev = node) { +- nptr = stack[len - 1]; +- node = DEREF(nptr); +- if (!node) { +- --len; +- continue; +- } +- if (!prev || REF(prev->bit[0]) == node || +- REF(prev->bit[1]) == node) { +- if (REF(node->bit[0])) +- PUSH(&node->bit[0]); +- else if (REF(node->bit[1])) +- PUSH(&node->bit[1]); +- } else if (REF(node->bit[0]) == prev) { +- if (REF(node->bit[1])) +- PUSH(&node->bit[1]); +- } else { +- if (rcu_dereference_protected(node->peer, +- lockdep_is_held(lock)) == peer) { +- RCU_INIT_POINTER(node->peer, NULL); +- list_del_init(&node->peer_list); +- if (!node->bit[0] || !node->bit[1]) { +- rcu_assign_pointer(*nptr, DEREF( +- &node->bit[!REF(node->bit[0])])); +- kfree_rcu(node, rcu); +- node = DEREF(nptr); +- } +- } +- --len; +- } +- } +- +-#undef REF +-#undef DEREF +-#undef PUSH +-} +- + static unsigned int fls128(u64 a, u64 b) + { + return a ? fls64(a) + 64U : fls64(b); +@@ -159,7 +115,7 @@ static struct allowedips_node *find_node(struct allowedips_node *trie, u8 bits, + found = node; + if (node->cidr == bits) + break; +- node = rcu_dereference_bh(CHOOSE_NODE(node, key)); ++ node = rcu_dereference_bh(node->bit[choose(node, key)]); + } + return found; + } +@@ -191,8 +147,7 @@ static bool node_placement(struct allowedips_node __rcu *trie, const u8 *key, + u8 cidr, u8 bits, struct allowedips_node **rnode, + struct mutex *lock) + { +- struct allowedips_node *node = rcu_dereference_protected(trie, +- lockdep_is_held(lock)); ++ struct allowedips_node *node = rcu_dereference_protected(trie, lockdep_is_held(lock)); + struct allowedips_node *parent = NULL; + bool exact = false; + +@@ -202,13 +157,24 @@ static bool node_placement(struct allowedips_node __rcu *trie, const u8 *key, + exact = true; + break; + } +- node = rcu_dereference_protected(CHOOSE_NODE(parent, key), +- lockdep_is_held(lock)); ++ node = rcu_dereference_protected(parent->bit[choose(parent, key)], lockdep_is_held(lock)); + } + *rnode = parent; + return exact; + } + ++static inline void connect_node(struct allowedips_node **parent, u8 bit, struct allowedips_node *node) ++{ ++ node->parent_bit_packed = (unsigned long)parent | bit; ++ rcu_assign_pointer(*parent, node); ++} ++ ++static inline void choose_and_connect_node(struct allowedips_node *parent, struct allowedips_node *node) ++{ ++ u8 bit = choose(parent, node->bits); ++ connect_node(&parent->bit[bit], bit, node); ++} ++ + static int add(struct allowedips_node __rcu **trie, u8 bits, const u8 *key, + u8 cidr, struct wg_peer *peer, struct mutex *lock) + { +@@ -218,13 +184,13 @@ static int add(struct allowedips_node __rcu **trie, u8 bits, const u8 *key, + return -EINVAL; + + if (!rcu_access_pointer(*trie)) { +- node = kzalloc(sizeof(*node), GFP_KERNEL); ++ node = kmem_cache_zalloc(node_cache, GFP_KERNEL); + if (unlikely(!node)) + return -ENOMEM; + RCU_INIT_POINTER(node->peer, peer); + list_add_tail(&node->peer_list, &peer->allowedips_list); + copy_and_assign_cidr(node, key, cidr, bits); +- rcu_assign_pointer(*trie, node); ++ connect_node(trie, 2, node); + return 0; + } + if (node_placement(*trie, key, cidr, bits, &node, lock)) { +@@ -233,7 +199,7 @@ static int add(struct allowedips_node __rcu **trie, u8 bits, const u8 *key, + return 0; + } + +- newnode = kzalloc(sizeof(*newnode), GFP_KERNEL); ++ newnode = kmem_cache_zalloc(node_cache, GFP_KERNEL); + if (unlikely(!newnode)) + return -ENOMEM; + RCU_INIT_POINTER(newnode->peer, peer); +@@ -243,10 +209,10 @@ static int add(struct allowedips_node __rcu **trie, u8 bits, const u8 *key, + if (!node) { + down = rcu_dereference_protected(*trie, lockdep_is_held(lock)); + } else { +- down = rcu_dereference_protected(CHOOSE_NODE(node, key), +- lockdep_is_held(lock)); ++ const u8 bit = choose(node, key); ++ down = rcu_dereference_protected(node->bit[bit], lockdep_is_held(lock)); + if (!down) { +- rcu_assign_pointer(CHOOSE_NODE(node, key), newnode); ++ connect_node(&node->bit[bit], bit, newnode); + return 0; + } + } +@@ -254,30 +220,29 @@ static int add(struct allowedips_node __rcu **trie, u8 bits, const u8 *key, + parent = node; + + if (newnode->cidr == cidr) { +- rcu_assign_pointer(CHOOSE_NODE(newnode, down->bits), down); ++ choose_and_connect_node(newnode, down); + if (!parent) +- rcu_assign_pointer(*trie, newnode); ++ connect_node(trie, 2, newnode); + else +- rcu_assign_pointer(CHOOSE_NODE(parent, newnode->bits), +- newnode); +- } else { +- node = kzalloc(sizeof(*node), GFP_KERNEL); +- if (unlikely(!node)) { +- list_del(&newnode->peer_list); +- kfree(newnode); +- return -ENOMEM; +- } +- INIT_LIST_HEAD(&node->peer_list); +- copy_and_assign_cidr(node, newnode->bits, cidr, bits); ++ choose_and_connect_node(parent, newnode); ++ return 0; ++ } + +- rcu_assign_pointer(CHOOSE_NODE(node, down->bits), down); +- rcu_assign_pointer(CHOOSE_NODE(node, newnode->bits), newnode); +- if (!parent) +- rcu_assign_pointer(*trie, node); +- else +- rcu_assign_pointer(CHOOSE_NODE(parent, node->bits), +- node); ++ node = kmem_cache_zalloc(node_cache, GFP_KERNEL); ++ if (unlikely(!node)) { ++ list_del(&newnode->peer_list); ++ kmem_cache_free(node_cache, newnode); ++ return -ENOMEM; + } ++ INIT_LIST_HEAD(&node->peer_list); ++ copy_and_assign_cidr(node, newnode->bits, cidr, bits); ++ ++ choose_and_connect_node(node, down); ++ choose_and_connect_node(node, newnode); ++ if (!parent) ++ connect_node(trie, 2, node); ++ else ++ choose_and_connect_node(parent, node); + return 0; + } + +@@ -335,9 +300,41 @@ int wg_allowedips_insert_v6(struct allowedips *table, const struct in6_addr *ip, + void wg_allowedips_remove_by_peer(struct allowedips *table, + struct wg_peer *peer, struct mutex *lock) + { ++ struct allowedips_node *node, *child, **parent_bit, *parent, *tmp; ++ bool free_parent; ++ ++ if (list_empty(&peer->allowedips_list)) ++ return; + ++table->seq; +- walk_remove_by_peer(&table->root4, peer, lock); +- walk_remove_by_peer(&table->root6, peer, lock); ++ list_for_each_entry_safe(node, tmp, &peer->allowedips_list, peer_list) { ++ list_del_init(&node->peer_list); ++ RCU_INIT_POINTER(node->peer, NULL); ++ if (node->bit[0] && node->bit[1]) ++ continue; ++ child = rcu_dereference_protected(node->bit[!rcu_access_pointer(node->bit[0])], ++ lockdep_is_held(lock)); ++ if (child) ++ child->parent_bit_packed = node->parent_bit_packed; ++ parent_bit = (struct allowedips_node **)(node->parent_bit_packed & ~3UL); ++ *parent_bit = child; ++ parent = (void *)parent_bit - ++ offsetof(struct allowedips_node, bit[node->parent_bit_packed & 1]); ++ free_parent = !rcu_access_pointer(node->bit[0]) && ++ !rcu_access_pointer(node->bit[1]) && ++ (node->parent_bit_packed & 3) <= 1 && ++ !rcu_access_pointer(parent->peer); ++ if (free_parent) ++ child = rcu_dereference_protected( ++ parent->bit[!(node->parent_bit_packed & 1)], ++ lockdep_is_held(lock)); ++ call_rcu(&node->rcu, node_free_rcu); ++ if (!free_parent) ++ continue; ++ if (child) ++ child->parent_bit_packed = parent->parent_bit_packed; ++ *(struct allowedips_node **)(parent->parent_bit_packed & ~3UL) = child; ++ call_rcu(&parent->rcu, node_free_rcu); ++ } + } + + int wg_allowedips_read_node(struct allowedips_node *node, u8 ip[16], u8 *cidr) +@@ -374,4 +371,16 @@ struct wg_peer *wg_allowedips_lookup_src(struct allowedips *table, + return NULL; + } + ++int __init wg_allowedips_slab_init(void) ++{ ++ node_cache = KMEM_CACHE(allowedips_node, 0); ++ return node_cache ? 0 : -ENOMEM; ++} ++ ++void wg_allowedips_slab_uninit(void) ++{ ++ rcu_barrier(); ++ kmem_cache_destroy(node_cache); ++} ++ + #include "selftest/allowedips.c" +diff --git a/drivers/net/wireguard/allowedips.h b/drivers/net/wireguard/allowedips.h +index e5c83cafcef4c..2346c797eb4d8 100644 +--- a/drivers/net/wireguard/allowedips.h ++++ b/drivers/net/wireguard/allowedips.h +@@ -15,14 +15,11 @@ struct wg_peer; + struct allowedips_node { + struct wg_peer __rcu *peer; + struct allowedips_node __rcu *bit[2]; +- /* While it may seem scandalous that we waste space for v4, +- * we're alloc'ing to the nearest power of 2 anyway, so this +- * doesn't actually make a difference. +- */ +- u8 bits[16] __aligned(__alignof(u64)); + u8 cidr, bit_at_a, bit_at_b, bitlen; ++ u8 bits[16] __aligned(__alignof(u64)); + +- /* Keep rarely used list at bottom to be beyond cache line. */ ++ /* Keep rarely used members at bottom to be beyond cache line. */ ++ unsigned long parent_bit_packed; + union { + struct list_head peer_list; + struct rcu_head rcu; +@@ -33,7 +30,7 @@ struct allowedips { + struct allowedips_node __rcu *root4; + struct allowedips_node __rcu *root6; + u64 seq; +-}; ++} __aligned(4); /* We pack the lower 2 bits of &root, but m68k only gives 16-bit alignment. */ + + void wg_allowedips_init(struct allowedips *table); + void wg_allowedips_free(struct allowedips *table, struct mutex *mutex); +@@ -56,4 +53,7 @@ struct wg_peer *wg_allowedips_lookup_src(struct allowedips *table, + bool wg_allowedips_selftest(void); + #endif + ++int wg_allowedips_slab_init(void); ++void wg_allowedips_slab_uninit(void); ++ + #endif /* _WG_ALLOWEDIPS_H */ +diff --git a/drivers/net/wireguard/main.c b/drivers/net/wireguard/main.c +index 7a7d5f1a80fc7..75dbe77b0b4b4 100644 +--- a/drivers/net/wireguard/main.c ++++ b/drivers/net/wireguard/main.c +@@ -21,13 +21,22 @@ static int __init mod_init(void) + { + int ret; + ++ ret = wg_allowedips_slab_init(); ++ if (ret < 0) ++ goto err_allowedips; ++ + #ifdef DEBUG ++ ret = -ENOTRECOVERABLE; + if (!wg_allowedips_selftest() || !wg_packet_counter_selftest() || + !wg_ratelimiter_selftest()) +- return -ENOTRECOVERABLE; ++ goto err_peer; + #endif + wg_noise_init(); + ++ ret = wg_peer_init(); ++ if (ret < 0) ++ goto err_peer; ++ + ret = wg_device_init(); + if (ret < 0) + goto err_device; +@@ -44,6 +53,10 @@ static int __init mod_init(void) + err_netlink: + wg_device_uninit(); + err_device: ++ wg_peer_uninit(); ++err_peer: ++ wg_allowedips_slab_uninit(); ++err_allowedips: + return ret; + } + +@@ -51,6 +64,8 @@ static void __exit mod_exit(void) + { + wg_genetlink_uninit(); + wg_device_uninit(); ++ wg_peer_uninit(); ++ wg_allowedips_slab_uninit(); + } + + module_init(mod_init); +diff --git a/drivers/net/wireguard/peer.c b/drivers/net/wireguard/peer.c +index cd5cb0292cb67..1acd00ab2fbcb 100644 +--- a/drivers/net/wireguard/peer.c ++++ b/drivers/net/wireguard/peer.c +@@ -15,6 +15,7 @@ + #include + #include + ++static struct kmem_cache *peer_cache; + static atomic64_t peer_counter = ATOMIC64_INIT(0); + + struct wg_peer *wg_peer_create(struct wg_device *wg, +@@ -29,10 +30,10 @@ struct wg_peer *wg_peer_create(struct wg_device *wg, + if (wg->num_peers >= MAX_PEERS_PER_DEVICE) + return ERR_PTR(ret); + +- peer = kzalloc(sizeof(*peer), GFP_KERNEL); ++ peer = kmem_cache_zalloc(peer_cache, GFP_KERNEL); + if (unlikely(!peer)) + return ERR_PTR(ret); +- if (dst_cache_init(&peer->endpoint_cache, GFP_KERNEL)) ++ if (unlikely(dst_cache_init(&peer->endpoint_cache, GFP_KERNEL))) + goto err; + + peer->device = wg; +@@ -64,7 +65,7 @@ struct wg_peer *wg_peer_create(struct wg_device *wg, + return peer; + + err: +- kfree(peer); ++ kmem_cache_free(peer_cache, peer); + return ERR_PTR(ret); + } + +@@ -88,7 +89,7 @@ static void peer_make_dead(struct wg_peer *peer) + /* Mark as dead, so that we don't allow jumping contexts after. */ + WRITE_ONCE(peer->is_dead, true); + +- /* The caller must now synchronize_rcu() for this to take effect. */ ++ /* The caller must now synchronize_net() for this to take effect. */ + } + + static void peer_remove_after_dead(struct wg_peer *peer) +@@ -160,7 +161,7 @@ void wg_peer_remove(struct wg_peer *peer) + lockdep_assert_held(&peer->device->device_update_lock); + + peer_make_dead(peer); +- synchronize_rcu(); ++ synchronize_net(); + peer_remove_after_dead(peer); + } + +@@ -178,7 +179,7 @@ void wg_peer_remove_all(struct wg_device *wg) + peer_make_dead(peer); + list_add_tail(&peer->peer_list, &dead_peers); + } +- synchronize_rcu(); ++ synchronize_net(); + list_for_each_entry_safe(peer, temp, &dead_peers, peer_list) + peer_remove_after_dead(peer); + } +@@ -193,7 +194,8 @@ static void rcu_release(struct rcu_head *rcu) + /* The final zeroing takes care of clearing any remaining handshake key + * material and other potentially sensitive information. + */ +- kfree_sensitive(peer); ++ memzero_explicit(peer, sizeof(*peer)); ++ kmem_cache_free(peer_cache, peer); + } + + static void kref_release(struct kref *refcount) +@@ -225,3 +227,14 @@ void wg_peer_put(struct wg_peer *peer) + return; + kref_put(&peer->refcount, kref_release); + } ++ ++int __init wg_peer_init(void) ++{ ++ peer_cache = KMEM_CACHE(wg_peer, 0); ++ return peer_cache ? 0 : -ENOMEM; ++} ++ ++void wg_peer_uninit(void) ++{ ++ kmem_cache_destroy(peer_cache); ++} +diff --git a/drivers/net/wireguard/peer.h b/drivers/net/wireguard/peer.h +index 8d53b687a1d16..76e4d3128ad4e 100644 +--- a/drivers/net/wireguard/peer.h ++++ b/drivers/net/wireguard/peer.h +@@ -80,4 +80,7 @@ void wg_peer_put(struct wg_peer *peer); + void wg_peer_remove(struct wg_peer *peer); + void wg_peer_remove_all(struct wg_device *wg); + ++int wg_peer_init(void); ++void wg_peer_uninit(void); ++ + #endif /* _WG_PEER_H */ +diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c +index 846db14cb046b..e173204ae7d78 100644 +--- a/drivers/net/wireguard/selftest/allowedips.c ++++ b/drivers/net/wireguard/selftest/allowedips.c +@@ -19,32 +19,22 @@ + + #include + +-static __init void swap_endian_and_apply_cidr(u8 *dst, const u8 *src, u8 bits, +- u8 cidr) +-{ +- swap_endian(dst, src, bits); +- memset(dst + (cidr + 7) / 8, 0, bits / 8 - (cidr + 7) / 8); +- if (cidr) +- dst[(cidr + 7) / 8 - 1] &= ~0U << ((8 - (cidr % 8)) % 8); +-} +- + static __init void print_node(struct allowedips_node *node, u8 bits) + { + char *fmt_connection = KERN_DEBUG "\t\"%p/%d\" -> \"%p/%d\";\n"; +- char *fmt_declaration = KERN_DEBUG +- "\t\"%p/%d\"[style=%s, color=\"#%06x\"];\n"; ++ char *fmt_declaration = KERN_DEBUG "\t\"%p/%d\"[style=%s, color=\"#%06x\"];\n"; ++ u8 ip1[16], ip2[16], cidr1, cidr2; + char *style = "dotted"; +- u8 ip1[16], ip2[16]; + u32 color = 0; + ++ if (node == NULL) ++ return; + if (bits == 32) { + fmt_connection = KERN_DEBUG "\t\"%pI4/%d\" -> \"%pI4/%d\";\n"; +- fmt_declaration = KERN_DEBUG +- "\t\"%pI4/%d\"[style=%s, color=\"#%06x\"];\n"; ++ fmt_declaration = KERN_DEBUG "\t\"%pI4/%d\"[style=%s, color=\"#%06x\"];\n"; + } else if (bits == 128) { + fmt_connection = KERN_DEBUG "\t\"%pI6/%d\" -> \"%pI6/%d\";\n"; +- fmt_declaration = KERN_DEBUG +- "\t\"%pI6/%d\"[style=%s, color=\"#%06x\"];\n"; ++ fmt_declaration = KERN_DEBUG "\t\"%pI6/%d\"[style=%s, color=\"#%06x\"];\n"; + } + if (node->peer) { + hsiphash_key_t key = { { 0 } }; +@@ -55,24 +45,20 @@ static __init void print_node(struct allowedips_node *node, u8 bits) + hsiphash_1u32(0xabad1dea, &key) % 200; + style = "bold"; + } +- swap_endian_and_apply_cidr(ip1, node->bits, bits, node->cidr); +- printk(fmt_declaration, ip1, node->cidr, style, color); ++ wg_allowedips_read_node(node, ip1, &cidr1); ++ printk(fmt_declaration, ip1, cidr1, style, color); + if (node->bit[0]) { +- swap_endian_and_apply_cidr(ip2, +- rcu_dereference_raw(node->bit[0])->bits, bits, +- node->cidr); +- printk(fmt_connection, ip1, node->cidr, ip2, +- rcu_dereference_raw(node->bit[0])->cidr); +- print_node(rcu_dereference_raw(node->bit[0]), bits); ++ wg_allowedips_read_node(rcu_dereference_raw(node->bit[0]), ip2, &cidr2); ++ printk(fmt_connection, ip1, cidr1, ip2, cidr2); + } + if (node->bit[1]) { +- swap_endian_and_apply_cidr(ip2, +- rcu_dereference_raw(node->bit[1])->bits, +- bits, node->cidr); +- printk(fmt_connection, ip1, node->cidr, ip2, +- rcu_dereference_raw(node->bit[1])->cidr); +- print_node(rcu_dereference_raw(node->bit[1]), bits); ++ wg_allowedips_read_node(rcu_dereference_raw(node->bit[1]), ip2, &cidr2); ++ printk(fmt_connection, ip1, cidr1, ip2, cidr2); + } ++ if (node->bit[0]) ++ print_node(rcu_dereference_raw(node->bit[0]), bits); ++ if (node->bit[1]) ++ print_node(rcu_dereference_raw(node->bit[1]), bits); + } + + static __init void print_tree(struct allowedips_node __rcu *top, u8 bits) +@@ -121,8 +107,8 @@ static __init inline union nf_inet_addr horrible_cidr_to_mask(u8 cidr) + { + union nf_inet_addr mask; + +- memset(&mask, 0x00, 128 / 8); +- memset(&mask, 0xff, cidr / 8); ++ memset(&mask, 0, sizeof(mask)); ++ memset(&mask.all, 0xff, cidr / 8); + if (cidr % 32) + mask.all[cidr / 32] = (__force u32)htonl( + (0xFFFFFFFFUL << (32 - (cidr % 32))) & 0xFFFFFFFFUL); +@@ -149,42 +135,36 @@ horrible_mask_self(struct horrible_allowedips_node *node) + } + + static __init inline bool +-horrible_match_v4(const struct horrible_allowedips_node *node, +- struct in_addr *ip) ++horrible_match_v4(const struct horrible_allowedips_node *node, struct in_addr *ip) + { + return (ip->s_addr & node->mask.ip) == node->ip.ip; + } + + static __init inline bool +-horrible_match_v6(const struct horrible_allowedips_node *node, +- struct in6_addr *ip) ++horrible_match_v6(const struct horrible_allowedips_node *node, struct in6_addr *ip) + { +- return (ip->in6_u.u6_addr32[0] & node->mask.ip6[0]) == +- node->ip.ip6[0] && +- (ip->in6_u.u6_addr32[1] & node->mask.ip6[1]) == +- node->ip.ip6[1] && +- (ip->in6_u.u6_addr32[2] & node->mask.ip6[2]) == +- node->ip.ip6[2] && ++ return (ip->in6_u.u6_addr32[0] & node->mask.ip6[0]) == node->ip.ip6[0] && ++ (ip->in6_u.u6_addr32[1] & node->mask.ip6[1]) == node->ip.ip6[1] && ++ (ip->in6_u.u6_addr32[2] & node->mask.ip6[2]) == node->ip.ip6[2] && + (ip->in6_u.u6_addr32[3] & node->mask.ip6[3]) == node->ip.ip6[3]; + } + + static __init void +-horrible_insert_ordered(struct horrible_allowedips *table, +- struct horrible_allowedips_node *node) ++horrible_insert_ordered(struct horrible_allowedips *table, struct horrible_allowedips_node *node) + { + struct horrible_allowedips_node *other = NULL, *where = NULL; + u8 my_cidr = horrible_mask_to_cidr(node->mask); + + hlist_for_each_entry(other, &table->head, table) { +- if (!memcmp(&other->mask, &node->mask, +- sizeof(union nf_inet_addr)) && +- !memcmp(&other->ip, &node->ip, +- sizeof(union nf_inet_addr)) && +- other->ip_version == node->ip_version) { ++ if (other->ip_version == node->ip_version && ++ !memcmp(&other->mask, &node->mask, sizeof(union nf_inet_addr)) && ++ !memcmp(&other->ip, &node->ip, sizeof(union nf_inet_addr))) { + other->value = node->value; + kfree(node); + return; + } ++ } ++ hlist_for_each_entry(other, &table->head, table) { + where = other; + if (horrible_mask_to_cidr(other->mask) <= my_cidr) + break; +@@ -201,8 +181,7 @@ static __init int + horrible_allowedips_insert_v4(struct horrible_allowedips *table, + struct in_addr *ip, u8 cidr, void *value) + { +- struct horrible_allowedips_node *node = kzalloc(sizeof(*node), +- GFP_KERNEL); ++ struct horrible_allowedips_node *node = kzalloc(sizeof(*node), GFP_KERNEL); + + if (unlikely(!node)) + return -ENOMEM; +@@ -219,8 +198,7 @@ static __init int + horrible_allowedips_insert_v6(struct horrible_allowedips *table, + struct in6_addr *ip, u8 cidr, void *value) + { +- struct horrible_allowedips_node *node = kzalloc(sizeof(*node), +- GFP_KERNEL); ++ struct horrible_allowedips_node *node = kzalloc(sizeof(*node), GFP_KERNEL); + + if (unlikely(!node)) + return -ENOMEM; +@@ -234,39 +212,43 @@ horrible_allowedips_insert_v6(struct horrible_allowedips *table, + } + + static __init void * +-horrible_allowedips_lookup_v4(struct horrible_allowedips *table, +- struct in_addr *ip) ++horrible_allowedips_lookup_v4(struct horrible_allowedips *table, struct in_addr *ip) + { + struct horrible_allowedips_node *node; +- void *ret = NULL; + + hlist_for_each_entry(node, &table->head, table) { +- if (node->ip_version != 4) +- continue; +- if (horrible_match_v4(node, ip)) { +- ret = node->value; +- break; +- } ++ if (node->ip_version == 4 && horrible_match_v4(node, ip)) ++ return node->value; + } +- return ret; ++ return NULL; + } + + static __init void * +-horrible_allowedips_lookup_v6(struct horrible_allowedips *table, +- struct in6_addr *ip) ++horrible_allowedips_lookup_v6(struct horrible_allowedips *table, struct in6_addr *ip) + { + struct horrible_allowedips_node *node; +- void *ret = NULL; + + hlist_for_each_entry(node, &table->head, table) { +- if (node->ip_version != 6) ++ if (node->ip_version == 6 && horrible_match_v6(node, ip)) ++ return node->value; ++ } ++ return NULL; ++} ++ ++ ++static __init void ++horrible_allowedips_remove_by_value(struct horrible_allowedips *table, void *value) ++{ ++ struct horrible_allowedips_node *node; ++ struct hlist_node *h; ++ ++ hlist_for_each_entry_safe(node, h, &table->head, table) { ++ if (node->value != value) + continue; +- if (horrible_match_v6(node, ip)) { +- ret = node->value; +- break; +- } ++ hlist_del(&node->table); ++ kfree(node); + } +- return ret; ++ + } + + static __init bool randomized_test(void) +@@ -296,6 +278,7 @@ static __init bool randomized_test(void) + goto free; + } + kref_init(&peers[i]->refcount); ++ INIT_LIST_HEAD(&peers[i]->allowedips_list); + } + + mutex_lock(&mutex); +@@ -333,7 +316,7 @@ static __init bool randomized_test(void) + if (wg_allowedips_insert_v4(&t, + (struct in_addr *)mutated, + cidr, peer, &mutex) < 0) { +- pr_err("allowedips random malloc: FAIL\n"); ++ pr_err("allowedips random self-test malloc: FAIL\n"); + goto free_locked; + } + if (horrible_allowedips_insert_v4(&h, +@@ -396,23 +379,33 @@ static __init bool randomized_test(void) + print_tree(t.root6, 128); + } + +- for (i = 0; i < NUM_QUERIES; ++i) { +- prandom_bytes(ip, 4); +- if (lookup(t.root4, 32, ip) != +- horrible_allowedips_lookup_v4(&h, (struct in_addr *)ip)) { +- pr_err("allowedips random self-test: FAIL\n"); +- goto free; ++ for (j = 0;; ++j) { ++ for (i = 0; i < NUM_QUERIES; ++i) { ++ prandom_bytes(ip, 4); ++ if (lookup(t.root4, 32, ip) != horrible_allowedips_lookup_v4(&h, (struct in_addr *)ip)) { ++ horrible_allowedips_lookup_v4(&h, (struct in_addr *)ip); ++ pr_err("allowedips random v4 self-test: FAIL\n"); ++ goto free; ++ } ++ prandom_bytes(ip, 16); ++ if (lookup(t.root6, 128, ip) != horrible_allowedips_lookup_v6(&h, (struct in6_addr *)ip)) { ++ pr_err("allowedips random v6 self-test: FAIL\n"); ++ goto free; ++ } + } ++ if (j >= NUM_PEERS) ++ break; ++ mutex_lock(&mutex); ++ wg_allowedips_remove_by_peer(&t, peers[j], &mutex); ++ mutex_unlock(&mutex); ++ horrible_allowedips_remove_by_value(&h, peers[j]); + } + +- for (i = 0; i < NUM_QUERIES; ++i) { +- prandom_bytes(ip, 16); +- if (lookup(t.root6, 128, ip) != +- horrible_allowedips_lookup_v6(&h, (struct in6_addr *)ip)) { +- pr_err("allowedips random self-test: FAIL\n"); +- goto free; +- } ++ if (t.root4 || t.root6) { ++ pr_err("allowedips random self-test removal: FAIL\n"); ++ goto free; + } ++ + ret = true; + + free: +diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c +index d9ad850daa793..8c496b7471082 100644 +--- a/drivers/net/wireguard/socket.c ++++ b/drivers/net/wireguard/socket.c +@@ -430,7 +430,7 @@ void wg_socket_reinit(struct wg_device *wg, struct sock *new4, + if (new4) + wg->incoming_port = ntohs(inet_sk(new4)->inet_sport); + mutex_unlock(&wg->socket_update_lock); +- synchronize_rcu(); ++ synchronize_net(); + sock_free(old4); + sock_free(old6); + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c +index 02d0aa0b815e9..d2489dc9dc139 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c +@@ -87,7 +87,7 @@ static const struct ieee80211_ops mt76x0e_ops = { + .reconfig_complete = mt76x02_reconfig_complete, + }; + +-static int mt76x0e_register_device(struct mt76x02_dev *dev) ++static int mt76x0e_init_hardware(struct mt76x02_dev *dev, bool resume) + { + int err; + +@@ -100,9 +100,11 @@ static int mt76x0e_register_device(struct mt76x02_dev *dev) + if (err < 0) + return err; + +- err = mt76x02_dma_init(dev); +- if (err < 0) +- return err; ++ if (!resume) { ++ err = mt76x02_dma_init(dev); ++ if (err < 0) ++ return err; ++ } + + err = mt76x0_init_hardware(dev); + if (err < 0) +@@ -123,6 +125,17 @@ static int mt76x0e_register_device(struct mt76x02_dev *dev) + mt76_clear(dev, 0x110, BIT(9)); + mt76_set(dev, MT_MAX_LEN_CFG, BIT(13)); + ++ return 0; ++} ++ ++static int mt76x0e_register_device(struct mt76x02_dev *dev) ++{ ++ int err; ++ ++ err = mt76x0e_init_hardware(dev, false); ++ if (err < 0) ++ return err; ++ + err = mt76x0_register_device(dev); + if (err < 0) + return err; +@@ -167,6 +180,8 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (ret) + return ret; + ++ mt76_pci_disable_aspm(pdev); ++ + mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt76x0e_ops, + &drv_ops); + if (!mdev) +@@ -220,6 +235,60 @@ mt76x0e_remove(struct pci_dev *pdev) + mt76_free_device(mdev); + } + ++#ifdef CONFIG_PM ++static int mt76x0e_suspend(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct mt76_dev *mdev = pci_get_drvdata(pdev); ++ struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); ++ int i; ++ ++ mt76_worker_disable(&mdev->tx_worker); ++ for (i = 0; i < ARRAY_SIZE(mdev->phy.q_tx); i++) ++ mt76_queue_tx_cleanup(dev, mdev->phy.q_tx[i], true); ++ for (i = 0; i < ARRAY_SIZE(mdev->q_mcu); i++) ++ mt76_queue_tx_cleanup(dev, mdev->q_mcu[i], true); ++ napi_disable(&mdev->tx_napi); ++ ++ mt76_for_each_q_rx(mdev, i) ++ napi_disable(&mdev->napi[i]); ++ ++ mt76x02_dma_disable(dev); ++ mt76x02_mcu_cleanup(dev); ++ mt76x0_chip_onoff(dev, false, false); ++ ++ pci_enable_wake(pdev, pci_choose_state(pdev, state), true); ++ pci_save_state(pdev); ++ ++ return pci_set_power_state(pdev, pci_choose_state(pdev, state)); ++} ++ ++static int mt76x0e_resume(struct pci_dev *pdev) ++{ ++ struct mt76_dev *mdev = pci_get_drvdata(pdev); ++ struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); ++ int err, i; ++ ++ err = pci_set_power_state(pdev, PCI_D0); ++ if (err) ++ return err; ++ ++ pci_restore_state(pdev); ++ ++ mt76_worker_enable(&mdev->tx_worker); ++ ++ mt76_for_each_q_rx(mdev, i) { ++ mt76_queue_rx_reset(dev, i); ++ napi_enable(&mdev->napi[i]); ++ napi_schedule(&mdev->napi[i]); ++ } ++ ++ napi_enable(&mdev->tx_napi); ++ napi_schedule(&mdev->tx_napi); ++ ++ return mt76x0e_init_hardware(dev, true); ++} ++#endif /* CONFIG_PM */ ++ + static const struct pci_device_id mt76x0e_device_table[] = { + { PCI_DEVICE(0x14c3, 0x7610) }, + { PCI_DEVICE(0x14c3, 0x7630) }, +@@ -237,6 +306,10 @@ static struct pci_driver mt76x0e_driver = { + .id_table = mt76x0e_device_table, + .probe = mt76x0e_probe, + .remove = mt76x0e_remove, ++#ifdef CONFIG_PM ++ .suspend = mt76x0e_suspend, ++ .resume = mt76x0e_resume, ++#endif /* CONFIG_PM */ + }; + + module_pci_driver(mt76x0e_driver); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +index 62afbad77596b..be88c9f5637a5 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +@@ -391,29 +391,37 @@ static void + mt7921_mcu_tx_rate_report(struct mt7921_dev *dev, struct sk_buff *skb, + u16 wlan_idx) + { +- struct mt7921_mcu_wlan_info_event *wtbl_info = +- (struct mt7921_mcu_wlan_info_event *)(skb->data); +- struct rate_info rate = {}; +- u8 curr_idx = wtbl_info->rate_info.rate_idx; +- u16 curr = le16_to_cpu(wtbl_info->rate_info.rate[curr_idx]); +- struct mt7921_mcu_peer_cap peer = wtbl_info->peer_cap; ++ struct mt7921_mcu_wlan_info_event *wtbl_info; + struct mt76_phy *mphy = &dev->mphy; + struct mt7921_sta_stats *stats; ++ struct rate_info rate = {}; + struct mt7921_sta *msta; + struct mt76_wcid *wcid; ++ u8 idx; + + if (wlan_idx >= MT76_N_WCIDS) + return; ++ ++ wtbl_info = (struct mt7921_mcu_wlan_info_event *)skb->data; ++ idx = wtbl_info->rate_info.rate_idx; ++ if (idx >= ARRAY_SIZE(wtbl_info->rate_info.rate)) ++ return; ++ ++ rcu_read_lock(); ++ + wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]); + if (!wcid) +- return; ++ goto out; + + msta = container_of(wcid, struct mt7921_sta, wcid); + stats = &msta->stats; + + /* current rate */ +- mt7921_mcu_tx_rate_parse(mphy, &peer, &rate, curr); ++ mt7921_mcu_tx_rate_parse(mphy, &wtbl_info->peer_cap, &rate, ++ le16_to_cpu(wtbl_info->rate_info.rate[idx])); + stats->tx_rate = rate; ++out: ++ rcu_read_unlock(); + } + + static void +diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c +index 193b723fe3bd7..c58996c1e2309 100644 +--- a/drivers/net/xen-netback/interface.c ++++ b/drivers/net/xen-netback/interface.c +@@ -684,6 +684,7 @@ static void xenvif_disconnect_queue(struct xenvif_queue *queue) + { + if (queue->task) { + kthread_stop(queue->task); ++ put_task_struct(queue->task); + queue->task = NULL; + } + +@@ -745,6 +746,11 @@ int xenvif_connect_data(struct xenvif_queue *queue, + if (IS_ERR(task)) + goto kthread_err; + queue->task = task; ++ /* ++ * Take a reference to the task in order to prevent it from being freed ++ * if the thread function returns before kthread_stop is called. ++ */ ++ get_task_struct(task); + + task = kthread_run(xenvif_dealloc_kthread, queue, + "%s-dealloc", queue->name); +diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c +index be905d4fdb47f..ce8b3ce7582be 100644 +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -1319,16 +1319,17 @@ static int nvme_rdma_map_sg_inline(struct nvme_rdma_queue *queue, + int count) + { + struct nvme_sgl_desc *sg = &c->common.dptr.sgl; +- struct scatterlist *sgl = req->data_sgl.sg_table.sgl; + struct ib_sge *sge = &req->sge[1]; ++ struct scatterlist *sgl; + u32 len = 0; + int i; + +- for (i = 0; i < count; i++, sgl++, sge++) { ++ for_each_sg(req->data_sgl.sg_table.sgl, sgl, count, i) { + sge->addr = sg_dma_address(sgl); + sge->length = sg_dma_len(sgl); + sge->lkey = queue->device->pd->local_dma_lkey; + len += sge->length; ++ sge++; + } + + sg->addr = cpu_to_le64(queue->ctrl->ctrl.icdoff); +diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c +index 348057fdc568f..7d16cb4cd8acf 100644 +--- a/drivers/nvme/target/core.c ++++ b/drivers/nvme/target/core.c +@@ -999,19 +999,23 @@ static unsigned int nvmet_data_transfer_len(struct nvmet_req *req) + return req->transfer_len - req->metadata_len; + } + +-static int nvmet_req_alloc_p2pmem_sgls(struct nvmet_req *req) ++static int nvmet_req_alloc_p2pmem_sgls(struct pci_dev *p2p_dev, ++ struct nvmet_req *req) + { +- req->sg = pci_p2pmem_alloc_sgl(req->p2p_dev, &req->sg_cnt, ++ req->sg = pci_p2pmem_alloc_sgl(p2p_dev, &req->sg_cnt, + nvmet_data_transfer_len(req)); + if (!req->sg) + goto out_err; + + if (req->metadata_len) { +- req->metadata_sg = pci_p2pmem_alloc_sgl(req->p2p_dev, ++ req->metadata_sg = pci_p2pmem_alloc_sgl(p2p_dev, + &req->metadata_sg_cnt, req->metadata_len); + if (!req->metadata_sg) + goto out_free_sg; + } ++ ++ req->p2p_dev = p2p_dev; ++ + return 0; + out_free_sg: + pci_p2pmem_free_sgl(req->p2p_dev, req->sg); +@@ -1019,25 +1023,19 @@ out_err: + return -ENOMEM; + } + +-static bool nvmet_req_find_p2p_dev(struct nvmet_req *req) ++static struct pci_dev *nvmet_req_find_p2p_dev(struct nvmet_req *req) + { +- if (!IS_ENABLED(CONFIG_PCI_P2PDMA)) +- return false; +- +- if (req->sq->ctrl && req->sq->qid && req->ns) { +- req->p2p_dev = radix_tree_lookup(&req->sq->ctrl->p2p_ns_map, +- req->ns->nsid); +- if (req->p2p_dev) +- return true; +- } +- +- req->p2p_dev = NULL; +- return false; ++ if (!IS_ENABLED(CONFIG_PCI_P2PDMA) || ++ !req->sq->ctrl || !req->sq->qid || !req->ns) ++ return NULL; ++ return radix_tree_lookup(&req->sq->ctrl->p2p_ns_map, req->ns->nsid); + } + + int nvmet_req_alloc_sgls(struct nvmet_req *req) + { +- if (nvmet_req_find_p2p_dev(req) && !nvmet_req_alloc_p2pmem_sgls(req)) ++ struct pci_dev *p2p_dev = nvmet_req_find_p2p_dev(req); ++ ++ if (p2p_dev && !nvmet_req_alloc_p2pmem_sgls(p2p_dev, req)) + return 0; + + req->sg = sgl_alloc(nvmet_data_transfer_len(req), GFP_KERNEL, +@@ -1066,6 +1064,7 @@ void nvmet_req_free_sgls(struct nvmet_req *req) + pci_p2pmem_free_sgl(req->p2p_dev, req->sg); + if (req->metadata_sg) + pci_p2pmem_free_sgl(req->p2p_dev, req->metadata_sg); ++ req->p2p_dev = NULL; + } else { + sgl_free(req->sg); + if (req->metadata_sg) +diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c +index 920cf329268b5..f8a5a4eb5bcef 100644 +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -20591,10 +20591,8 @@ lpfc_sli4_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + abtswqe = &abtsiocb->wqe; + memset(abtswqe, 0, sizeof(*abtswqe)); + +- if (lpfc_is_link_up(phba)) ++ if (!lpfc_is_link_up(phba)) + bf_set(abort_cmd_ia, &abtswqe->abort_cmd, 1); +- else +- bf_set(abort_cmd_ia, &abtswqe->abort_cmd, 0); + bf_set(abort_cmd_criteria, &abtswqe->abort_cmd, T_XRI_TAG); + abtswqe->abort_cmd.rsrvd5 = 0; + abtswqe->abort_cmd.wqe_com.abort_tag = xritag; +diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c +index 7a77e375b503c..6b52f0c526baa 100644 +--- a/drivers/tee/optee/call.c ++++ b/drivers/tee/optee/call.c +@@ -216,6 +216,7 @@ int optee_open_session(struct tee_context *ctx, + struct optee_msg_arg *msg_arg; + phys_addr_t msg_parg; + struct optee_session *sess = NULL; ++ uuid_t client_uuid; + + /* +2 for the meta parameters added below */ + shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg, &msg_parg); +@@ -236,10 +237,11 @@ int optee_open_session(struct tee_context *ctx, + memcpy(&msg_arg->params[0].u.value, arg->uuid, sizeof(arg->uuid)); + msg_arg->params[1].u.value.c = arg->clnt_login; + +- rc = tee_session_calc_client_uuid((uuid_t *)&msg_arg->params[1].u.value, +- arg->clnt_login, arg->clnt_uuid); ++ rc = tee_session_calc_client_uuid(&client_uuid, arg->clnt_login, ++ arg->clnt_uuid); + if (rc) + goto out; ++ export_uuid(msg_arg->params[1].u.octets, &client_uuid); + + rc = optee_to_msg_param(msg_arg->params + 2, arg->num_params, param); + if (rc) +diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h +index 81ff593ac4ec2..e3d72d09c4848 100644 +--- a/drivers/tee/optee/optee_msg.h ++++ b/drivers/tee/optee/optee_msg.h +@@ -9,7 +9,7 @@ + #include + + /* +- * This file defines the OP-TEE message protocol used to communicate ++ * This file defines the OP-TEE message protocol (ABI) used to communicate + * with an instance of OP-TEE running in secure world. + * + * This file is divided into two sections. +@@ -144,9 +144,10 @@ struct optee_msg_param_value { + * @tmem: parameter by temporary memory reference + * @rmem: parameter by registered memory reference + * @value: parameter by opaque value ++ * @octets: parameter by octet string + * + * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if tmem, rmem or value is used in +- * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value, ++ * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value or octets, + * OPTEE_MSG_ATTR_TYPE_TMEM_* indicates @tmem and + * OPTEE_MSG_ATTR_TYPE_RMEM_* indicates @rmem, + * OPTEE_MSG_ATTR_TYPE_NONE indicates that none of the members are used. +@@ -157,6 +158,7 @@ struct optee_msg_param { + struct optee_msg_param_tmem tmem; + struct optee_msg_param_rmem rmem; + struct optee_msg_param_value value; ++ u8 octets[24]; + } u; + }; + +diff --git a/drivers/thermal/intel/therm_throt.c b/drivers/thermal/intel/therm_throt.c +index f8e882592ba5d..99abdc03c44ce 100644 +--- a/drivers/thermal/intel/therm_throt.c ++++ b/drivers/thermal/intel/therm_throt.c +@@ -621,6 +621,17 @@ bool x86_thermal_enabled(void) + return atomic_read(&therm_throt_en); + } + ++void __init therm_lvt_init(void) ++{ ++ /* ++ * This function is only called on boot CPU. Save the init thermal ++ * LVT value on BSP and use that value to restore APs' thermal LVT ++ * entry BIOS programmed later ++ */ ++ if (intel_thermal_supported(&boot_cpu_data)) ++ lvtthmr_init = apic_read(APIC_LVTTHMR); ++} ++ + void intel_init_thermal(struct cpuinfo_x86 *c) + { + unsigned int cpu = smp_processor_id(); +@@ -630,10 +641,6 @@ void intel_init_thermal(struct cpuinfo_x86 *c) + if (!intel_thermal_supported(c)) + return; + +- /* On the BSP? */ +- if (c == &boot_cpu_data) +- lvtthmr_init = apic_read(APIC_LVTTHMR); +- + /* + * First check if its enabled already, in which case there might + * be some SMM goo which handles it, so we can't even put a handler +diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c +index 99dfa884cbefb..68c6535bbf7f0 100644 +--- a/drivers/tty/serial/stm32-usart.c ++++ b/drivers/tty/serial/stm32-usart.c +@@ -214,14 +214,11 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded) + struct tty_port *tport = &port->state->port; + struct stm32_port *stm32_port = to_stm32_port(port); + const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; +- unsigned long c, flags; ++ unsigned long c; + u32 sr; + char flag; + +- if (threaded) +- spin_lock_irqsave(&port->lock, flags); +- else +- spin_lock(&port->lock); ++ spin_lock(&port->lock); + + while (stm32_usart_pending_rx(port, &sr, &stm32_port->last_res, + threaded)) { +@@ -278,10 +275,7 @@ static void stm32_usart_receive_chars(struct uart_port *port, bool threaded) + uart_insert_char(port, sr, USART_SR_ORE, c, flag); + } + +- if (threaded) +- spin_unlock_irqrestore(&port->lock, flags); +- else +- spin_unlock(&port->lock); ++ spin_unlock(&port->lock); + + tty_flip_buffer_push(tport); + } +@@ -654,7 +648,8 @@ static int stm32_usart_startup(struct uart_port *port) + + ret = request_threaded_irq(port->irq, stm32_usart_interrupt, + stm32_usart_threaded_interrupt, +- IRQF_NO_SUSPEND, name, port); ++ IRQF_ONESHOT | IRQF_NO_SUSPEND, ++ name, port); + if (ret) + return ret; + +@@ -1136,6 +1131,13 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, + struct dma_async_tx_descriptor *desc = NULL; + int ret; + ++ /* ++ * Using DMA and threaded handler for the console could lead to ++ * deadlocks. ++ */ ++ if (uart_console(port)) ++ return -ENODEV; ++ + /* Request DMA RX channel */ + stm32port->rx_ch = dma_request_slave_channel(dev, "rx"); + if (!stm32port->rx_ch) { +diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c +index 510fd0572feb1..e3f429f1575e9 100644 +--- a/drivers/usb/dwc2/core_intr.c ++++ b/drivers/usb/dwc2/core_intr.c +@@ -707,7 +707,11 @@ static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg, + dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN); + + hsotg->hibernated = 0; ++ ++#if IS_ENABLED(CONFIG_USB_DWC2_HOST) || \ ++ IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) + hsotg->bus_suspended = 0; ++#endif + + if (gpwrdn & GPWRDN_IDSTS) { + hsotg->op_state = OTG_STATE_B_PERIPHERAL; +diff --git a/drivers/vfio/pci/Kconfig b/drivers/vfio/pci/Kconfig +index 4abddbebd4b23..c691127bc805a 100644 +--- a/drivers/vfio/pci/Kconfig ++++ b/drivers/vfio/pci/Kconfig +@@ -2,6 +2,7 @@ + config VFIO_PCI + tristate "VFIO support for PCI devices" + depends on VFIO && PCI && EVENTFD ++ depends on MMU + select VFIO_VIRQFD + select IRQ_BYPASS_MANAGER + help +diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c +index a402adee8a215..47f21a6ca7fe9 100644 +--- a/drivers/vfio/pci/vfio_pci_config.c ++++ b/drivers/vfio/pci/vfio_pci_config.c +@@ -1581,7 +1581,7 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev) + if (len == 0xFF) { + len = vfio_ext_cap_len(vdev, ecap, epos); + if (len < 0) +- return ret; ++ return len; + } + } + +diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c +index fb4b385191f28..e83a7cd15c956 100644 +--- a/drivers/vfio/platform/vfio_platform_common.c ++++ b/drivers/vfio/platform/vfio_platform_common.c +@@ -289,7 +289,7 @@ err_irq: + vfio_platform_regions_cleanup(vdev); + err_reg: + mutex_unlock(&driver_lock); +- module_put(THIS_MODULE); ++ module_put(vdev->parent_module); + return ret; + } + +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 5b82050b871a7..27c3680074814 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -1868,7 +1868,7 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans, + trace_run_delayed_ref_head(fs_info, head, 0); + btrfs_delayed_ref_unlock(head); + btrfs_put_delayed_ref_head(head); +- return 0; ++ return ret; + } + + static struct btrfs_delayed_ref_head *btrfs_obtain_ref_head( +diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c +index 47cd3a6dc6351..eed75bb0fedbf 100644 +--- a/fs/btrfs/file-item.c ++++ b/fs/btrfs/file-item.c +@@ -787,7 +787,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + u64 end_byte = bytenr + len; + u64 csum_end; + struct extent_buffer *leaf; +- int ret; ++ int ret = 0; + const u32 csum_size = fs_info->csum_size; + u32 blocksize_bits = fs_info->sectorsize_bits; + +@@ -805,6 +805,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); + if (ret > 0) { ++ ret = 0; + if (path->slots[0] == 0) + break; + path->slots[0]--; +@@ -861,7 +862,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + ret = btrfs_del_items(trans, root, path, + path->slots[0], del_nr); + if (ret) +- goto out; ++ break; + if (key.offset == bytenr) + break; + } else if (key.offset < bytenr && csum_end > end_byte) { +@@ -905,8 +906,9 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + ret = btrfs_split_item(trans, root, path, &key, offset); + if (ret && ret != -EAGAIN) { + btrfs_abort_transaction(trans, ret); +- goto out; ++ break; + } ++ ret = 0; + + key.offset = end_byte - 1; + } else { +@@ -916,12 +918,41 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, + } + btrfs_release_path(path); + } +- ret = 0; +-out: + btrfs_free_path(path); + return ret; + } + ++static int find_next_csum_offset(struct btrfs_root *root, ++ struct btrfs_path *path, ++ u64 *next_offset) ++{ ++ const u32 nritems = btrfs_header_nritems(path->nodes[0]); ++ struct btrfs_key found_key; ++ int slot = path->slots[0] + 1; ++ int ret; ++ ++ if (nritems == 0 || slot >= nritems) { ++ ret = btrfs_next_leaf(root, path); ++ if (ret < 0) { ++ return ret; ++ } else if (ret > 0) { ++ *next_offset = (u64)-1; ++ return 0; ++ } ++ slot = path->slots[0]; ++ } ++ ++ btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot); ++ ++ if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || ++ found_key.type != BTRFS_EXTENT_CSUM_KEY) ++ *next_offset = (u64)-1; ++ else ++ *next_offset = found_key.offset; ++ ++ return 0; ++} ++ + int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_ordered_sum *sums) +@@ -937,7 +968,6 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, + u64 total_bytes = 0; + u64 csum_offset; + u64 bytenr; +- u32 nritems; + u32 ins_size; + int index = 0; + int found_next; +@@ -980,26 +1010,10 @@ again: + goto insert; + } + } else { +- int slot = path->slots[0] + 1; +- /* we didn't find a csum item, insert one */ +- nritems = btrfs_header_nritems(path->nodes[0]); +- if (!nritems || (path->slots[0] >= nritems - 1)) { +- ret = btrfs_next_leaf(root, path); +- if (ret < 0) { +- goto out; +- } else if (ret > 0) { +- found_next = 1; +- goto insert; +- } +- slot = path->slots[0]; +- } +- btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot); +- if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID || +- found_key.type != BTRFS_EXTENT_CSUM_KEY) { +- found_next = 1; +- goto insert; +- } +- next_offset = found_key.offset; ++ /* We didn't find a csum item, insert one. */ ++ ret = find_next_csum_offset(root, path, &next_offset); ++ if (ret < 0) ++ goto out; + found_next = 1; + goto insert; + } +@@ -1055,8 +1069,48 @@ extend_csum: + tmp = sums->len - total_bytes; + tmp >>= fs_info->sectorsize_bits; + WARN_ON(tmp < 1); ++ extend_nr = max_t(int, 1, tmp); ++ ++ /* ++ * A log tree can already have checksum items with a subset of ++ * the checksums we are trying to log. This can happen after ++ * doing a sequence of partial writes into prealloc extents and ++ * fsyncs in between, with a full fsync logging a larger subrange ++ * of an extent for which a previous fast fsync logged a smaller ++ * subrange. And this happens in particular due to merging file ++ * extent items when we complete an ordered extent for a range ++ * covered by a prealloc extent - this is done at ++ * btrfs_mark_extent_written(). ++ * ++ * So if we try to extend the previous checksum item, which has ++ * a range that ends at the start of the range we want to insert, ++ * make sure we don't extend beyond the start offset of the next ++ * checksum item. If we are at the last item in the leaf, then ++ * forget the optimization of extending and add a new checksum ++ * item - it is not worth the complexity of releasing the path, ++ * getting the first key for the next leaf, repeat the btree ++ * search, etc, because log trees are temporary anyway and it ++ * would only save a few bytes of leaf space. ++ */ ++ if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { ++ if (path->slots[0] + 1 >= ++ btrfs_header_nritems(path->nodes[0])) { ++ ret = find_next_csum_offset(root, path, &next_offset); ++ if (ret < 0) ++ goto out; ++ found_next = 1; ++ goto insert; ++ } ++ ++ ret = find_next_csum_offset(root, path, &next_offset); ++ if (ret < 0) ++ goto out; ++ ++ tmp = (next_offset - bytenr) >> fs_info->sectorsize_bits; ++ if (tmp <= INT_MAX) ++ extend_nr = min_t(int, extend_nr, tmp); ++ } + +- extend_nr = max_t(int, 1, (int)tmp); + diff = (csum_offset + extend_nr) * csum_size; + diff = min(diff, + MAX_CSUM_ITEMS(fs_info, csum_size) * csum_size); +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 81b93c9c659b7..3bb8ce4969f31 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -3011,6 +3011,18 @@ out: + if (ret || truncated) { + u64 unwritten_start = start; + ++ /* ++ * If we failed to finish this ordered extent for any reason we ++ * need to make sure BTRFS_ORDERED_IOERR is set on the ordered ++ * extent, and mark the inode with the error if it wasn't ++ * already set. Any error during writeback would have already ++ * set the mapping error, so we need to set it if we're the ones ++ * marking this ordered extent as failed. ++ */ ++ if (ret && !test_and_set_bit(BTRFS_ORDERED_IOERR, ++ &ordered_extent->flags)) ++ mapping_set_error(ordered_extent->inode->i_mapping, -EIO); ++ + if (truncated) + unwritten_start += logical_len; + clear_extent_uptodate(io_tree, unwritten_start, end, NULL); +@@ -9076,6 +9088,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, + int ret2; + bool root_log_pinned = false; + bool dest_log_pinned = false; ++ bool need_abort = false; + + /* we only allow rename subvolume link between subvolumes */ + if (old_ino != BTRFS_FIRST_FREE_OBJECTID && root != dest) +@@ -9132,6 +9145,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, + old_idx); + if (ret) + goto out_fail; ++ need_abort = true; + } + + /* And now for the dest. */ +@@ -9147,8 +9161,11 @@ static int btrfs_rename_exchange(struct inode *old_dir, + new_ino, + btrfs_ino(BTRFS_I(old_dir)), + new_idx); +- if (ret) ++ if (ret) { ++ if (need_abort) ++ btrfs_abort_transaction(trans, ret); + goto out_fail; ++ } + } + + /* Update inode version and ctime/mtime. */ +diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c +index 53ee17f5e382c..238e713635d79 100644 +--- a/fs/btrfs/reflink.c ++++ b/fs/btrfs/reflink.c +@@ -207,10 +207,7 @@ static int clone_copy_inline_extent(struct inode *dst, + * inline extent's data to the page. + */ + ASSERT(key.offset > 0); +- ret = copy_inline_to_page(BTRFS_I(dst), new_key->offset, +- inline_data, size, datal, +- comp_type); +- goto out; ++ goto copy_to_page; + } + } else if (i_size_read(dst) <= datal) { + struct btrfs_file_extent_item *ei; +@@ -226,13 +223,10 @@ static int clone_copy_inline_extent(struct inode *dst, + BTRFS_FILE_EXTENT_INLINE) + goto copy_inline_extent; + +- ret = copy_inline_to_page(BTRFS_I(dst), new_key->offset, +- inline_data, size, datal, comp_type); +- goto out; ++ goto copy_to_page; + } + + copy_inline_extent: +- ret = 0; + /* + * We have no extent items, or we have an extent at offset 0 which may + * or may not be inlined. All these cases are dealt the same way. +@@ -244,11 +238,13 @@ copy_inline_extent: + * clone. Deal with all these cases by copying the inline extent + * data into the respective page at the destination inode. + */ +- ret = copy_inline_to_page(BTRFS_I(dst), new_key->offset, +- inline_data, size, datal, comp_type); +- goto out; ++ goto copy_to_page; + } + ++ /* ++ * Release path before starting a new transaction so we don't hold locks ++ * that would confuse lockdep. ++ */ + btrfs_release_path(path); + /* + * If we end up here it means were copy the inline extent into a leaf +@@ -285,11 +281,6 @@ copy_inline_extent: + ret = btrfs_inode_set_file_extent_range(BTRFS_I(dst), 0, aligned_end); + out: + if (!ret && !trans) { +- /* +- * Release path before starting a new transaction so we don't +- * hold locks that would confuse lockdep. +- */ +- btrfs_release_path(path); + /* + * No transaction here means we copied the inline extent into a + * page of the destination inode. +@@ -310,6 +301,21 @@ out: + *trans_out = trans; + + return ret; ++ ++copy_to_page: ++ /* ++ * Release our path because we don't need it anymore and also because ++ * copy_inline_to_page() needs to reserve data and metadata, which may ++ * need to flush delalloc when we are low on available space and ++ * therefore cause a deadlock if writeback of an inline extent needs to ++ * write to the same leaf or an ordered extent completion needs to write ++ * to the same leaf. ++ */ ++ btrfs_release_path(path); ++ ++ ret = copy_inline_to_page(BTRFS_I(dst), new_key->offset, ++ inline_data, size, datal, comp_type); ++ goto out; + } + + /** +diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c +index d7f1599e69b1f..faae6ebd8a279 100644 +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -1574,7 +1574,9 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, + if (ret) + goto out; + +- btrfs_update_inode(trans, root, BTRFS_I(inode)); ++ ret = btrfs_update_inode(trans, root, BTRFS_I(inode)); ++ if (ret) ++ goto out; + } + + ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen; +@@ -1749,7 +1751,9 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, + + if (nlink != inode->i_nlink) { + set_nlink(inode, nlink); +- btrfs_update_inode(trans, root, BTRFS_I(inode)); ++ ret = btrfs_update_inode(trans, root, BTRFS_I(inode)); ++ if (ret) ++ goto out; + } + BTRFS_I(inode)->index_cnt = (u64)-1; + +@@ -1787,6 +1791,7 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + break; + + if (ret == 1) { ++ ret = 0; + if (path->slots[0] == 0) + break; + path->slots[0]--; +@@ -1799,17 +1804,19 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + + ret = btrfs_del_item(trans, root, path); + if (ret) +- goto out; ++ break; + + btrfs_release_path(path); + inode = read_one_inode(root, key.offset); +- if (!inode) +- return -EIO; ++ if (!inode) { ++ ret = -EIO; ++ break; ++ } + + ret = fixup_inode_link_count(trans, root, inode); + iput(inode); + if (ret) +- goto out; ++ break; + + /* + * fixup on a directory may create new entries, +@@ -1818,8 +1825,6 @@ static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, + */ + key.offset = (u64)-1; + } +- ret = 0; +-out: + btrfs_release_path(path); + return ret; + } +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 77c84d6f1af6b..cbf37b2cf871e 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -3206,7 +3206,10 @@ static int ext4_split_extent_at(handle_t *handle, + ext4_ext_mark_unwritten(ex2); + + err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags); +- if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { ++ if (err != -ENOSPC && err != -EDQUOT) ++ goto out; ++ ++ if (EXT4_EXT_MAY_ZEROOUT & split_flag) { + if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { + if (split_flag & EXT4_EXT_DATA_VALID1) { + err = ext4_ext_zeroout(inode, ex2); +@@ -3232,25 +3235,22 @@ static int ext4_split_extent_at(handle_t *handle, + ext4_ext_pblock(&orig_ex)); + } + +- if (err) +- goto fix_extent_len; +- /* update the extent length and mark as initialized */ +- ex->ee_len = cpu_to_le16(ee_len); +- ext4_ext_try_to_merge(handle, inode, path, ex); +- err = ext4_ext_dirty(handle, inode, path + path->p_depth); +- if (err) +- goto fix_extent_len; +- +- /* update extent status tree */ +- err = ext4_zeroout_es(inode, &zero_ex); +- +- goto out; +- } else if (err) +- goto fix_extent_len; +- +-out: +- ext4_ext_show_leaf(inode, path); +- return err; ++ if (!err) { ++ /* update the extent length and mark as initialized */ ++ ex->ee_len = cpu_to_le16(ee_len); ++ ext4_ext_try_to_merge(handle, inode, path, ex); ++ err = ext4_ext_dirty(handle, inode, path + path->p_depth); ++ if (!err) ++ /* update extent status tree */ ++ err = ext4_zeroout_es(inode, &zero_ex); ++ /* If we failed at this point, we don't know in which ++ * state the extent tree exactly is so don't try to fix ++ * length of the original extent as it may do even more ++ * damage. ++ */ ++ goto out; ++ } ++ } + + fix_extent_len: + ex->ee_len = orig_ex.ee_len; +@@ -3260,6 +3260,9 @@ fix_extent_len: + */ + ext4_ext_dirty(handle, inode, path + path->p_depth); + return err; ++out: ++ ext4_ext_show_leaf(inode, path); ++ return err; + } + + /* +diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c +index eda14f630def4..c1c962b118012 100644 +--- a/fs/ext4/fast_commit.c ++++ b/fs/ext4/fast_commit.c +@@ -1288,28 +1288,29 @@ struct dentry_info_args { + }; + + static inline void tl_to_darg(struct dentry_info_args *darg, +- struct ext4_fc_tl *tl) ++ struct ext4_fc_tl *tl, u8 *val) + { +- struct ext4_fc_dentry_info *fcd; ++ struct ext4_fc_dentry_info fcd; + +- fcd = (struct ext4_fc_dentry_info *)ext4_fc_tag_val(tl); ++ memcpy(&fcd, val, sizeof(fcd)); + +- darg->parent_ino = le32_to_cpu(fcd->fc_parent_ino); +- darg->ino = le32_to_cpu(fcd->fc_ino); +- darg->dname = fcd->fc_dname; +- darg->dname_len = ext4_fc_tag_len(tl) - +- sizeof(struct ext4_fc_dentry_info); ++ darg->parent_ino = le32_to_cpu(fcd.fc_parent_ino); ++ darg->ino = le32_to_cpu(fcd.fc_ino); ++ darg->dname = val + offsetof(struct ext4_fc_dentry_info, fc_dname); ++ darg->dname_len = le16_to_cpu(tl->fc_len) - ++ sizeof(struct ext4_fc_dentry_info); + } + + /* Unlink replay function */ +-static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl) ++static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl, ++ u8 *val) + { + struct inode *inode, *old_parent; + struct qstr entry; + struct dentry_info_args darg; + int ret = 0; + +- tl_to_darg(&darg, tl); ++ tl_to_darg(&darg, tl, val); + + trace_ext4_fc_replay(sb, EXT4_FC_TAG_UNLINK, darg.ino, + darg.parent_ino, darg.dname_len); +@@ -1399,13 +1400,14 @@ out: + } + + /* Link replay function */ +-static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl) ++static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl, ++ u8 *val) + { + struct inode *inode; + struct dentry_info_args darg; + int ret = 0; + +- tl_to_darg(&darg, tl); ++ tl_to_darg(&darg, tl, val); + trace_ext4_fc_replay(sb, EXT4_FC_TAG_LINK, darg.ino, + darg.parent_ino, darg.dname_len); + +@@ -1450,9 +1452,10 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino) + /* + * Inode replay function + */ +-static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl) ++static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl, ++ u8 *val) + { +- struct ext4_fc_inode *fc_inode; ++ struct ext4_fc_inode fc_inode; + struct ext4_inode *raw_inode; + struct ext4_inode *raw_fc_inode; + struct inode *inode = NULL; +@@ -1460,9 +1463,9 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl) + int inode_len, ino, ret, tag = le16_to_cpu(tl->fc_tag); + struct ext4_extent_header *eh; + +- fc_inode = (struct ext4_fc_inode *)ext4_fc_tag_val(tl); ++ memcpy(&fc_inode, val, sizeof(fc_inode)); + +- ino = le32_to_cpu(fc_inode->fc_ino); ++ ino = le32_to_cpu(fc_inode.fc_ino); + trace_ext4_fc_replay(sb, tag, ino, 0, 0); + + inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); +@@ -1474,12 +1477,13 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl) + + ext4_fc_record_modified_inode(sb, ino); + +- raw_fc_inode = (struct ext4_inode *)fc_inode->fc_raw_inode; ++ raw_fc_inode = (struct ext4_inode *) ++ (val + offsetof(struct ext4_fc_inode, fc_raw_inode)); + ret = ext4_get_fc_inode_loc(sb, ino, &iloc); + if (ret) + goto out; + +- inode_len = ext4_fc_tag_len(tl) - sizeof(struct ext4_fc_inode); ++ inode_len = le16_to_cpu(tl->fc_len) - sizeof(struct ext4_fc_inode); + raw_inode = ext4_raw_inode(&iloc); + + memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block)); +@@ -1547,14 +1551,15 @@ out: + * inode for which we are trying to create a dentry here, should already have + * been replayed before we start here. + */ +-static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl) ++static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl, ++ u8 *val) + { + int ret = 0; + struct inode *inode = NULL; + struct inode *dir = NULL; + struct dentry_info_args darg; + +- tl_to_darg(&darg, tl); ++ tl_to_darg(&darg, tl, val); + + trace_ext4_fc_replay(sb, EXT4_FC_TAG_CREAT, darg.ino, + darg.parent_ino, darg.dname_len); +@@ -1633,9 +1638,9 @@ static int ext4_fc_record_regions(struct super_block *sb, int ino, + + /* Replay add range tag */ + static int ext4_fc_replay_add_range(struct super_block *sb, +- struct ext4_fc_tl *tl) ++ struct ext4_fc_tl *tl, u8 *val) + { +- struct ext4_fc_add_range *fc_add_ex; ++ struct ext4_fc_add_range fc_add_ex; + struct ext4_extent newex, *ex; + struct inode *inode; + ext4_lblk_t start, cur; +@@ -1645,15 +1650,14 @@ static int ext4_fc_replay_add_range(struct super_block *sb, + struct ext4_ext_path *path = NULL; + int ret; + +- fc_add_ex = (struct ext4_fc_add_range *)ext4_fc_tag_val(tl); +- ex = (struct ext4_extent *)&fc_add_ex->fc_ex; ++ memcpy(&fc_add_ex, val, sizeof(fc_add_ex)); ++ ex = (struct ext4_extent *)&fc_add_ex.fc_ex; + + trace_ext4_fc_replay(sb, EXT4_FC_TAG_ADD_RANGE, +- le32_to_cpu(fc_add_ex->fc_ino), le32_to_cpu(ex->ee_block), ++ le32_to_cpu(fc_add_ex.fc_ino), le32_to_cpu(ex->ee_block), + ext4_ext_get_actual_len(ex)); + +- inode = ext4_iget(sb, le32_to_cpu(fc_add_ex->fc_ino), +- EXT4_IGET_NORMAL); ++ inode = ext4_iget(sb, le32_to_cpu(fc_add_ex.fc_ino), EXT4_IGET_NORMAL); + if (IS_ERR(inode)) { + jbd_debug(1, "Inode not found."); + return 0; +@@ -1762,32 +1766,33 @@ next: + + /* Replay DEL_RANGE tag */ + static int +-ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl) ++ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl, ++ u8 *val) + { + struct inode *inode; +- struct ext4_fc_del_range *lrange; ++ struct ext4_fc_del_range lrange; + struct ext4_map_blocks map; + ext4_lblk_t cur, remaining; + int ret; + +- lrange = (struct ext4_fc_del_range *)ext4_fc_tag_val(tl); +- cur = le32_to_cpu(lrange->fc_lblk); +- remaining = le32_to_cpu(lrange->fc_len); ++ memcpy(&lrange, val, sizeof(lrange)); ++ cur = le32_to_cpu(lrange.fc_lblk); ++ remaining = le32_to_cpu(lrange.fc_len); + + trace_ext4_fc_replay(sb, EXT4_FC_TAG_DEL_RANGE, +- le32_to_cpu(lrange->fc_ino), cur, remaining); ++ le32_to_cpu(lrange.fc_ino), cur, remaining); + +- inode = ext4_iget(sb, le32_to_cpu(lrange->fc_ino), EXT4_IGET_NORMAL); ++ inode = ext4_iget(sb, le32_to_cpu(lrange.fc_ino), EXT4_IGET_NORMAL); + if (IS_ERR(inode)) { +- jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange->fc_ino)); ++ jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange.fc_ino)); + return 0; + } + + ret = ext4_fc_record_modified_inode(sb, inode->i_ino); + + jbd_debug(1, "DEL_RANGE, inode %ld, lblk %d, len %d\n", +- inode->i_ino, le32_to_cpu(lrange->fc_lblk), +- le32_to_cpu(lrange->fc_len)); ++ inode->i_ino, le32_to_cpu(lrange.fc_lblk), ++ le32_to_cpu(lrange.fc_len)); + while (remaining > 0) { + map.m_lblk = cur; + map.m_len = remaining; +@@ -1808,8 +1813,8 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl) + } + + ret = ext4_punch_hole(inode, +- le32_to_cpu(lrange->fc_lblk) << sb->s_blocksize_bits, +- le32_to_cpu(lrange->fc_len) << sb->s_blocksize_bits); ++ le32_to_cpu(lrange.fc_lblk) << sb->s_blocksize_bits, ++ le32_to_cpu(lrange.fc_len) << sb->s_blocksize_bits); + if (ret) + jbd_debug(1, "ext4_punch_hole returned %d", ret); + ext4_ext_replay_shrink_inode(inode, +@@ -1925,11 +1930,11 @@ static int ext4_fc_replay_scan(journal_t *journal, + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_fc_replay_state *state; + int ret = JBD2_FC_REPLAY_CONTINUE; +- struct ext4_fc_add_range *ext; +- struct ext4_fc_tl *tl; +- struct ext4_fc_tail *tail; +- __u8 *start, *end; +- struct ext4_fc_head *head; ++ struct ext4_fc_add_range ext; ++ struct ext4_fc_tl tl; ++ struct ext4_fc_tail tail; ++ __u8 *start, *end, *cur, *val; ++ struct ext4_fc_head head; + struct ext4_extent *ex; + + state = &sbi->s_fc_replay_state; +@@ -1956,15 +1961,17 @@ static int ext4_fc_replay_scan(journal_t *journal, + } + + state->fc_replay_expected_off++; +- fc_for_each_tl(start, end, tl) { ++ for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) { ++ memcpy(&tl, cur, sizeof(tl)); ++ val = cur + sizeof(tl); + jbd_debug(3, "Scan phase, tag:%s, blk %lld\n", +- tag2str(le16_to_cpu(tl->fc_tag)), bh->b_blocknr); +- switch (le16_to_cpu(tl->fc_tag)) { ++ tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr); ++ switch (le16_to_cpu(tl.fc_tag)) { + case EXT4_FC_TAG_ADD_RANGE: +- ext = (struct ext4_fc_add_range *)ext4_fc_tag_val(tl); +- ex = (struct ext4_extent *)&ext->fc_ex; ++ memcpy(&ext, val, sizeof(ext)); ++ ex = (struct ext4_extent *)&ext.fc_ex; + ret = ext4_fc_record_regions(sb, +- le32_to_cpu(ext->fc_ino), ++ le32_to_cpu(ext.fc_ino), + le32_to_cpu(ex->ee_block), ext4_ext_pblock(ex), + ext4_ext_get_actual_len(ex)); + if (ret < 0) +@@ -1978,18 +1985,18 @@ static int ext4_fc_replay_scan(journal_t *journal, + case EXT4_FC_TAG_INODE: + case EXT4_FC_TAG_PAD: + state->fc_cur_tag++; +- state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl, +- sizeof(*tl) + ext4_fc_tag_len(tl)); ++ state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur, ++ sizeof(tl) + le16_to_cpu(tl.fc_len)); + break; + case EXT4_FC_TAG_TAIL: + state->fc_cur_tag++; +- tail = (struct ext4_fc_tail *)ext4_fc_tag_val(tl); +- state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl, +- sizeof(*tl) + ++ memcpy(&tail, val, sizeof(tail)); ++ state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur, ++ sizeof(tl) + + offsetof(struct ext4_fc_tail, + fc_crc)); +- if (le32_to_cpu(tail->fc_tid) == expected_tid && +- le32_to_cpu(tail->fc_crc) == state->fc_crc) { ++ if (le32_to_cpu(tail.fc_tid) == expected_tid && ++ le32_to_cpu(tail.fc_crc) == state->fc_crc) { + state->fc_replay_num_tags = state->fc_cur_tag; + state->fc_regions_valid = + state->fc_regions_used; +@@ -2000,19 +2007,19 @@ static int ext4_fc_replay_scan(journal_t *journal, + state->fc_crc = 0; + break; + case EXT4_FC_TAG_HEAD: +- head = (struct ext4_fc_head *)ext4_fc_tag_val(tl); +- if (le32_to_cpu(head->fc_features) & ++ memcpy(&head, val, sizeof(head)); ++ if (le32_to_cpu(head.fc_features) & + ~EXT4_FC_SUPPORTED_FEATURES) { + ret = -EOPNOTSUPP; + break; + } +- if (le32_to_cpu(head->fc_tid) != expected_tid) { ++ if (le32_to_cpu(head.fc_tid) != expected_tid) { + ret = JBD2_FC_REPLAY_STOP; + break; + } + state->fc_cur_tag++; +- state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl, +- sizeof(*tl) + ext4_fc_tag_len(tl)); ++ state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur, ++ sizeof(tl) + le16_to_cpu(tl.fc_len)); + break; + default: + ret = state->fc_replay_num_tags ? +@@ -2036,11 +2043,11 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh, + { + struct super_block *sb = journal->j_private; + struct ext4_sb_info *sbi = EXT4_SB(sb); +- struct ext4_fc_tl *tl; +- __u8 *start, *end; ++ struct ext4_fc_tl tl; ++ __u8 *start, *end, *cur, *val; + int ret = JBD2_FC_REPLAY_CONTINUE; + struct ext4_fc_replay_state *state = &sbi->s_fc_replay_state; +- struct ext4_fc_tail *tail; ++ struct ext4_fc_tail tail; + + if (pass == PASS_SCAN) { + state->fc_current_pass = PASS_SCAN; +@@ -2067,49 +2074,52 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh, + start = (u8 *)bh->b_data; + end = (__u8 *)bh->b_data + journal->j_blocksize - 1; + +- fc_for_each_tl(start, end, tl) { ++ for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) { ++ memcpy(&tl, cur, sizeof(tl)); ++ val = cur + sizeof(tl); ++ + if (state->fc_replay_num_tags == 0) { + ret = JBD2_FC_REPLAY_STOP; + ext4_fc_set_bitmaps_and_counters(sb); + break; + } + jbd_debug(3, "Replay phase, tag:%s\n", +- tag2str(le16_to_cpu(tl->fc_tag))); ++ tag2str(le16_to_cpu(tl.fc_tag))); + state->fc_replay_num_tags--; +- switch (le16_to_cpu(tl->fc_tag)) { ++ switch (le16_to_cpu(tl.fc_tag)) { + case EXT4_FC_TAG_LINK: +- ret = ext4_fc_replay_link(sb, tl); ++ ret = ext4_fc_replay_link(sb, &tl, val); + break; + case EXT4_FC_TAG_UNLINK: +- ret = ext4_fc_replay_unlink(sb, tl); ++ ret = ext4_fc_replay_unlink(sb, &tl, val); + break; + case EXT4_FC_TAG_ADD_RANGE: +- ret = ext4_fc_replay_add_range(sb, tl); ++ ret = ext4_fc_replay_add_range(sb, &tl, val); + break; + case EXT4_FC_TAG_CREAT: +- ret = ext4_fc_replay_create(sb, tl); ++ ret = ext4_fc_replay_create(sb, &tl, val); + break; + case EXT4_FC_TAG_DEL_RANGE: +- ret = ext4_fc_replay_del_range(sb, tl); ++ ret = ext4_fc_replay_del_range(sb, &tl, val); + break; + case EXT4_FC_TAG_INODE: +- ret = ext4_fc_replay_inode(sb, tl); ++ ret = ext4_fc_replay_inode(sb, &tl, val); + break; + case EXT4_FC_TAG_PAD: + trace_ext4_fc_replay(sb, EXT4_FC_TAG_PAD, 0, +- ext4_fc_tag_len(tl), 0); ++ le16_to_cpu(tl.fc_len), 0); + break; + case EXT4_FC_TAG_TAIL: + trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, 0, +- ext4_fc_tag_len(tl), 0); +- tail = (struct ext4_fc_tail *)ext4_fc_tag_val(tl); +- WARN_ON(le32_to_cpu(tail->fc_tid) != expected_tid); ++ le16_to_cpu(tl.fc_len), 0); ++ memcpy(&tail, val, sizeof(tail)); ++ WARN_ON(le32_to_cpu(tail.fc_tid) != expected_tid); + break; + case EXT4_FC_TAG_HEAD: + break; + default: +- trace_ext4_fc_replay(sb, le16_to_cpu(tl->fc_tag), 0, +- ext4_fc_tag_len(tl), 0); ++ trace_ext4_fc_replay(sb, le16_to_cpu(tl.fc_tag), 0, ++ le16_to_cpu(tl.fc_len), 0); + ret = -ECANCELED; + break; + } +diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h +index b77f70f55a622..937c381b4c85e 100644 +--- a/fs/ext4/fast_commit.h ++++ b/fs/ext4/fast_commit.h +@@ -153,13 +153,6 @@ struct ext4_fc_replay_state { + #define region_last(__region) (((__region)->lblk) + ((__region)->len) - 1) + #endif + +-#define fc_for_each_tl(__start, __end, __tl) \ +- for (tl = (struct ext4_fc_tl *)(__start); \ +- (__u8 *)tl < (__u8 *)(__end); \ +- tl = (struct ext4_fc_tl *)((__u8 *)tl + \ +- sizeof(struct ext4_fc_tl) + \ +- + le16_to_cpu(tl->fc_len))) +- + static inline const char *tag2str(__u16 tag) + { + switch (tag) { +@@ -186,16 +179,4 @@ static inline const char *tag2str(__u16 tag) + } + } + +-/* Get length of a particular tlv */ +-static inline int ext4_fc_tag_len(struct ext4_fc_tl *tl) +-{ +- return le16_to_cpu(tl->fc_len); +-} +- +-/* Get a pointer to "value" of a tlv */ +-static inline __u8 *ext4_fc_tag_val(struct ext4_fc_tl *tl) +-{ +- return (__u8 *)tl + sizeof(*tl); +-} +- + #endif /* __FAST_COMMIT_H__ */ +diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c +index 71d321b3b9844..edbaed073ac5c 100644 +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -322,14 +322,16 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) + if (is_directory) { + count = ext4_used_dirs_count(sb, gdp) - 1; + ext4_used_dirs_set(sb, gdp, count); +- percpu_counter_dec(&sbi->s_dirs_counter); ++ if (percpu_counter_initialized(&sbi->s_dirs_counter)) ++ percpu_counter_dec(&sbi->s_dirs_counter); + } + ext4_inode_bitmap_csum_set(sb, block_group, gdp, bitmap_bh, + EXT4_INODES_PER_GROUP(sb) / 8); + ext4_group_desc_csum_set(sb, block_group, gdp); + ext4_unlock_group(sb, block_group); + +- percpu_counter_inc(&sbi->s_freeinodes_counter); ++ if (percpu_counter_initialized(&sbi->s_freeinodes_counter)) ++ percpu_counter_inc(&sbi->s_freeinodes_counter); + if (sbi->s_log_groups_per_flex) { + struct flex_groups *fg; + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index a02fadf4fc84e..d24cb3dc79fff 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -2715,7 +2715,7 @@ static int ext4_mb_init_backend(struct super_block *sb) + */ + if (sbi->s_es->s_log_groups_per_flex >= 32) { + ext4_msg(sb, KERN_ERR, "too many log groups per flexible block group"); +- goto err_freesgi; ++ goto err_freebuddy; + } + sbi->s_mb_prefetch = min_t(uint, 1 << sbi->s_es->s_log_groups_per_flex, + BLK_MAX_SEGMENT_SIZE >> (sb->s_blocksize_bits - 9)); +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 77c1cb2582623..0e3a847b5d279 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -4449,14 +4449,20 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) + } + + if (sb->s_blocksize != blocksize) { ++ /* ++ * bh must be released before kill_bdev(), otherwise ++ * it won't be freed and its page also. kill_bdev() ++ * is called by sb_set_blocksize(). ++ */ ++ brelse(bh); + /* Validate the filesystem blocksize */ + if (!sb_set_blocksize(sb, blocksize)) { + ext4_msg(sb, KERN_ERR, "bad block size %d", + blocksize); ++ bh = NULL; + goto failed_mount; + } + +- brelse(bh); + logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; + offset = do_div(logical_sb_block, blocksize); + bh = ext4_sb_bread_unmovable(sb, logical_sb_block); +@@ -5176,8 +5182,9 @@ failed_mount: + kfree(get_qf_name(sb, sbi, i)); + #endif + fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy); +- ext4_blkdev_remove(sbi); ++ /* ext4_blkdev_remove() calls kill_bdev(), release bh before it. */ + brelse(bh); ++ ext4_blkdev_remove(sbi); + out_fail: + sb->s_fs_info = NULL; + kfree(sbi->s_blockgroup_lock); +diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c +index 9567520d79f79..7c2ba81213da0 100644 +--- a/fs/gfs2/glock.c ++++ b/fs/gfs2/glock.c +@@ -1465,9 +1465,11 @@ void gfs2_glock_dq(struct gfs2_holder *gh) + glock_blocked_by_withdraw(gl) && + gh->gh_gl != sdp->sd_jinode_gl) { + sdp->sd_glock_dqs_held++; ++ spin_unlock(&gl->gl_lockref.lock); + might_sleep(); + wait_on_bit(&sdp->sd_flags, SDF_WITHDRAW_RECOVERY, + TASK_UNINTERRUPTIBLE); ++ spin_lock(&gl->gl_lockref.lock); + } + if (gh->gh_flags & GL_NOCACHE) + handle_callback(gl, LM_ST_UNLOCKED, 0, false); +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 144056b0cac92..359d1abb089c4 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -653,7 +653,7 @@ struct io_unlink { + struct io_completion { + struct file *file; + struct list_head list; +- int cflags; ++ u32 cflags; + }; + + struct io_async_connect { +@@ -1476,7 +1476,33 @@ static bool io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force, + return ret; + } + +-static void __io_cqring_fill_event(struct io_kiocb *req, long res, long cflags) ++static inline bool req_ref_inc_not_zero(struct io_kiocb *req) ++{ ++ return refcount_inc_not_zero(&req->refs); ++} ++ ++static inline bool req_ref_sub_and_test(struct io_kiocb *req, int refs) ++{ ++ return refcount_sub_and_test(refs, &req->refs); ++} ++ ++static inline bool req_ref_put_and_test(struct io_kiocb *req) ++{ ++ return refcount_dec_and_test(&req->refs); ++} ++ ++static inline void req_ref_put(struct io_kiocb *req) ++{ ++ refcount_dec(&req->refs); ++} ++ ++static inline void req_ref_get(struct io_kiocb *req) ++{ ++ refcount_inc(&req->refs); ++} ++ ++static void __io_cqring_fill_event(struct io_kiocb *req, long res, ++ unsigned int cflags) + { + struct io_ring_ctx *ctx = req->ctx; + struct io_uring_cqe *cqe; +@@ -1511,7 +1537,7 @@ static void __io_cqring_fill_event(struct io_kiocb *req, long res, long cflags) + io_clean_op(req); + req->result = res; + req->compl.cflags = cflags; +- refcount_inc(&req->refs); ++ req_ref_get(req); + list_add_tail(&req->compl.list, &ctx->cq_overflow_list); + } + } +@@ -1533,7 +1559,7 @@ static void io_req_complete_post(struct io_kiocb *req, long res, + * If we're the last reference to this request, add to our locked + * free_list cache. + */ +- if (refcount_dec_and_test(&req->refs)) { ++ if (req_ref_put_and_test(req)) { + struct io_comp_state *cs = &ctx->submit_state.comp; + + if (req->flags & (REQ_F_LINK | REQ_F_HARDLINK)) { +@@ -2112,7 +2138,7 @@ static void io_submit_flush_completions(struct io_comp_state *cs, + req = cs->reqs[i]; + + /* submission and completion refs */ +- if (refcount_sub_and_test(2, &req->refs)) ++ if (req_ref_sub_and_test(req, 2)) + io_req_free_batch(&rb, req, &ctx->submit_state); + } + +@@ -2128,7 +2154,7 @@ static struct io_kiocb *io_put_req_find_next(struct io_kiocb *req) + { + struct io_kiocb *nxt = NULL; + +- if (refcount_dec_and_test(&req->refs)) { ++ if (req_ref_put_and_test(req)) { + nxt = io_req_find_next(req); + __io_free_req(req); + } +@@ -2137,7 +2163,7 @@ static struct io_kiocb *io_put_req_find_next(struct io_kiocb *req) + + static void io_put_req(struct io_kiocb *req) + { +- if (refcount_dec_and_test(&req->refs)) ++ if (req_ref_put_and_test(req)) + io_free_req(req); + } + +@@ -2160,14 +2186,14 @@ static void io_free_req_deferred(struct io_kiocb *req) + + static inline void io_put_req_deferred(struct io_kiocb *req, int refs) + { +- if (refcount_sub_and_test(refs, &req->refs)) ++ if (req_ref_sub_and_test(req, refs)) + io_free_req_deferred(req); + } + + static void io_double_put_req(struct io_kiocb *req) + { + /* drop both submit and complete references */ +- if (refcount_sub_and_test(2, &req->refs)) ++ if (req_ref_sub_and_test(req, 2)) + io_free_req(req); + } + +@@ -2253,7 +2279,7 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events, + __io_cqring_fill_event(req, req->result, cflags); + (*nr_events)++; + +- if (refcount_dec_and_test(&req->refs)) ++ if (req_ref_put_and_test(req)) + io_req_free_batch(&rb, req, &ctx->submit_state); + } + +@@ -2495,7 +2521,7 @@ static bool io_rw_reissue(struct io_kiocb *req) + lockdep_assert_held(&req->ctx->uring_lock); + + if (io_resubmit_prep(req)) { +- refcount_inc(&req->refs); ++ req_ref_get(req); + io_queue_async_work(req); + return true; + } +@@ -3208,7 +3234,7 @@ static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode, + list_del_init(&wait->entry); + + /* submit ref gets dropped, acquire a new one */ +- refcount_inc(&req->refs); ++ req_ref_get(req); + io_req_task_queue(req); + return 1; + } +@@ -4953,7 +4979,7 @@ static void io_poll_remove_double(struct io_kiocb *req) + spin_lock(&head->lock); + list_del_init(&poll->wait.entry); + if (poll->wait.private) +- refcount_dec(&req->refs); ++ req_ref_put(req); + poll->head = NULL; + spin_unlock(&head->lock); + } +@@ -5019,7 +5045,7 @@ static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode, + poll->wait.func(&poll->wait, mode, sync, key); + } + } +- refcount_dec(&req->refs); ++ req_ref_put(req); + return 1; + } + +@@ -5062,7 +5088,7 @@ static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, + return; + } + io_init_poll_iocb(poll, poll_one->events, io_poll_double_wake); +- refcount_inc(&req->refs); ++ req_ref_get(req); + poll->wait.private = req; + *poll_ptr = poll; + } +@@ -6211,7 +6237,7 @@ static void io_wq_submit_work(struct io_wq_work *work) + /* avoid locking problems by failing it from a clean context */ + if (ret) { + /* io-wq is going to take one down */ +- refcount_inc(&req->refs); ++ req_ref_get(req); + io_req_task_queue_fail(req, ret); + } + } +@@ -6263,15 +6289,17 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer) + * We don't expect the list to be empty, that will only happen if we + * race with the completion of the linked work. + */ +- if (prev && refcount_inc_not_zero(&prev->refs)) ++ if (prev) { + io_remove_next_linked(prev); +- else +- prev = NULL; ++ if (!req_ref_inc_not_zero(prev)) ++ prev = NULL; ++ } + spin_unlock_irqrestore(&ctx->completion_lock, flags); + + if (prev) { + io_async_find_and_cancel(ctx, req, prev->user_data, -ETIME); + io_put_req_deferred(prev, 1); ++ io_put_req_deferred(req, 1); + } else { + io_req_complete_post(req, -ETIME, 0); + io_put_req_deferred(req, 1); +diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c +index 5edc1d0cf115f..0e45893c0cda0 100644 +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -1857,6 +1857,45 @@ out: + return ret; + } + ++/* ++ * zero out partial blocks of one cluster. ++ * ++ * start: file offset where zero starts, will be made upper block aligned. ++ * len: it will be trimmed to the end of current cluster if "start + len" ++ * is bigger than it. ++ */ ++static int ocfs2_zeroout_partial_cluster(struct inode *inode, ++ u64 start, u64 len) ++{ ++ int ret; ++ u64 start_block, end_block, nr_blocks; ++ u64 p_block, offset; ++ u32 cluster, p_cluster, nr_clusters; ++ struct super_block *sb = inode->i_sb; ++ u64 end = ocfs2_align_bytes_to_clusters(sb, start); ++ ++ if (start + len < end) ++ end = start + len; ++ ++ start_block = ocfs2_blocks_for_bytes(sb, start); ++ end_block = ocfs2_blocks_for_bytes(sb, end); ++ nr_blocks = end_block - start_block; ++ if (!nr_blocks) ++ return 0; ++ ++ cluster = ocfs2_bytes_to_clusters(sb, start); ++ ret = ocfs2_get_clusters(inode, cluster, &p_cluster, ++ &nr_clusters, NULL); ++ if (ret) ++ return ret; ++ if (!p_cluster) ++ return 0; ++ ++ offset = start_block - ocfs2_clusters_to_blocks(sb, cluster); ++ p_block = ocfs2_clusters_to_blocks(sb, p_cluster) + offset; ++ return sb_issue_zeroout(sb, p_block, nr_blocks, GFP_NOFS); ++} ++ + /* + * Parts of this function taken from xfs_change_file_space() + */ +@@ -1867,7 +1906,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + { + int ret; + s64 llen; +- loff_t size; ++ loff_t size, orig_isize; + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); + struct buffer_head *di_bh = NULL; + handle_t *handle; +@@ -1898,6 +1937,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + goto out_inode_unlock; + } + ++ orig_isize = i_size_read(inode); + switch (sr->l_whence) { + case 0: /*SEEK_SET*/ + break; +@@ -1905,7 +1945,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + sr->l_start += f_pos; + break; + case 2: /*SEEK_END*/ +- sr->l_start += i_size_read(inode); ++ sr->l_start += orig_isize; + break; + default: + ret = -EINVAL; +@@ -1959,6 +1999,14 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + default: + ret = -EINVAL; + } ++ ++ /* zeroout eof blocks in the cluster. */ ++ if (!ret && change_size && orig_isize < size) { ++ ret = ocfs2_zeroout_partial_cluster(inode, orig_isize, ++ size - orig_isize); ++ if (!ret) ++ i_size_write(inode, size); ++ } + up_write(&OCFS2_I(inode)->ip_alloc_sem); + if (ret) { + mlog_errno(ret); +@@ -1975,9 +2023,6 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, + goto out_inode_unlock; + } + +- if (change_size && i_size_read(inode) < size) +- i_size_write(inode, size); +- + inode->i_ctime = inode->i_mtime = current_time(inode); + ret = ocfs2_mark_inode_dirty(handle, inode, di_bh); + if (ret < 0) +diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h +index 9c68b2da14c63..e5a4c68093fc2 100644 +--- a/include/linux/mlx5/mlx5_ifc.h ++++ b/include/linux/mlx5/mlx5_ifc.h +@@ -1260,6 +1260,8 @@ enum mlx5_fc_bulk_alloc_bitmask { + + #define MLX5_FC_BULK_NUM_FCS(fc_enum) (MLX5_FC_BULK_SIZE_FACTOR * (fc_enum)) + ++#define MLX5_FT_MAX_MULTIPATH_LEVEL 63 ++ + enum { + MLX5_STEERING_FORMAT_CONNECTX_5 = 0, + MLX5_STEERING_FORMAT_CONNECTX_6DX = 1, +diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h +index 5e772392a3795..136b1d996075c 100644 +--- a/include/linux/pgtable.h ++++ b/include/linux/pgtable.h +@@ -432,6 +432,14 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres + * To be differentiate with macro pte_mkyoung, this macro is used on platforms + * where software maintains page access bit. + */ ++#ifndef pte_sw_mkyoung ++static inline pte_t pte_sw_mkyoung(pte_t pte) ++{ ++ return pte; ++} ++#define pte_sw_mkyoung pte_sw_mkyoung ++#endif ++ + #ifndef pte_savedwrite + #define pte_savedwrite pte_write + #endif +diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h +index fafc1beea504a..9837fb011f2fb 100644 +--- a/include/linux/platform_data/ti-sysc.h ++++ b/include/linux/platform_data/ti-sysc.h +@@ -50,6 +50,7 @@ struct sysc_regbits { + s8 emufree_shift; + }; + ++#define SYSC_QUIRK_REINIT_ON_RESUME BIT(27) + #define SYSC_QUIRK_GPMC_DEBUG BIT(26) + #define SYSC_MODULE_QUIRK_ENA_RESETDONE BIT(25) + #define SYSC_MODULE_QUIRK_PRUSS BIT(24) +diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h +index 48ecca8530ffa..b655d8666f555 100644 +--- a/include/net/caif/caif_dev.h ++++ b/include/net/caif/caif_dev.h +@@ -119,7 +119,7 @@ void caif_free_client(struct cflayer *adap_layer); + * The link_support layer is used to add any Link Layer specific + * framing. + */ +-void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, ++int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + struct cflayer *link_support, int head_room, + struct cflayer **layer, int (**rcv_func)( + struct sk_buff *, struct net_device *, +diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h +index 2aa5e91d84576..8819ff4db35a6 100644 +--- a/include/net/caif/cfcnfg.h ++++ b/include/net/caif/cfcnfg.h +@@ -62,7 +62,7 @@ void cfcnfg_remove(struct cfcnfg *cfg); + * @fcs: Specify if checksum is used in CAIF Framing Layer. + * @head_room: Head space needed by link specific protocol. + */ +-void ++int + cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + struct net_device *dev, struct cflayer *phy_layer, + enum cfcnfg_phy_preference pref, +diff --git a/include/net/caif/cfserl.h b/include/net/caif/cfserl.h +index 14a55e03bb3ce..67cce8757175a 100644 +--- a/include/net/caif/cfserl.h ++++ b/include/net/caif/cfserl.h +@@ -9,4 +9,5 @@ + #include + + struct cflayer *cfserl_create(int instance, bool use_stx); ++void cfserl_release(struct cflayer *layer); + #endif +diff --git a/include/net/tls.h b/include/net/tls.h +index 3eccb525e8f79..8341a8d1e8073 100644 +--- a/include/net/tls.h ++++ b/include/net/tls.h +@@ -193,7 +193,11 @@ struct tls_offload_context_tx { + (sizeof(struct tls_offload_context_tx) + TLS_DRIVER_STATE_SIZE_TX) + + enum tls_context_flags { +- TLS_RX_SYNC_RUNNING = 0, ++ /* tls_device_down was called after the netdev went down, device state ++ * was released, and kTLS works in software, even though rx_conf is ++ * still TLS_HW (needed for transition). ++ */ ++ TLS_RX_DEV_DEGRADED = 0, + /* Unlike RX where resync is driven entirely by the core in TX only + * the driver knows when things went out of sync, so we need the flag + * to be atomic. +@@ -266,6 +270,7 @@ struct tls_context { + + /* cache cold stuff */ + struct proto *sk_proto; ++ struct sock *sk; + + void (*sk_destruct)(struct sock *sk); + +@@ -448,6 +453,9 @@ static inline u16 tls_user_config(struct tls_context *ctx, bool tx) + struct sk_buff * + tls_validate_xmit_skb(struct sock *sk, struct net_device *dev, + struct sk_buff *skb); ++struct sk_buff * ++tls_validate_xmit_skb_sw(struct sock *sk, struct net_device *dev, ++ struct sk_buff *skb); + + static inline bool tls_is_sk_tx_device_offloaded(struct sock *sk) + { +diff --git a/init/main.c b/init/main.c +index 53b278845b886..5bd1a25f1d6f5 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -1514,7 +1514,7 @@ static noinline void __init kernel_init_freeable(void) + */ + set_mems_allowed(node_states[N_MEMORY]); + +- cad_pid = task_pid(current); ++ cad_pid = get_pid(task_pid(current)); + + smp_prepare_cpus(setup_max_cpus); + +diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c +index 308427fe03a3a..6140e91e9c891 100644 +--- a/kernel/bpf/helpers.c ++++ b/kernel/bpf/helpers.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #include "../../lib/kstrtox.h" + +@@ -741,11 +742,13 @@ bpf_base_func_proto(enum bpf_func_id func_id) + case BPF_FUNC_probe_read_user: + return &bpf_probe_read_user_proto; + case BPF_FUNC_probe_read_kernel: +- return &bpf_probe_read_kernel_proto; ++ return security_locked_down(LOCKDOWN_BPF_READ) < 0 ? ++ NULL : &bpf_probe_read_kernel_proto; + case BPF_FUNC_probe_read_user_str: + return &bpf_probe_read_user_str_proto; + case BPF_FUNC_probe_read_kernel_str: +- return &bpf_probe_read_kernel_str_proto; ++ return security_locked_down(LOCKDOWN_BPF_READ) < 0 ? ++ NULL : &bpf_probe_read_kernel_str_proto; + case BPF_FUNC_snprintf_btf: + return &bpf_snprintf_btf_proto; + default: +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index b0c45d923f0f9..9bb3d2823f442 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -215,16 +215,11 @@ const struct bpf_func_proto bpf_probe_read_user_str_proto = { + static __always_inline int + bpf_probe_read_kernel_common(void *dst, u32 size, const void *unsafe_ptr) + { +- int ret = security_locked_down(LOCKDOWN_BPF_READ); ++ int ret; + +- if (unlikely(ret < 0)) +- goto fail; + ret = copy_from_kernel_nofault(dst, unsafe_ptr, size); + if (unlikely(ret < 0)) +- goto fail; +- return ret; +-fail: +- memset(dst, 0, size); ++ memset(dst, 0, size); + return ret; + } + +@@ -246,10 +241,7 @@ const struct bpf_func_proto bpf_probe_read_kernel_proto = { + static __always_inline int + bpf_probe_read_kernel_str_common(void *dst, u32 size, const void *unsafe_ptr) + { +- int ret = security_locked_down(LOCKDOWN_BPF_READ); +- +- if (unlikely(ret < 0)) +- goto fail; ++ int ret; + + /* + * The strncpy_from_kernel_nofault() call will likely not fill the +@@ -262,11 +254,7 @@ bpf_probe_read_kernel_str_common(void *dst, u32 size, const void *unsafe_ptr) + */ + ret = strncpy_from_kernel_nofault(dst, unsafe_ptr, size); + if (unlikely(ret < 0)) +- goto fail; +- +- return ret; +-fail: +- memset(dst, 0, size); ++ memset(dst, 0, size); + return ret; + } + +@@ -1322,16 +1310,20 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) + case BPF_FUNC_probe_read_user: + return &bpf_probe_read_user_proto; + case BPF_FUNC_probe_read_kernel: +- return &bpf_probe_read_kernel_proto; ++ return security_locked_down(LOCKDOWN_BPF_READ) < 0 ? ++ NULL : &bpf_probe_read_kernel_proto; + case BPF_FUNC_probe_read_user_str: + return &bpf_probe_read_user_str_proto; + case BPF_FUNC_probe_read_kernel_str: +- return &bpf_probe_read_kernel_str_proto; ++ return security_locked_down(LOCKDOWN_BPF_READ) < 0 ? ++ NULL : &bpf_probe_read_kernel_str_proto; + #ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + case BPF_FUNC_probe_read: +- return &bpf_probe_read_compat_proto; ++ return security_locked_down(LOCKDOWN_BPF_READ) < 0 ? ++ NULL : &bpf_probe_read_compat_proto; + case BPF_FUNC_probe_read_str: +- return &bpf_probe_read_compat_str_proto; ++ return security_locked_down(LOCKDOWN_BPF_READ) < 0 ? ++ NULL : &bpf_probe_read_compat_str_proto; + #endif + #ifdef CONFIG_CGROUPS + case BPF_FUNC_get_current_cgroup_id: +diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c +index a9bd6ce1ba02b..726fd2030f645 100644 +--- a/mm/debug_vm_pgtable.c ++++ b/mm/debug_vm_pgtable.c +@@ -192,7 +192,7 @@ static void __init pmd_advanced_tests(struct mm_struct *mm, + + pr_debug("Validating PMD advanced\n"); + /* Align the address wrt HPAGE_PMD_SIZE */ +- vaddr = (vaddr & HPAGE_PMD_MASK) + HPAGE_PMD_SIZE; ++ vaddr &= HPAGE_PMD_MASK; + + pgtable_trans_huge_deposit(mm, pmdp, pgtable); + +@@ -330,7 +330,7 @@ static void __init pud_advanced_tests(struct mm_struct *mm, + + pr_debug("Validating PUD advanced\n"); + /* Align the address wrt HPAGE_PUD_SIZE */ +- vaddr = (vaddr & HPAGE_PUD_MASK) + HPAGE_PUD_SIZE; ++ vaddr &= HPAGE_PUD_MASK; + + set_pud_at(mm, vaddr, pudp, pud); + pudp_set_wrprotect(mm, vaddr, pudp); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 96b722af092e7..ce63ec0187c55 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -4705,10 +4705,20 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm, + struct page *page; + + if (!*pagep) { +- ret = -ENOMEM; ++ /* If a page already exists, then it's UFFDIO_COPY for ++ * a non-missing case. Return -EEXIST. ++ */ ++ if (vm_shared && ++ hugetlbfs_pagecache_present(h, dst_vma, dst_addr)) { ++ ret = -EEXIST; ++ goto out; ++ } ++ + page = alloc_huge_page(dst_vma, dst_addr, 0); +- if (IS_ERR(page)) ++ if (IS_ERR(page)) { ++ ret = -ENOMEM; + goto out; ++ } + + ret = copy_huge_page_from_user(page, + (const void __user *) src_addr, +diff --git a/mm/kfence/core.c b/mm/kfence/core.c +index f0be2c5038b5d..6f29981e317fe 100644 +--- a/mm/kfence/core.c ++++ b/mm/kfence/core.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -620,7 +621,16 @@ static void toggle_allocation_gate(struct work_struct *work) + /* Enable static key, and await allocation to happen. */ + static_branch_enable(&kfence_allocation_key); + +- wait_event_timeout(allocation_wait, atomic_read(&kfence_allocation_gate), HZ); ++ if (sysctl_hung_task_timeout_secs) { ++ /* ++ * During low activity with no allocations we might wait a ++ * while; let's avoid the hung task warning. ++ */ ++ wait_event_idle_timeout(allocation_wait, atomic_read(&kfence_allocation_gate), ++ sysctl_hung_task_timeout_secs * HZ / 2); ++ } else { ++ wait_event_idle(allocation_wait, atomic_read(&kfence_allocation_gate)); ++ } + + /* Disable static key and reset timer. */ + static_branch_disable(&kfence_allocation_key); +diff --git a/mm/memory.c b/mm/memory.c +index 550405fc3b5e6..14a6c66b37483 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -2896,6 +2896,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) + } + flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte)); + entry = mk_pte(new_page, vma->vm_page_prot); ++ entry = pte_sw_mkyoung(entry); + entry = maybe_mkwrite(pte_mkdirty(entry), vma); + + /* +@@ -3561,6 +3562,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf) + __SetPageUptodate(page); + + entry = mk_pte(page, vma->vm_page_prot); ++ entry = pte_sw_mkyoung(entry); + if (vma->vm_flags & VM_WRITE) + entry = pte_mkwrite(pte_mkdirty(entry)); + +@@ -3745,6 +3747,8 @@ void do_set_pte(struct vm_fault *vmf, struct page *page, unsigned long addr) + + if (prefault && arch_wants_old_prefaulted_pte()) + entry = pte_mkold(entry); ++ else ++ entry = pte_sw_mkyoung(entry); + + if (write) + entry = maybe_mkwrite(pte_mkdirty(entry), vma); +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 4bb3cdfc47f87..d9dbf45f7590e 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -8951,6 +8951,8 @@ bool take_page_off_buddy(struct page *page) + del_page_from_free_list(page_head, zone, page_order); + break_down_buddy_pages(zone, page_head, page, 0, + page_order, migratetype); ++ if (!is_migrate_isolate(migratetype)) ++ __mod_zone_freepage_state(zone, -1, migratetype); + ret = true; + break; + } +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index b0d9c36acc033..4fad2ca661ed9 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -1608,8 +1608,13 @@ setup_failed: + } else { + /* Init failed, cleanup */ + flush_work(&hdev->tx_work); +- flush_work(&hdev->cmd_work); ++ ++ /* Since hci_rx_work() is possible to awake new cmd_work ++ * it should be flushed first to avoid unexpected call of ++ * hci_cmd_work() ++ */ + flush_work(&hdev->rx_work); ++ flush_work(&hdev->cmd_work); + + skb_queue_purge(&hdev->cmd_q); + skb_queue_purge(&hdev->rx_q); +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index 251b9128f530a..eed0dd066e12c 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -762,7 +762,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) + /* Detach sockets from device */ + read_lock(&hci_sk_list.lock); + sk_for_each(sk, &hci_sk_list.head) { +- bh_lock_sock_nested(sk); ++ lock_sock(sk); + if (hci_pi(sk)->hdev == hdev) { + hci_pi(sk)->hdev = NULL; + sk->sk_err = EPIPE; +@@ -771,7 +771,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) + + hci_dev_put(hdev); + } +- bh_unlock_sock(sk); ++ release_sock(sk); + } + read_unlock(&hci_sk_list.lock); + } +diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c +index c10e5a55758d2..440139706130a 100644 +--- a/net/caif/caif_dev.c ++++ b/net/caif/caif_dev.c +@@ -308,7 +308,7 @@ static void dev_flowctrl(struct net_device *dev, int on) + caifd_put(caifd); + } + +-void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, ++int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + struct cflayer *link_support, int head_room, + struct cflayer **layer, + int (**rcv_func)(struct sk_buff *, struct net_device *, +@@ -319,11 +319,12 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + enum cfcnfg_phy_preference pref; + struct cfcnfg *cfg = get_cfcnfg(dev_net(dev)); + struct caif_device_entry_list *caifdevs; ++ int res; + + caifdevs = caif_device_list(dev_net(dev)); + caifd = caif_device_alloc(dev); + if (!caifd) +- return; ++ return -ENOMEM; + *layer = &caifd->layer; + spin_lock_init(&caifd->flow_lock); + +@@ -344,7 +345,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + strlcpy(caifd->layer.name, dev->name, + sizeof(caifd->layer.name)); + caifd->layer.transmit = transmit; +- cfcnfg_add_phy_layer(cfg, ++ res = cfcnfg_add_phy_layer(cfg, + dev, + &caifd->layer, + pref, +@@ -354,6 +355,7 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, + mutex_unlock(&caifdevs->lock); + if (rcv_func) + *rcv_func = receive; ++ return res; + } + EXPORT_SYMBOL(caif_enroll_dev); + +@@ -368,6 +370,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, + struct cflayer *layer, *link_support; + int head_room = 0; + struct caif_device_entry_list *caifdevs; ++ int res; + + cfg = get_cfcnfg(dev_net(dev)); + caifdevs = caif_device_list(dev_net(dev)); +@@ -393,8 +396,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, + break; + } + } +- caif_enroll_dev(dev, caifdev, link_support, head_room, ++ res = caif_enroll_dev(dev, caifdev, link_support, head_room, + &layer, NULL); ++ if (res) ++ cfserl_release(link_support); + caifdev->flowctrl = dev_flowctrl; + break; + +diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c +index a0116b9503d9d..b02e1292f7f19 100644 +--- a/net/caif/caif_usb.c ++++ b/net/caif/caif_usb.c +@@ -115,6 +115,11 @@ static struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN], + return (struct cflayer *) this; + } + ++static void cfusbl_release(struct cflayer *layer) ++{ ++ kfree(layer); ++} ++ + static struct packet_type caif_usb_type __read_mostly = { + .type = cpu_to_be16(ETH_P_802_EX1), + }; +@@ -127,6 +132,7 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, + struct cflayer *layer, *link_support; + struct usbnet *usbnet; + struct usb_device *usbdev; ++ int res; + + /* Check whether we have a NCM device, and find its VID/PID. */ + if (!(dev->dev.parent && dev->dev.parent->driver && +@@ -169,8 +175,11 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, + if (dev->num_tx_queues > 1) + pr_warn("USB device uses more than one tx queue\n"); + +- caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN, ++ res = caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN, + &layer, &caif_usb_type.func); ++ if (res) ++ goto err; ++ + if (!pack_added) + dev_add_pack(&caif_usb_type); + pack_added = true; +@@ -178,6 +187,9 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, + strlcpy(layer->name, dev->name, sizeof(layer->name)); + + return 0; ++err: ++ cfusbl_release(link_support); ++ return res; + } + + static struct notifier_block caif_device_notifier = { +diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c +index 399239a14420f..cac30e676ac94 100644 +--- a/net/caif/cfcnfg.c ++++ b/net/caif/cfcnfg.c +@@ -450,7 +450,7 @@ unlock: + rcu_read_unlock(); + } + +-void ++int + cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + struct net_device *dev, struct cflayer *phy_layer, + enum cfcnfg_phy_preference pref, +@@ -459,7 +459,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + { + struct cflayer *frml; + struct cfcnfg_phyinfo *phyinfo = NULL; +- int i; ++ int i, res = 0; + u8 phyid; + + mutex_lock(&cnfg->lock); +@@ -473,12 +473,15 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, + goto got_phyid; + } + pr_warn("Too many CAIF Link Layers (max 6)\n"); ++ res = -EEXIST; + goto out; + + got_phyid: + phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC); +- if (!phyinfo) ++ if (!phyinfo) { ++ res = -ENOMEM; + goto out_err; ++ } + + phy_layer->id = phyid; + phyinfo->pref = pref; +@@ -492,8 +495,10 @@ got_phyid: + + frml = cffrml_create(phyid, fcs); + +- if (!frml) ++ if (!frml) { ++ res = -ENOMEM; + goto out_err; ++ } + phyinfo->frm_layer = frml; + layer_set_up(frml, cnfg->mux); + +@@ -511,11 +516,12 @@ got_phyid: + list_add_rcu(&phyinfo->node, &cnfg->phys); + out: + mutex_unlock(&cnfg->lock); +- return; ++ return res; + + out_err: + kfree(phyinfo); + mutex_unlock(&cnfg->lock); ++ return res; + } + EXPORT_SYMBOL(cfcnfg_add_phy_layer); + +diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c +index e11725a4bb0ed..40cd57ad0a0f4 100644 +--- a/net/caif/cfserl.c ++++ b/net/caif/cfserl.c +@@ -31,6 +31,11 @@ static int cfserl_transmit(struct cflayer *layr, struct cfpkt *pkt); + static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, + int phyid); + ++void cfserl_release(struct cflayer *layer) ++{ ++ kfree(layer); ++} ++ + struct cflayer *cfserl_create(int instance, bool use_stx) + { + struct cfserl *this = kzalloc(sizeof(struct cfserl), GFP_ATOMIC); +diff --git a/net/core/devlink.c b/net/core/devlink.c +index 737b61c2976e1..4c363fa7d4d11 100644 +--- a/net/core/devlink.c ++++ b/net/core/devlink.c +@@ -705,7 +705,6 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg, + case DEVLINK_PORT_FLAVOUR_PHYSICAL: + case DEVLINK_PORT_FLAVOUR_CPU: + case DEVLINK_PORT_FLAVOUR_DSA: +- case DEVLINK_PORT_FLAVOUR_VIRTUAL: + if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, + attrs->phys.port_number)) + return -EMSGSIZE; +@@ -8629,7 +8628,6 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, + + switch (attrs->flavour) { + case DEVLINK_PORT_FLAVOUR_PHYSICAL: +- case DEVLINK_PORT_FLAVOUR_VIRTUAL: + if (!attrs->split) + n = snprintf(name, len, "p%u", attrs->phys.port_number); + else +@@ -8670,6 +8668,8 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port, + n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf, + attrs->pci_sf.sf); + break; ++ case DEVLINK_PORT_FLAVOUR_VIRTUAL: ++ return -EOPNOTSUPP; + } + + if (n >= len) +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 98f20efbfadf2..bf774575ad716 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -238,6 +238,7 @@ static int neigh_forced_gc(struct neigh_table *tbl) + + write_lock(&n->lock); + if ((n->nud_state == NUD_FAILED) || ++ (n->nud_state == NUD_NOARP) || + (tbl->is_multicast && + tbl->is_multicast(n->primary_key)) || + time_after(tref, n->updated)) +diff --git a/net/core/sock.c b/net/core/sock.c +index 9c7b143e7a964..a266760cd65ea 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -815,10 +815,18 @@ void sock_set_rcvbuf(struct sock *sk, int val) + } + EXPORT_SYMBOL(sock_set_rcvbuf); + ++static void __sock_set_mark(struct sock *sk, u32 val) ++{ ++ if (val != sk->sk_mark) { ++ sk->sk_mark = val; ++ sk_dst_reset(sk); ++ } ++} ++ + void sock_set_mark(struct sock *sk, u32 val) + { + lock_sock(sk); +- sk->sk_mark = val; ++ __sock_set_mark(sk, val); + release_sock(sk); + } + EXPORT_SYMBOL(sock_set_mark); +@@ -1126,10 +1134,10 @@ set_sndbuf: + case SO_MARK: + if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { + ret = -EPERM; +- } else if (val != sk->sk_mark) { +- sk->sk_mark = val; +- sk_dst_reset(sk); ++ break; + } ++ ++ __sock_set_mark(sk, val); + break; + + case SO_RXQ_OVFL: +diff --git a/net/dsa/tag_8021q.c b/net/dsa/tag_8021q.c +index 008c1ec6e20c1..122ad5833fb1c 100644 +--- a/net/dsa/tag_8021q.c ++++ b/net/dsa/tag_8021q.c +@@ -64,7 +64,7 @@ + #define DSA_8021Q_SUBVLAN_HI_SHIFT 9 + #define DSA_8021Q_SUBVLAN_HI_MASK GENMASK(9, 9) + #define DSA_8021Q_SUBVLAN_LO_SHIFT 4 +-#define DSA_8021Q_SUBVLAN_LO_MASK GENMASK(4, 3) ++#define DSA_8021Q_SUBVLAN_LO_MASK GENMASK(5, 4) + #define DSA_8021Q_SUBVLAN_HI(x) (((x) & GENMASK(2, 2)) >> 2) + #define DSA_8021Q_SUBVLAN_LO(x) ((x) & GENMASK(1, 0)) + #define DSA_8021Q_SUBVLAN(x) \ +diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c +index 0c1b0770c59ea..c23c152860b73 100644 +--- a/net/ieee802154/nl-mac.c ++++ b/net/ieee802154/nl-mac.c +@@ -680,8 +680,10 @@ int ieee802154_llsec_getparams(struct sk_buff *skb, struct genl_info *info) + nla_put_u8(msg, IEEE802154_ATTR_LLSEC_SECLEVEL, params.out_level) || + nla_put_u32(msg, IEEE802154_ATTR_LLSEC_FRAME_COUNTER, + be32_to_cpu(params.frame_counter)) || +- ieee802154_llsec_fill_key_id(msg, ¶ms.out_key)) ++ ieee802154_llsec_fill_key_id(msg, ¶ms.out_key)) { ++ rc = -ENOBUFS; + goto out_free; ++ } + + dev_put(dev); + +diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c +index 2cdc7e63fe172..88215b5c93aa4 100644 +--- a/net/ieee802154/nl-phy.c ++++ b/net/ieee802154/nl-phy.c +@@ -241,8 +241,10 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) + } + + if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || +- nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) ++ nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) { ++ rc = -EMSGSIZE; + goto nla_put_failure; ++ } + dev_put(dev); + + wpan_phy_put(phy); +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 373d48073106f..36e80b3598b01 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3676,11 +3676,11 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg, + if (nh) { + if (rt->fib6_src.plen) { + NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing"); +- goto out; ++ goto out_free; + } + if (!nexthop_get(nh)) { + NL_SET_ERR_MSG(extack, "Nexthop has been deleted"); +- goto out; ++ goto out_free; + } + rt->nh = nh; + fib6_nh = nexthop_fib6_nh(rt->nh); +@@ -3717,6 +3717,10 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg, + out: + fib6_info_release(rt); + return ERR_PTR(err); ++out_free: ++ ip_fib_metrics_put(rt->fib6_metrics); ++ kfree(rt); ++ return ERR_PTR(err); + } + + int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, +diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c +index 228dd40828c4b..225b988215171 100644 +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -937,6 +937,10 @@ static void __mptcp_update_wmem(struct sock *sk) + { + struct mptcp_sock *msk = mptcp_sk(sk); + ++#ifdef CONFIG_LOCKDEP ++ WARN_ON_ONCE(!lockdep_is_held(&sk->sk_lock.slock)); ++#endif ++ + if (!msk->wmem_reserved) + return; + +@@ -1075,10 +1079,20 @@ out: + + static void __mptcp_clean_una_wakeup(struct sock *sk) + { ++#ifdef CONFIG_LOCKDEP ++ WARN_ON_ONCE(!lockdep_is_held(&sk->sk_lock.slock)); ++#endif + __mptcp_clean_una(sk); + mptcp_write_space(sk); + } + ++static void mptcp_clean_una_wakeup(struct sock *sk) ++{ ++ mptcp_data_lock(sk); ++ __mptcp_clean_una_wakeup(sk); ++ mptcp_data_unlock(sk); ++} ++ + static void mptcp_enter_memory_pressure(struct sock *sk) + { + struct mptcp_subflow_context *subflow; +@@ -2288,7 +2302,7 @@ static void __mptcp_retrans(struct sock *sk) + struct sock *ssk; + int ret; + +- __mptcp_clean_una_wakeup(sk); ++ mptcp_clean_una_wakeup(sk); + dfrag = mptcp_rtx_head(sk); + if (!dfrag) { + if (mptcp_data_fin_enabled(msk)) { +diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c +index 1936db3574d2e..8425cd393bf3e 100644 +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -608,21 +608,20 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, + + /* if the sk is MP_CAPABLE, we try to fetch the client key */ + if (subflow_req->mp_capable) { +- if (TCP_SKB_CB(skb)->seq != subflow_req->ssn_offset + 1) { +- /* here we can receive and accept an in-window, +- * out-of-order pkt, which will not carry the MP_CAPABLE +- * opt even on mptcp enabled paths +- */ +- goto create_msk; +- } +- ++ /* we can receive and accept an in-window, out-of-order pkt, ++ * which may not carry the MP_CAPABLE opt even on mptcp enabled ++ * paths: always try to extract the peer key, and fallback ++ * for packets missing it. ++ * Even OoO DSS packets coming legitly after dropped or ++ * reordered MPC will cause fallback, but we don't have other ++ * options. ++ */ + mptcp_get_options(skb, &mp_opt); + if (!mp_opt.mp_capable) { + fallback = true; + goto create_child; + } + +-create_msk: + new_msk = mptcp_sk_clone(listener->conn, &mp_opt, req); + if (!new_msk) + fallback = true; +@@ -985,22 +984,11 @@ static bool subflow_check_data_avail(struct sock *ssk) + u64 old_ack; + + status = get_mapping_status(ssk, msk); +- pr_debug("msk=%p ssk=%p status=%d", msk, ssk, status); +- if (status == MAPPING_INVALID) { +- ssk->sk_err = EBADMSG; +- goto fatal; +- } +- if (status == MAPPING_DUMMY) { +- __mptcp_do_fallback(msk); +- skb = skb_peek(&ssk->sk_receive_queue); +- subflow->map_valid = 1; +- subflow->map_seq = READ_ONCE(msk->ack_seq); +- subflow->map_data_len = skb->len; +- subflow->map_subflow_seq = tcp_sk(ssk)->copied_seq - +- subflow->ssn_offset; +- subflow->data_avail = MPTCP_SUBFLOW_DATA_AVAIL; +- return true; +- } ++ if (unlikely(status == MAPPING_INVALID)) ++ goto fallback; ++ ++ if (unlikely(status == MAPPING_DUMMY)) ++ goto fallback; + + if (status != MAPPING_OK) + goto no_data; +@@ -1013,10 +1001,8 @@ static bool subflow_check_data_avail(struct sock *ssk) + * MP_CAPABLE-based mapping + */ + if (unlikely(!READ_ONCE(msk->can_ack))) { +- if (!subflow->mpc_map) { +- ssk->sk_err = EBADMSG; +- goto fatal; +- } ++ if (!subflow->mpc_map) ++ goto fallback; + WRITE_ONCE(msk->remote_key, subflow->remote_key); + WRITE_ONCE(msk->ack_seq, subflow->map_seq); + WRITE_ONCE(msk->can_ack, true); +@@ -1044,15 +1030,29 @@ static bool subflow_check_data_avail(struct sock *ssk) + no_data: + subflow_sched_work_if_closed(msk, ssk); + return false; +-fatal: +- /* fatal protocol error, close the socket */ +- /* This barrier is coupled with smp_rmb() in tcp_poll() */ +- smp_wmb(); +- ssk->sk_error_report(ssk); +- tcp_set_state(ssk, TCP_CLOSE); +- tcp_send_active_reset(ssk, GFP_ATOMIC); +- subflow->data_avail = 0; +- return false; ++ ++fallback: ++ /* RFC 8684 section 3.7. */ ++ if (subflow->mp_join || subflow->fully_established) { ++ /* fatal protocol error, close the socket. ++ * subflow_error_report() will introduce the appropriate barriers ++ */ ++ ssk->sk_err = EBADMSG; ++ ssk->sk_error_report(ssk); ++ tcp_set_state(ssk, TCP_CLOSE); ++ tcp_send_active_reset(ssk, GFP_ATOMIC); ++ subflow->data_avail = 0; ++ return false; ++ } ++ ++ __mptcp_do_fallback(msk); ++ skb = skb_peek(&ssk->sk_receive_queue); ++ subflow->map_valid = 1; ++ subflow->map_seq = READ_ONCE(msk->ack_seq); ++ subflow->map_data_len = skb->len; ++ subflow->map_subflow_seq = tcp_sk(ssk)->copied_seq - subflow->ssn_offset; ++ subflow->data_avail = MPTCP_SUBFLOW_DATA_AVAIL; ++ return true; + } + + bool mptcp_subflow_data_available(struct sock *sk) +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index d45dbcba8b49c..c25097092a060 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -1367,7 +1367,7 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, + ip_vs_addr_copy(svc->af, &svc->addr, &u->addr); + svc->port = u->port; + svc->fwmark = u->fwmark; +- svc->flags = u->flags; ++ svc->flags = u->flags & ~IP_VS_SVC_F_HASHED; + svc->timeout = u->timeout * HZ; + svc->netmask = u->netmask; + svc->ipvs = ipvs; +diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c +index 47e9319d2cf31..71892822bbf5d 100644 +--- a/net/netfilter/nf_conntrack_proto.c ++++ b/net/netfilter/nf_conntrack_proto.c +@@ -660,7 +660,7 @@ int nf_conntrack_proto_init(void) + + #if IS_ENABLED(CONFIG_IPV6) + cleanup_sockopt: +- nf_unregister_sockopt(&so_getorigdst6); ++ nf_unregister_sockopt(&so_getorigdst); + #endif + return ret; + } +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 878ed49d0c569..31016c144c48b 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -3288,8 +3288,10 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, + if (n == NFT_RULE_MAXEXPRS) + goto err1; + err = nf_tables_expr_parse(&ctx, tmp, &info[n]); +- if (err < 0) ++ if (err < 0) { ++ NL_SET_BAD_ATTR(extack, tmp); + goto err1; ++ } + size += info[n].ops->size; + n++; + } +diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c +index 0f94fce1d3ed3..04a12a264cf74 100644 +--- a/net/netfilter/nfnetlink_cthelper.c ++++ b/net/netfilter/nfnetlink_cthelper.c +@@ -380,10 +380,14 @@ static int + nfnl_cthelper_update(const struct nlattr * const tb[], + struct nf_conntrack_helper *helper) + { ++ u32 size; + int ret; + +- if (tb[NFCTH_PRIV_DATA_LEN]) +- return -EBUSY; ++ if (tb[NFCTH_PRIV_DATA_LEN]) { ++ size = ntohl(nla_get_be32(tb[NFCTH_PRIV_DATA_LEN])); ++ if (size != helper->data_len) ++ return -EBUSY; ++ } + + if (tb[NFCTH_POLICY]) { + ret = nfnl_cthelper_update_policy(helper, tb[NFCTH_POLICY]); +diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c +index 882fe8648653d..6d2b382f5e075 100644 +--- a/net/netfilter/nft_ct.c ++++ b/net/netfilter/nft_ct.c +@@ -1216,7 +1216,7 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj, + struct nf_conn *ct; + + ct = nf_ct_get(pkt->skb, &ctinfo); +- if (!ct || ctinfo == IP_CT_UNTRACKED) { ++ if (!ct || nf_ct_is_confirmed(ct) || nf_ct_is_template(ct)) { + regs->verdict.code = NFT_BREAK; + return; + } +diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c +index 53dbe733f9981..6cfd30fc07985 100644 +--- a/net/nfc/llcp_sock.c ++++ b/net/nfc/llcp_sock.c +@@ -110,6 +110,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) + if (!llcp_sock->service_name) { + nfc_llcp_local_put(llcp_sock->local); + llcp_sock->local = NULL; ++ llcp_sock->dev = NULL; + ret = -ENOMEM; + goto put_dev; + } +@@ -119,6 +120,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) + llcp_sock->local = NULL; + kfree(llcp_sock->service_name); + llcp_sock->service_name = NULL; ++ llcp_sock->dev = NULL; + ret = -EADDRINUSE; + goto put_dev; + } +diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c +index 48fdf7293deaa..ba7f57cb41c30 100644 +--- a/net/sched/act_ct.c ++++ b/net/sched/act_ct.c +@@ -984,7 +984,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, + */ + cached = tcf_ct_skb_nfct_cached(net, skb, p->zone, force); + if (!cached) { +- if (!commit && tcf_ct_flow_table_lookup(p, skb, family)) { ++ if (tcf_ct_flow_table_lookup(p, skb, family)) { + skip_add = true; + goto do_nat; + } +@@ -1024,10 +1024,11 @@ do_nat: + * even if the connection is already confirmed. + */ + nf_conntrack_confirm(skb); +- } else if (!skip_add) { +- tcf_ct_flow_table_process_conn(p->ct_ft, ct, ctinfo); + } + ++ if (!skip_add) ++ tcf_ct_flow_table_process_conn(p->ct_ft, ct, ctinfo); ++ + out_push: + skb_push_rcsum(skb, nh_ofs); + +@@ -1204,9 +1205,6 @@ static int tcf_ct_fill_params(struct net *net, + sizeof(p->zone)); + } + +- if (p->zone == NF_CT_DEFAULT_ZONE_ID) +- return 0; +- + nf_ct_zone_init(&zone, p->zone, NF_CT_DEFAULT_ZONE_DIR, 0); + tmpl = nf_ct_tmpl_alloc(net, &zone, GFP_KERNEL); + if (!tmpl) { +diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c +index 081c11d5717c4..8827987ba9034 100644 +--- a/net/sched/sch_htb.c ++++ b/net/sched/sch_htb.c +@@ -1488,7 +1488,8 @@ static void htb_parent_to_leaf_offload(struct Qdisc *sch, + struct Qdisc *old_q; + + /* One ref for cl->leaf.q, the other for dev_queue->qdisc. */ +- qdisc_refcount_inc(new_q); ++ if (new_q) ++ qdisc_refcount_inc(new_q); + old_q = htb_graft_helper(dev_queue, new_q); + WARN_ON(!(old_q->flags & TCQ_F_BUILTIN)); + } +@@ -1675,10 +1676,9 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg, + cl->parent->common.classid, + NULL); + if (q->offload) { +- if (new_q) { ++ if (new_q) + htb_set_lockdep_class_child(new_q); +- htb_parent_to_leaf_offload(sch, dev_queue, new_q); +- } ++ htb_parent_to_leaf_offload(sch, dev_queue, new_q); + } + } + +diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c +index a4389ef08a980..0c8882052ba08 100644 +--- a/net/tipc/bearer.c ++++ b/net/tipc/bearer.c +@@ -243,7 +243,8 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest) + */ + static int tipc_enable_bearer(struct net *net, const char *name, + u32 disc_domain, u32 prio, +- struct nlattr *attr[]) ++ struct nlattr *attr[], ++ struct netlink_ext_ack *extack) + { + struct tipc_net *tn = tipc_net(net); + struct tipc_bearer_names b_names; +@@ -254,20 +255,24 @@ static int tipc_enable_bearer(struct net *net, const char *name, + int bearer_id = 0; + int res = -EINVAL; + char *errstr = ""; ++ u32 i; + + if (!bearer_name_validate(name, &b_names)) { + errstr = "illegal name"; ++ NL_SET_ERR_MSG(extack, "Illegal name"); + goto rejected; + } + + if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) { + errstr = "illegal priority"; ++ NL_SET_ERR_MSG(extack, "Illegal priority"); + goto rejected; + } + + m = tipc_media_find(b_names.media_name); + if (!m) { + errstr = "media not registered"; ++ NL_SET_ERR_MSG(extack, "Media not registered"); + goto rejected; + } + +@@ -275,33 +280,43 @@ static int tipc_enable_bearer(struct net *net, const char *name, + prio = m->priority; + + /* Check new bearer vs existing ones and find free bearer id if any */ +- while (bearer_id < MAX_BEARERS) { +- b = rtnl_dereference(tn->bearer_list[bearer_id]); +- if (!b) +- break; ++ bearer_id = MAX_BEARERS; ++ i = MAX_BEARERS; ++ while (i-- != 0) { ++ b = rtnl_dereference(tn->bearer_list[i]); ++ if (!b) { ++ bearer_id = i; ++ continue; ++ } + if (!strcmp(name, b->name)) { + errstr = "already enabled"; ++ NL_SET_ERR_MSG(extack, "Already enabled"); + goto rejected; + } +- bearer_id++; +- if (b->priority != prio) +- continue; +- if (++with_this_prio <= 2) +- continue; +- pr_warn("Bearer <%s>: already 2 bearers with priority %u\n", +- name, prio); +- if (prio == TIPC_MIN_LINK_PRI) { +- errstr = "cannot adjust to lower"; +- goto rejected; ++ ++ if (b->priority == prio && ++ (++with_this_prio > 2)) { ++ pr_warn("Bearer <%s>: already 2 bearers with priority %u\n", ++ name, prio); ++ ++ if (prio == TIPC_MIN_LINK_PRI) { ++ errstr = "cannot adjust to lower"; ++ NL_SET_ERR_MSG(extack, "Cannot adjust to lower"); ++ goto rejected; ++ } ++ ++ pr_warn("Bearer <%s>: trying with adjusted priority\n", ++ name); ++ prio--; ++ bearer_id = MAX_BEARERS; ++ i = MAX_BEARERS; ++ with_this_prio = 1; + } +- pr_warn("Bearer <%s>: trying with adjusted priority\n", name); +- prio--; +- bearer_id = 0; +- with_this_prio = 1; + } + + if (bearer_id >= MAX_BEARERS) { + errstr = "max 3 bearers permitted"; ++ NL_SET_ERR_MSG(extack, "Max 3 bearers permitted"); + goto rejected; + } + +@@ -315,6 +330,7 @@ static int tipc_enable_bearer(struct net *net, const char *name, + if (res) { + kfree(b); + errstr = "failed to enable media"; ++ NL_SET_ERR_MSG(extack, "Failed to enable media"); + goto rejected; + } + +@@ -331,6 +347,7 @@ static int tipc_enable_bearer(struct net *net, const char *name, + if (res) { + bearer_disable(net, b); + errstr = "failed to create discoverer"; ++ NL_SET_ERR_MSG(extack, "Failed to create discoverer"); + goto rejected; + } + +@@ -909,6 +926,7 @@ int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info) + bearer = tipc_bearer_find(net, name); + if (!bearer) { + err = -EINVAL; ++ NL_SET_ERR_MSG(info->extack, "Bearer not found"); + goto err_out; + } + +@@ -948,8 +966,10 @@ int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info) + name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); + + bearer = tipc_bearer_find(net, name); +- if (!bearer) ++ if (!bearer) { ++ NL_SET_ERR_MSG(info->extack, "Bearer not found"); + return -EINVAL; ++ } + + bearer_disable(net, bearer); + +@@ -1007,7 +1027,8 @@ int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) + prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); + } + +- return tipc_enable_bearer(net, bearer, domain, prio, attrs); ++ return tipc_enable_bearer(net, bearer, domain, prio, attrs, ++ info->extack); + } + + int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info) +@@ -1046,6 +1067,7 @@ int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info) + b = tipc_bearer_find(net, name); + if (!b) { + rtnl_unlock(); ++ NL_SET_ERR_MSG(info->extack, "Bearer not found"); + return -EINVAL; + } + +@@ -1086,8 +1108,10 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) + name = nla_data(attrs[TIPC_NLA_BEARER_NAME]); + + b = tipc_bearer_find(net, name); +- if (!b) ++ if (!b) { ++ NL_SET_ERR_MSG(info->extack, "Bearer not found"); + return -EINVAL; ++ } + + if (attrs[TIPC_NLA_BEARER_PROP]) { + struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; +@@ -1106,12 +1130,18 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) + if (props[TIPC_NLA_PROP_WIN]) + b->max_win = nla_get_u32(props[TIPC_NLA_PROP_WIN]); + if (props[TIPC_NLA_PROP_MTU]) { +- if (b->media->type_id != TIPC_MEDIA_TYPE_UDP) ++ if (b->media->type_id != TIPC_MEDIA_TYPE_UDP) { ++ NL_SET_ERR_MSG(info->extack, ++ "MTU property is unsupported"); + return -EINVAL; ++ } + #ifdef CONFIG_TIPC_MEDIA_UDP + if (tipc_udp_mtu_bad(nla_get_u32 +- (props[TIPC_NLA_PROP_MTU]))) ++ (props[TIPC_NLA_PROP_MTU]))) { ++ NL_SET_ERR_MSG(info->extack, ++ "MTU value is out-of-range"); + return -EINVAL; ++ } + b->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]); + tipc_node_apply_property(net, b, TIPC_NLA_PROP_MTU); + #endif +@@ -1239,6 +1269,7 @@ int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info) + rtnl_lock(); + media = tipc_media_find(name); + if (!media) { ++ NL_SET_ERR_MSG(info->extack, "Media not found"); + err = -EINVAL; + goto err_out; + } +@@ -1275,9 +1306,10 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) + name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]); + + m = tipc_media_find(name); +- if (!m) ++ if (!m) { ++ NL_SET_ERR_MSG(info->extack, "Media not found"); + return -EINVAL; +- ++ } + if (attrs[TIPC_NLA_MEDIA_PROP]) { + struct nlattr *props[TIPC_NLA_PROP_MAX + 1]; + +@@ -1293,12 +1325,18 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info) + if (props[TIPC_NLA_PROP_WIN]) + m->max_win = nla_get_u32(props[TIPC_NLA_PROP_WIN]); + if (props[TIPC_NLA_PROP_MTU]) { +- if (m->type_id != TIPC_MEDIA_TYPE_UDP) ++ if (m->type_id != TIPC_MEDIA_TYPE_UDP) { ++ NL_SET_ERR_MSG(info->extack, ++ "MTU property is unsupported"); + return -EINVAL; ++ } + #ifdef CONFIG_TIPC_MEDIA_UDP + if (tipc_udp_mtu_bad(nla_get_u32 +- (props[TIPC_NLA_PROP_MTU]))) ++ (props[TIPC_NLA_PROP_MTU]))) { ++ NL_SET_ERR_MSG(info->extack, ++ "MTU value is out-of-range"); + return -EINVAL; ++ } + m->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]); + #endif + } +diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c +index d9cd229aa111b..9b1ea17f3b1dc 100644 +--- a/net/tls/tls_device.c ++++ b/net/tls/tls_device.c +@@ -50,6 +50,7 @@ static void tls_device_gc_task(struct work_struct *work); + static DECLARE_WORK(tls_device_gc_work, tls_device_gc_task); + static LIST_HEAD(tls_device_gc_list); + static LIST_HEAD(tls_device_list); ++static LIST_HEAD(tls_device_down_list); + static DEFINE_SPINLOCK(tls_device_lock); + + static void tls_device_free_ctx(struct tls_context *ctx) +@@ -680,15 +681,13 @@ static void tls_device_resync_rx(struct tls_context *tls_ctx, + struct tls_offload_context_rx *rx_ctx = tls_offload_ctx_rx(tls_ctx); + struct net_device *netdev; + +- if (WARN_ON(test_and_set_bit(TLS_RX_SYNC_RUNNING, &tls_ctx->flags))) +- return; +- + trace_tls_device_rx_resync_send(sk, seq, rcd_sn, rx_ctx->resync_type); ++ rcu_read_lock(); + netdev = READ_ONCE(tls_ctx->netdev); + if (netdev) + netdev->tlsdev_ops->tls_dev_resync(netdev, sk, seq, rcd_sn, + TLS_OFFLOAD_CTX_DIR_RX); +- clear_bit_unlock(TLS_RX_SYNC_RUNNING, &tls_ctx->flags); ++ rcu_read_unlock(); + TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSRXDEVICERESYNC); + } + +@@ -761,6 +760,8 @@ void tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq) + + if (tls_ctx->rx_conf != TLS_HW) + return; ++ if (unlikely(test_bit(TLS_RX_DEV_DEGRADED, &tls_ctx->flags))) ++ return; + + prot = &tls_ctx->prot_info; + rx_ctx = tls_offload_ctx_rx(tls_ctx); +@@ -963,6 +964,17 @@ int tls_device_decrypted(struct sock *sk, struct tls_context *tls_ctx, + + ctx->sw.decrypted |= is_decrypted; + ++ if (unlikely(test_bit(TLS_RX_DEV_DEGRADED, &tls_ctx->flags))) { ++ if (likely(is_encrypted || is_decrypted)) ++ return 0; ++ ++ /* After tls_device_down disables the offload, the next SKB will ++ * likely have initial fragments decrypted, and final ones not ++ * decrypted. We need to reencrypt that single SKB. ++ */ ++ return tls_device_reencrypt(sk, skb); ++ } ++ + /* Return immediately if the record is either entirely plaintext or + * entirely ciphertext. Otherwise handle reencrypt partially decrypted + * record. +@@ -1292,6 +1304,26 @@ static int tls_device_down(struct net_device *netdev) + spin_unlock_irqrestore(&tls_device_lock, flags); + + list_for_each_entry_safe(ctx, tmp, &list, list) { ++ /* Stop offloaded TX and switch to the fallback. ++ * tls_is_sk_tx_device_offloaded will return false. ++ */ ++ WRITE_ONCE(ctx->sk->sk_validate_xmit_skb, tls_validate_xmit_skb_sw); ++ ++ /* Stop the RX and TX resync. ++ * tls_dev_resync must not be called after tls_dev_del. ++ */ ++ WRITE_ONCE(ctx->netdev, NULL); ++ ++ /* Start skipping the RX resync logic completely. */ ++ set_bit(TLS_RX_DEV_DEGRADED, &ctx->flags); ++ ++ /* Sync with inflight packets. After this point: ++ * TX: no non-encrypted packets will be passed to the driver. ++ * RX: resync requests from the driver will be ignored. ++ */ ++ synchronize_net(); ++ ++ /* Release the offload context on the driver side. */ + if (ctx->tx_conf == TLS_HW) + netdev->tlsdev_ops->tls_dev_del(netdev, ctx, + TLS_OFFLOAD_CTX_DIR_TX); +@@ -1299,15 +1331,21 @@ static int tls_device_down(struct net_device *netdev) + !test_bit(TLS_RX_DEV_CLOSED, &ctx->flags)) + netdev->tlsdev_ops->tls_dev_del(netdev, ctx, + TLS_OFFLOAD_CTX_DIR_RX); +- WRITE_ONCE(ctx->netdev, NULL); +- smp_mb__before_atomic(); /* pairs with test_and_set_bit() */ +- while (test_bit(TLS_RX_SYNC_RUNNING, &ctx->flags)) +- usleep_range(10, 200); ++ + dev_put(netdev); +- list_del_init(&ctx->list); + +- if (refcount_dec_and_test(&ctx->refcount)) +- tls_device_free_ctx(ctx); ++ /* Move the context to a separate list for two reasons: ++ * 1. When the context is deallocated, list_del is called. ++ * 2. It's no longer an offloaded context, so we don't want to ++ * run offload-specific code on this context. ++ */ ++ spin_lock_irqsave(&tls_device_lock, flags); ++ list_move_tail(&ctx->list, &tls_device_down_list); ++ spin_unlock_irqrestore(&tls_device_lock, flags); ++ ++ /* Device contexts for RX and TX will be freed in on sk_destruct ++ * by tls_device_free_ctx. rx_conf and tx_conf stay in TLS_HW. ++ */ + } + + up_write(&device_offload_lock); +diff --git a/net/tls/tls_device_fallback.c b/net/tls/tls_device_fallback.c +index cacf040872c74..e40bedd112b68 100644 +--- a/net/tls/tls_device_fallback.c ++++ b/net/tls/tls_device_fallback.c +@@ -431,6 +431,13 @@ struct sk_buff *tls_validate_xmit_skb(struct sock *sk, + } + EXPORT_SYMBOL_GPL(tls_validate_xmit_skb); + ++struct sk_buff *tls_validate_xmit_skb_sw(struct sock *sk, ++ struct net_device *dev, ++ struct sk_buff *skb) ++{ ++ return tls_sw_fallback(sk, skb); ++} ++ + struct sk_buff *tls_encrypt_skb(struct sk_buff *skb) + { + return tls_sw_fallback(skb->sk, skb); +diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c +index 47b7c5334c346..fde56ff491637 100644 +--- a/net/tls/tls_main.c ++++ b/net/tls/tls_main.c +@@ -636,6 +636,7 @@ struct tls_context *tls_ctx_create(struct sock *sk) + mutex_init(&ctx->tx_lock); + rcu_assign_pointer(icsk->icsk_ulp_data, ctx); + ctx->sk_proto = READ_ONCE(sk->sk_prot); ++ ctx->sk = sk; + return ctx; + } + +diff --git a/samples/vfio-mdev/mdpy-fb.c b/samples/vfio-mdev/mdpy-fb.c +index 21dbf63d6e415..9ec93d90e8a5a 100644 +--- a/samples/vfio-mdev/mdpy-fb.c ++++ b/samples/vfio-mdev/mdpy-fb.c +@@ -117,22 +117,27 @@ static int mdpy_fb_probe(struct pci_dev *pdev, + if (format != DRM_FORMAT_XRGB8888) { + pci_err(pdev, "format mismatch (0x%x != 0x%x)\n", + format, DRM_FORMAT_XRGB8888); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_release_regions; + } + if (width < 100 || width > 10000) { + pci_err(pdev, "width (%d) out of range\n", width); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_release_regions; + } + if (height < 100 || height > 10000) { + pci_err(pdev, "height (%d) out of range\n", height); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_release_regions; + } + pci_info(pdev, "mdpy found: %dx%d framebuffer\n", + width, height); + + info = framebuffer_alloc(sizeof(struct mdpy_fb_par), &pdev->dev); +- if (!info) ++ if (!info) { ++ ret = -ENOMEM; + goto err_release_regions; ++ } + pci_set_drvdata(pdev, info); + par = info->par; + +diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal +index 735e11e9041b9..19468831fcc73 100644 +--- a/scripts/Makefile.modfinal ++++ b/scripts/Makefile.modfinal +@@ -59,7 +59,7 @@ quiet_cmd_ld_ko_o = LD [M] $@ + quiet_cmd_btf_ko = BTF [M] $@ + cmd_btf_ko = \ + if [ -f vmlinux ]; then \ +- LLVM_OBJCOPY=$(OBJCOPY) $(PAHOLE) -J --btf_base vmlinux $@; \ ++ LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J --btf_base vmlinux $@; \ + else \ + printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ + fi; +diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh +index 3b261b0f74f0a..0a16928e495b9 100755 +--- a/scripts/link-vmlinux.sh ++++ b/scripts/link-vmlinux.sh +@@ -228,7 +228,7 @@ gen_btf() + vmlinux_link ${1} + + info "BTF" ${2} +- LLVM_OBJCOPY=${OBJCOPY} ${PAHOLE} -J ${1} ++ LLVM_OBJCOPY="${OBJCOPY}" ${PAHOLE} -J ${1} + + # Create ${2} which contains just .BTF section but no symbols. Add + # SHF_ALLOC because .BTF will be part of the vmlinux image. --strip-all +diff --git a/sound/core/timer.c b/sound/core/timer.c +index 6898b1ac0d7f4..92b7008fcdb86 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -520,9 +520,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) + return; + if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) + return; ++ event += 10; /* convert to SNDRV_TIMER_EVENT_MXXX */ + list_for_each_entry(ts, &ti->slave_active_head, active_list) + if (ts->ccallback) +- ts->ccallback(ts, event + 100, &tstamp, resolution); ++ ts->ccallback(ts, event, &tstamp, resolution); + } + + /* start/continue a master timer */ +diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c +index 2026f1ccaf5a7..a220f7ac81263 100644 +--- a/sound/pci/hda/hda_codec.c ++++ b/sound/pci/hda/hda_codec.c +@@ -2973,6 +2973,7 @@ static int hda_codec_runtime_resume(struct device *dev) + #ifdef CONFIG_PM_SLEEP + static int hda_codec_pm_prepare(struct device *dev) + { ++ dev->power.power_state = PMSG_SUSPEND; + return pm_runtime_suspended(dev); + } + +@@ -2980,6 +2981,10 @@ static void hda_codec_pm_complete(struct device *dev) + { + struct hda_codec *codec = dev_to_hda_codec(dev); + ++ /* If no other pm-functions are called between prepare() and complete() */ ++ if (dev->power.power_state.event == PM_EVENT_SUSPEND) ++ dev->power.power_state = PMSG_RESUME; ++ + if (pm_runtime_suspended(dev) && (codec->jackpoll_interval || + hda_codec_need_resume(codec) || codec->forced_resume)) + pm_request_resume(dev); +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index d8424d226714f..cc13a68197f3c 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -8289,6 +8289,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), ++ SND_PCI_QUIRK(0x103c, 0x841c, "HP Pavilion 15-CK0xx", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN), + SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), +diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c +index 7b2d471a6419d..4343356f3cf9a 100644 +--- a/tools/perf/util/dwarf-aux.c ++++ b/tools/perf/util/dwarf-aux.c +@@ -975,9 +975,13 @@ static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) + if ((tag == DW_TAG_formal_parameter || + tag == DW_TAG_variable) && + die_compare_name(die_mem, fvp->name) && +- /* Does the DIE have location information or external instance? */ ++ /* ++ * Does the DIE have location information or const value ++ * or external instance? ++ */ + (dwarf_attr(die_mem, DW_AT_external, &attr) || +- dwarf_attr(die_mem, DW_AT_location, &attr))) ++ dwarf_attr(die_mem, DW_AT_location, &attr) || ++ dwarf_attr(die_mem, DW_AT_const_value, &attr))) + return DIE_FIND_CB_END; + if (dwarf_haspc(die_mem, fvp->addr)) + return DIE_FIND_CB_CONTINUE; +diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c +index 1b118c9c86a69..bba61b95a37a8 100644 +--- a/tools/perf/util/probe-finder.c ++++ b/tools/perf/util/probe-finder.c +@@ -190,6 +190,9 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr, + immediate_value_is_supported()) { + Dwarf_Sword snum; + ++ if (!tvar) ++ return 0; ++ + dwarf_formsdata(&attr, &snum); + ret = asprintf(&tvar->value, "\\%ld", (long)snum); + +diff --git a/tools/testing/selftests/wireguard/netns.sh b/tools/testing/selftests/wireguard/netns.sh +index 7ed7cd95e58fe..ebc4ee0fe179f 100755 +--- a/tools/testing/selftests/wireguard/netns.sh ++++ b/tools/testing/selftests/wireguard/netns.sh +@@ -363,6 +363,7 @@ ip1 -6 rule add table main suppress_prefixlength 0 + ip1 -4 route add default dev wg0 table 51820 + ip1 -4 rule add not fwmark 51820 table 51820 + ip1 -4 rule add table main suppress_prefixlength 0 ++n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/vethc/rp_filter' + # Flood the pings instead of sending just one, to trigger routing table reference counting bugs. + n1 ping -W 1 -c 100 -f 192.168.99.7 + n1 ping -W 1 -c 100 -f abab::1111 +diff --git a/tools/testing/selftests/wireguard/qemu/kernel.config b/tools/testing/selftests/wireguard/qemu/kernel.config +index 4eecb432a66c1..74db83a0aedd8 100644 +--- a/tools/testing/selftests/wireguard/qemu/kernel.config ++++ b/tools/testing/selftests/wireguard/qemu/kernel.config +@@ -19,7 +19,6 @@ CONFIG_NETFILTER_XTABLES=y + CONFIG_NETFILTER_XT_NAT=y + CONFIG_NETFILTER_XT_MATCH_LENGTH=y + CONFIG_NETFILTER_XT_MARK=y +-CONFIG_NF_CONNTRACK_IPV4=y + CONFIG_NF_NAT_IPV4=y + CONFIG_IP_NF_IPTABLES=y + CONFIG_IP_NF_FILTER=y diff --git a/patch/kernel/jetson-nano-legacy b/patch/kernel/jetson-nano-legacy new file mode 120000 index 0000000000..91f0de189d --- /dev/null +++ b/patch/kernel/jetson-nano-legacy @@ -0,0 +1 @@ +archive/jetson-nano-4.9 \ No newline at end of file