commit: 6ae97f813849bf6707efc7a41ec1f990486b4d8b Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Tue May 30 12:58:10 2023 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Tue May 30 12:58:10 2023 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6ae97f81
Linux patch 4.14.316 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 1315_linux-4.14.316.patch | 3880 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3884 insertions(+) diff --git a/0000_README b/0000_README index 3386c191..21cbbeae 100644 --- a/0000_README +++ b/0000_README @@ -1303,6 +1303,10 @@ Patch: 1314_linux-4.14.315.patch From: https://www.kernel.org Desc: Linux 4.14.315 +Patch: 1315_linux-4.14.316.patch +From: https://www.kernel.org +Desc: Linux 4.14.316 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1315_linux-4.14.316.patch b/1315_linux-4.14.316.patch new file mode 100644 index 00000000..ffa8fd54 --- /dev/null +++ b/1315_linux-4.14.316.patch @@ -0,0 +1,3880 @@ +diff --git a/Makefile b/Makefile +index 78a88e76c2536..4962d14e36a90 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 14 +-SUBLEVEL = 315 ++SUBLEVEL = 316 + EXTRAVERSION = + NAME = Petit Gorille + +diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c +index 20a3ff41d0d5a..2498dc17c14b9 100644 +--- a/arch/m68k/kernel/signal.c ++++ b/arch/m68k/kernel/signal.c +@@ -819,11 +819,17 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs * + } + + static inline void __user * +-get_sigframe(struct ksignal *ksig, size_t frame_size) ++get_sigframe(struct ksignal *ksig, struct pt_regs *tregs, size_t frame_size) + { + unsigned long usp = sigsp(rdusp(), ksig); ++ unsigned long gap = 0; + +- return (void __user *)((usp - frame_size) & -8UL); ++ if (CPU_IS_020_OR_030 && tregs->format == 0xb) { ++ /* USP is unreliable so use worst-case value */ ++ gap = 256; ++ } ++ ++ return (void __user *)((usp - gap - frame_size) & -8UL); + } + + static int setup_frame(struct ksignal *ksig, sigset_t *set, +@@ -841,7 +847,7 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set, + return -EFAULT; + } + +- frame = get_sigframe(ksig, sizeof(*frame) + fsize); ++ frame = get_sigframe(ksig, tregs, sizeof(*frame) + fsize); + + if (fsize) + err |= copy_to_user (frame + 1, regs + 1, fsize); +@@ -912,7 +918,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, + return -EFAULT; + } + +- frame = get_sigframe(ksig, sizeof(*frame)); ++ frame = get_sigframe(ksig, tregs, sizeof(*frame)); + + if (fsize) + err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); +diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c +index 77650dc808307..12b38a3bcd736 100644 +--- a/arch/parisc/kernel/process.c ++++ b/arch/parisc/kernel/process.c +@@ -142,13 +142,18 @@ void machine_power_off(void) + /* It seems we have no way to power the system off via + * software. The user has to press the button himself. */ + +- printk(KERN_EMERG "System shut down completed.\n" +- "Please power this system off now."); ++ printk("Power off or press RETURN to reboot.\n"); + + /* prevent soft lockup/stalled CPU messages for endless loop. */ + rcu_sysrq_start(); + lockup_detector_soft_poweroff(); +- for (;;); ++ while (1) { ++ /* reboot if user presses RETURN key */ ++ if (pdc_iodc_getc() == 13) { ++ printk("Rebooting...\n"); ++ machine_restart(NULL); ++ } ++ } + } + + void (*pm_power_off)(void) = machine_power_off; +diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h +index 7811d42e78ef7..436ab2c3a4371 100644 +--- a/arch/x86/include/asm/intel-family.h ++++ b/arch/x86/include/asm/intel-family.h +@@ -73,6 +73,11 @@ + #define INTEL_FAM6_LAKEFIELD 0x8A + #define INTEL_FAM6_ALDERLAKE 0x97 + #define INTEL_FAM6_ALDERLAKE_L 0x9A ++#define INTEL_FAM6_ALDERLAKE_N 0xBE ++ ++#define INTEL_FAM6_RAPTORLAKE 0xB7 ++#define INTEL_FAM6_RAPTORLAKE_P 0xBA ++#define INTEL_FAM6_RAPTORLAKE_S 0xBF + + #define INTEL_FAM6_TIGERLAKE_L 0x8C + #define INTEL_FAM6_TIGERLAKE 0x8D +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index 92585a755410b..8c766aa56f0ae 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -115,7 +115,6 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + printk("%sCall Trace:\n", log_lvl); + + unwind_start(&state, task, regs, stack); +- stack = stack ? : get_stack_pointer(task, regs); + regs = unwind_get_entry_regs(&state, &partial); + + /* +@@ -134,9 +133,13 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + * - hardirq stack + * - entry stack + */ +- for ( ; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { ++ for (stack = stack ?: get_stack_pointer(task, regs); ++ stack; ++ stack = stack_info.next_sp) { + const char *stack_name; + ++ stack = PTR_ALIGN(stack, sizeof(long)); ++ + if (get_stack_info(stack, task, &stack_info, &visit_mask)) { + /* + * We weren't on a valid stack. It's possible that +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index 8039a951db8f5..579f48ee03be2 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -8,6 +8,7 @@ + #include <linux/swapops.h> + + #include <asm/set_memory.h> ++#include <asm/cpu_device_id.h> + #include <asm/e820/api.h> + #include <asm/init.h> + #include <asm/page.h> +@@ -199,6 +200,24 @@ static void __init probe_page_size_mask(void) + } + } + ++#define INTEL_MATCH(_model) { .vendor = X86_VENDOR_INTEL, \ ++ .family = 6, \ ++ .model = _model, \ ++ } ++/* ++ * INVLPG may not properly flush Global entries ++ * on these CPUs when PCIDs are enabled. ++ */ ++static const struct x86_cpu_id invlpg_miss_ids[] = { ++ INTEL_MATCH(INTEL_FAM6_ALDERLAKE ), ++ INTEL_MATCH(INTEL_FAM6_ALDERLAKE_L ), ++ INTEL_MATCH(INTEL_FAM6_ALDERLAKE_N ), ++ INTEL_MATCH(INTEL_FAM6_RAPTORLAKE ), ++ INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_P), ++ INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_S), ++ {} ++}; ++ + static void setup_pcid(void) + { + if (!IS_ENABLED(CONFIG_X86_64)) +@@ -207,6 +226,12 @@ static void setup_pcid(void) + if (!boot_cpu_has(X86_FEATURE_PCID)) + return; + ++ if (x86_match_cpu(invlpg_miss_ids)) { ++ pr_info("Incomplete global flushes, disabling PCID"); ++ setup_clear_cpu_cap(X86_FEATURE_PCID); ++ return; ++ } ++ + if (boot_cpu_has(X86_FEATURE_PGE)) { + /* + * This can't be cr4_set_bits_and_update_boot() -- the +diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c +index 8c207c7725179..658fd7cfbd6cd 100644 +--- a/drivers/acpi/acpica/dbnames.c ++++ b/drivers/acpi/acpica/dbnames.c +@@ -600,6 +600,9 @@ acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg) + object_info = + ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info)); + ++ if (!object_info) ++ return (AE_NO_MEMORY); ++ + /* Walk the namespace from the root */ + + (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, +diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c +index da111a1f5bfbc..6eaf2a01034ea 100644 +--- a/drivers/acpi/acpica/dswstate.c ++++ b/drivers/acpi/acpica/dswstate.c +@@ -610,9 +610,14 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, + ACPI_FUNCTION_TRACE(ds_init_aml_walk); + + walk_state->parser_state.aml = +- walk_state->parser_state.aml_start = aml_start; +- walk_state->parser_state.aml_end = +- walk_state->parser_state.pkg_end = aml_start + aml_length; ++ walk_state->parser_state.aml_start = ++ walk_state->parser_state.aml_end = ++ walk_state->parser_state.pkg_end = aml_start; ++ /* Avoid undefined behavior: applying zero offset to null pointer */ ++ if (aml_length != 0) { ++ walk_state->parser_state.aml_end += aml_length; ++ walk_state->parser_state.pkg_end += aml_length; ++ } + + /* The next_op of the next_walk will be the beginning of the method */ + +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c +index f8fc30be68711..1dedab328c464 100644 +--- a/drivers/acpi/ec.c ++++ b/drivers/acpi/ec.c +@@ -1135,6 +1135,7 @@ static void acpi_ec_remove_query_handlers(struct acpi_ec *ec, + void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) + { + acpi_ec_remove_query_handlers(ec, false, query_bit); ++ flush_workqueue(ec_query_wq); + } + EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); + +diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c +index 773560348337f..b78e4b6e2c9da 100644 +--- a/drivers/base/regmap/regcache.c ++++ b/drivers/base/regmap/regcache.c +@@ -347,6 +347,9 @@ int regcache_sync(struct regmap *map) + const char *name; + bool bypass; + ++ if (WARN_ON(map->cache_type == REGCACHE_NONE)) ++ return -EINVAL; ++ + BUG_ON(!map->cache_ops); + + map->lock(map->lock_arg); +@@ -416,6 +419,9 @@ int regcache_sync_region(struct regmap *map, unsigned int min, + const char *name; + bool bypass; + ++ if (WARN_ON(map->cache_type == REGCACHE_NONE)) ++ return -EINVAL; ++ + BUG_ON(!map->cache_ops); + + map->lock(map->lock_arg); +diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c +index 4c9038e738886..a660adaa4920f 100644 +--- a/drivers/clk/tegra/clk-tegra20.c ++++ b/drivers/clk/tegra/clk-tegra20.c +@@ -27,24 +27,24 @@ + #include "clk-id.h" + + #define OSC_CTRL 0x50 +-#define OSC_CTRL_OSC_FREQ_MASK (3<<30) +-#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) +-#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30) +-#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30) +-#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30) +-#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) +- +-#define OSC_CTRL_PLL_REF_DIV_MASK (3<<28) +-#define OSC_CTRL_PLL_REF_DIV_1 (0<<28) +-#define OSC_CTRL_PLL_REF_DIV_2 (1<<28) +-#define OSC_CTRL_PLL_REF_DIV_4 (2<<28) ++#define OSC_CTRL_OSC_FREQ_MASK (3u<<30) ++#define OSC_CTRL_OSC_FREQ_13MHZ (0u<<30) ++#define OSC_CTRL_OSC_FREQ_19_2MHZ (1u<<30) ++#define OSC_CTRL_OSC_FREQ_12MHZ (2u<<30) ++#define OSC_CTRL_OSC_FREQ_26MHZ (3u<<30) ++#define OSC_CTRL_MASK (0x3f2u | OSC_CTRL_OSC_FREQ_MASK) ++ ++#define OSC_CTRL_PLL_REF_DIV_MASK (3u<<28) ++#define OSC_CTRL_PLL_REF_DIV_1 (0u<<28) ++#define OSC_CTRL_PLL_REF_DIV_2 (1u<<28) ++#define OSC_CTRL_PLL_REF_DIV_4 (2u<<28) + + #define OSC_FREQ_DET 0x58 +-#define OSC_FREQ_DET_TRIG (1<<31) ++#define OSC_FREQ_DET_TRIG (1u<<31) + + #define OSC_FREQ_DET_STATUS 0x5c +-#define OSC_FREQ_DET_BUSY (1<<31) +-#define OSC_FREQ_DET_CNT_MASK 0xFFFF ++#define OSC_FREQ_DET_BUSYu (1<<31) ++#define OSC_FREQ_DET_CNT_MASK 0xFFFFu + + #define TEGRA20_CLK_PERIPH_BANKS 3 + +diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c +index 352ae52be3418..76451c8bfb46b 100644 +--- a/drivers/gpu/drm/tegra/sor.c ++++ b/drivers/gpu/drm/tegra/sor.c +@@ -709,7 +709,7 @@ static int tegra_sor_compute_config(struct tegra_sor *sor, + struct drm_dp_link *link) + { + const u64 f = 100000, link_rate = link->rate * 1000; +- const u64 pclk = mode->clock * 1000; ++ const u64 pclk = (u64)mode->clock * 1000; + u64 input, output, watermark, num; + struct tegra_sor_params params; + u32 num_syms_per_line; +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index 6ad776b4711b7..1588508b3e7b7 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -675,8 +675,7 @@ static int hidpp_unifying_init(struct hidpp_device *hidpp) + if (ret) + return ret; + +- snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD", +- hdev->product, &serial); ++ snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial); + dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq); + + name = hidpp_unifying_get_name(hidpp); +@@ -777,6 +776,54 @@ static bool hidpp_is_connected(struct hidpp_device *hidpp) + return ret == 0; + } + ++/* -------------------------------------------------------------------------- */ ++/* 0x0003: Device Information */ ++/* -------------------------------------------------------------------------- */ ++ ++#define HIDPP_PAGE_DEVICE_INFORMATION 0x0003 ++ ++#define CMD_GET_DEVICE_INFO 0x00 ++ ++static int hidpp_get_serial(struct hidpp_device *hidpp, u32 *serial) ++{ ++ struct hidpp_report response; ++ u8 feature_type; ++ u8 feature_index; ++ int ret; ++ ++ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_DEVICE_INFORMATION, ++ &feature_index, ++ &feature_type); ++ if (ret) ++ return ret; ++ ++ ret = hidpp_send_fap_command_sync(hidpp, feature_index, ++ CMD_GET_DEVICE_INFO, ++ NULL, 0, &response); ++ if (ret) ++ return ret; ++ ++ /* See hidpp_unifying_get_serial() */ ++ *serial = *((u32 *)&response.rap.params[1]); ++ return 0; ++} ++ ++static int hidpp_serial_init(struct hidpp_device *hidpp) ++{ ++ struct hid_device *hdev = hidpp->hid_dev; ++ u32 serial; ++ int ret; ++ ++ ret = hidpp_get_serial(hidpp, &serial); ++ if (ret) ++ return ret; ++ ++ snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial); ++ dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq); ++ ++ return 0; ++} ++ + /* -------------------------------------------------------------------------- */ + /* 0x0005: GetDeviceNameType */ + /* -------------------------------------------------------------------------- */ +@@ -3039,6 +3086,8 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) + + if (hidpp->quirks & HIDPP_QUIRK_UNIFYING) + hidpp_unifying_init(hidpp); ++ else if (hid_is_usb(hidpp->hid_dev)) ++ hidpp_serial_init(hidpp); + + connected = hidpp_is_connected(hidpp); + atomic_set(&hidpp->connected, connected); +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index 921d5184196d2..1b0161c2cd7a6 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -1782,18 +1782,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage, + static void wacom_wac_battery_usage_mapping(struct hid_device *hdev, + struct hid_field *field, struct hid_usage *usage) + { +- struct wacom *wacom = hid_get_drvdata(hdev); +- struct wacom_wac *wacom_wac = &wacom->wacom_wac; +- struct wacom_features *features = &wacom_wac->features; +- unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); +- +- switch (equivalent_usage) { +- case HID_DG_BATTERYSTRENGTH: +- case WACOM_HID_WD_BATTERY_LEVEL: +- case WACOM_HID_WD_BATTERY_CHARGING: +- features->quirks |= WACOM_QUIRK_BATTERY; +- break; +- } ++ return; + } + + static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field, +@@ -1814,18 +1803,21 @@ static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *f + wacom_wac->hid_data.bat_connected = 1; + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; + } ++ wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY; + break; + case WACOM_HID_WD_BATTERY_LEVEL: + value = value * 100 / (field->logical_maximum - field->logical_minimum); + wacom_wac->hid_data.battery_capacity = value; + wacom_wac->hid_data.bat_connected = 1; + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; ++ wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY; + break; + case WACOM_HID_WD_BATTERY_CHARGING: + wacom_wac->hid_data.bat_charging = value; + wacom_wac->hid_data.ps_connected = value; + wacom_wac->hid_data.bat_connected = 1; + wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; ++ wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY; + break; + } + } +@@ -1841,18 +1833,15 @@ static void wacom_wac_battery_report(struct hid_device *hdev, + { + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; +- struct wacom_features *features = &wacom_wac->features; + +- if (features->quirks & WACOM_QUIRK_BATTERY) { +- int status = wacom_wac->hid_data.bat_status; +- int capacity = wacom_wac->hid_data.battery_capacity; +- bool charging = wacom_wac->hid_data.bat_charging; +- bool connected = wacom_wac->hid_data.bat_connected; +- bool powered = wacom_wac->hid_data.ps_connected; ++ int status = wacom_wac->hid_data.bat_status; ++ int capacity = wacom_wac->hid_data.battery_capacity; ++ bool charging = wacom_wac->hid_data.bat_charging; ++ bool connected = wacom_wac->hid_data.bat_connected; ++ bool powered = wacom_wac->hid_data.ps_connected; + +- wacom_notify_battery(wacom_wac, status, capacity, charging, +- connected, powered); +- } ++ wacom_notify_battery(wacom_wac, status, capacity, charging, ++ connected, powered); + } + + static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 1a12f95227301..f1c2bc108fd76 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -506,6 +506,9 @@ struct xboxone_init_packet { + } + + ++#define GIP_WIRED_INTF_DATA 0 ++#define GIP_WIRED_INTF_AUDIO 1 ++ + /* + * This packet is required for all Xbox One pads with 2015 + * or later firmware installed (or present from the factory). +@@ -1830,7 +1833,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id + } + + if (xpad->xtype == XTYPE_XBOXONE && +- intf->cur_altsetting->desc.bInterfaceNumber != 0) { ++ intf->cur_altsetting->desc.bInterfaceNumber != GIP_WIRED_INTF_DATA) { + /* + * The Xbox One controller lists three interfaces all with the + * same interface class, subclass and protocol. Differentiate by +diff --git a/drivers/mcb/mcb-pci.c b/drivers/mcb/mcb-pci.c +index af4d2f26f1c62..b0ec3bbf1b76d 100644 +--- a/drivers/mcb/mcb-pci.c ++++ b/drivers/mcb/mcb-pci.c +@@ -34,7 +34,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + { + struct resource *res; + struct priv *priv; +- int ret; ++ int ret, table_size; + unsigned long flags; + + priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL); +@@ -93,7 +93,30 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + if (ret < 0) + goto out_mcb_bus; + +- dev_dbg(&pdev->dev, "Found %d cells\n", ret); ++ table_size = ret; ++ ++ if (table_size < CHAM_HEADER_SIZE) { ++ /* Release the previous resources */ ++ devm_iounmap(&pdev->dev, priv->base); ++ devm_release_mem_region(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE); ++ ++ /* Then, allocate it again with the actual chameleon table size */ ++ res = devm_request_mem_region(&pdev->dev, priv->mapbase, ++ table_size, ++ KBUILD_MODNAME); ++ if (!res) { ++ dev_err(&pdev->dev, "Failed to request PCI memory\n"); ++ ret = -EBUSY; ++ goto out_mcb_bus; ++ } ++ ++ priv->base = devm_ioremap(&pdev->dev, priv->mapbase, table_size); ++ if (!priv->base) { ++ dev_err(&pdev->dev, "Cannot ioremap\n"); ++ ret = -ENOMEM; ++ goto out_mcb_bus; ++ } ++ } + + mcb_bus_add_devices(priv->bus); + +diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +index 03239fba87bf2..4f2ea0f035ae5 100644 +--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c ++++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +@@ -707,7 +707,7 @@ static void netup_unidvb_dma_fini(struct netup_unidvb_dev *ndev, int num) + netup_unidvb_dma_enable(dma, 0); + msleep(50); + cancel_work_sync(&dma->work); +- del_timer(&dma->timeout); ++ del_timer_sync(&dma->timeout); + } + + static int netup_unidvb_dma_setup(struct netup_unidvb_dev *ndev) +diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c +index 22f3466af2b18..5275180aed0b7 100644 +--- a/drivers/media/radio/radio-shark.c ++++ b/drivers/media/radio/radio-shark.c +@@ -316,6 +316,16 @@ static int usb_shark_probe(struct usb_interface *intf, + { + struct shark_device *shark; + int retval = -ENOMEM; ++ static const u8 ep_addresses[] = { ++ SHARK_IN_EP | USB_DIR_IN, ++ SHARK_OUT_EP | USB_DIR_OUT, ++ 0}; ++ ++ /* Are the expected endpoints present? */ ++ if (!usb_check_int_endpoints(intf, ep_addresses)) { ++ dev_err(&intf->dev, "Invalid radioSHARK device\n"); ++ return -EINVAL; ++ } + + shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); + if (!shark) +diff --git a/drivers/media/radio/radio-shark2.c b/drivers/media/radio/radio-shark2.c +index 4d1a4b3d669cf..5356941f54aef 100644 +--- a/drivers/media/radio/radio-shark2.c ++++ b/drivers/media/radio/radio-shark2.c +@@ -282,6 +282,16 @@ static int usb_shark_probe(struct usb_interface *intf, + { + struct shark_device *shark; + int retval = -ENOMEM; ++ static const u8 ep_addresses[] = { ++ SHARK_IN_EP | USB_DIR_IN, ++ SHARK_OUT_EP | USB_DIR_OUT, ++ 0}; ++ ++ /* Are the expected endpoints present? */ ++ if (!usb_check_int_endpoints(intf, ep_addresses)) { ++ dev_err(&intf->dev, "Invalid radioSHARK2 device\n"); ++ return -EINVAL; ++ } + + shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); + if (!shark) +diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c +index 256634ec58b63..d52c89b2a1d58 100644 +--- a/drivers/memstick/host/r592.c ++++ b/drivers/memstick/host/r592.c +@@ -832,7 +832,7 @@ static void r592_remove(struct pci_dev *pdev) + /* Stop the processing thread. + That ensures that we won't take any more requests */ + kthread_stop(dev->io_thread); +- ++ del_timer_sync(&dev->detect_timer); + r592_enable_device(dev, false); + + while (!error && dev->req) { +diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c +index 55dd71bbdc2aa..74d0ae00b0827 100644 +--- a/drivers/message/fusion/mptlan.c ++++ b/drivers/message/fusion/mptlan.c +@@ -1429,7 +1429,9 @@ mptlan_remove(struct pci_dev *pdev) + { + MPT_ADAPTER *ioc = pci_get_drvdata(pdev); + struct net_device *dev = ioc->netdev; ++ struct mpt_lan_priv *priv = netdev_priv(dev); + ++ cancel_delayed_work_sync(&priv->post_buckets_task); + if(dev != NULL) { + unregister_netdev(dev); + free_netdev(dev); +diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c +index 97a69cd6f1278..a0ad99ca495fd 100644 +--- a/drivers/mfd/dln2.c ++++ b/drivers/mfd/dln2.c +@@ -804,6 +804,7 @@ out_stop_rx: + dln2_stop_rx_urbs(dln2); + + out_free: ++ usb_put_dev(dln2->usb_dev); + dln2_free(dln2); + + return ret; +diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c +index e28254a005997..0c0bc3c178abe 100644 +--- a/drivers/net/ethernet/3com/3c589_cs.c ++++ b/drivers/net/ethernet/3com/3c589_cs.c +@@ -196,6 +196,7 @@ static int tc589_probe(struct pcmcia_device *link) + { + struct el3_private *lp; + struct net_device *dev; ++ int ret; + + dev_dbg(&link->dev, "3c589_attach()\n"); + +@@ -219,7 +220,15 @@ static int tc589_probe(struct pcmcia_device *link) + + dev->ethtool_ops = &netdev_ethtool_ops; + +- return tc589_config(link); ++ ret = tc589_config(link); ++ if (ret) ++ goto err_free_netdev; ++ ++ return 0; ++ ++err_free_netdev: ++ free_netdev(dev); ++ return ret; + } + + static void tc589_detach(struct pcmcia_device *link) +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index c6fc77a211ea6..1085f1d721b02 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -3569,7 +3569,9 @@ fec_drv_remove(struct platform_device *pdev) + + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) +- return ret; ++ dev_err(&pdev->dev, ++ "Failed to resume device in remove callback (%pe)\n", ++ ERR_PTR(ret)); + + cancel_work_sync(&fep->tx_timeout_work); + fec_ptp_stop(pdev); +@@ -3582,8 +3584,13 @@ fec_drv_remove(struct platform_device *pdev) + of_phy_deregister_fixed_link(np); + of_node_put(fep->phy_node); + +- clk_disable_unprepare(fep->clk_ahb); +- clk_disable_unprepare(fep->clk_ipg); ++ /* After pm_runtime_get_sync() failed, the clks are still off, so skip ++ * disabling them again. ++ */ ++ if (ret >= 0) { ++ clk_disable_unprepare(fep->clk_ahb); ++ clk_disable_unprepare(fep->clk_ipg); ++ } + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + +diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c +index 5eff82678f0ba..1db5d2edecbc1 100644 +--- a/drivers/net/ethernet/intel/igb/e1000_mac.c ++++ b/drivers/net/ethernet/intel/igb/e1000_mac.c +@@ -445,7 +445,7 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value) + static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) + { + u32 hash_value, hash_mask; +- u8 bit_shift = 0; ++ u8 bit_shift = 1; + + /* Register count multiplied by bits per register */ + hash_mask = (hw->mac.mta_reg_count * 32) - 1; +@@ -453,7 +453,7 @@ static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) + /* For a mc_filter_type of 0, bit_shift is the number of left-shifts + * where 0xFF would still fall within the hash mask. + */ +- while (hash_mask >> bit_shift != 0xFF) ++ while (hash_mask >> bit_shift != 0xFF && bit_shift < 4) + bit_shift++; + + /* The portion of the address that is used for the hash table +diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c +index 994a83a1f0a5c..3e8477e697c52 100644 +--- a/drivers/net/ethernet/nvidia/forcedeth.c ++++ b/drivers/net/ethernet/nvidia/forcedeth.c +@@ -6020,6 +6020,7 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) + return 0; + + out_error: ++ nv_mgmt_release_sema(dev); + if (phystate_orig) + writel(phystate|NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); + out_freering: +diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c +index 6ccdce21ca9b5..c891ee70099a7 100644 +--- a/drivers/net/ethernet/pasemi/pasemi_mac.c ++++ b/drivers/net/ethernet/pasemi/pasemi_mac.c +@@ -1436,7 +1436,7 @@ static void pasemi_mac_queue_csdesc(const struct sk_buff *skb, + write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), 2); + } + +-static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) ++static netdev_tx_t pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) + { + struct pasemi_mac * const mac = netdev_priv(dev); + struct pasemi_mac_txring * const txring = tx_ring(mac); +diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c +index 7e5c0f182770d..ba546f993fb53 100644 +--- a/drivers/net/ethernet/sun/cassini.c ++++ b/drivers/net/ethernet/sun/cassini.c +@@ -5152,6 +5152,8 @@ err_out_iounmap: + cas_shutdown(cp); + mutex_unlock(&cp->pm_mutex); + ++ vfree(cp->fw_data); ++ + pci_iounmap(pdev, cp->regs); + + +diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c +index 71fd45137ee44..6283cbc9f6ed1 100644 +--- a/drivers/net/ipvlan/ipvlan_core.c ++++ b/drivers/net/ipvlan/ipvlan_core.c +@@ -394,6 +394,9 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) + goto err; + } + skb_dst_set(skb, &rt->dst); ++ ++ memset(IPCB(skb), 0, sizeof(*IPCB(skb))); ++ + err = ip_local_out(net, skb->sk, skb); + if (unlikely(net_xmit_eval(err))) + dev->stats.tx_errors++; +@@ -431,6 +434,9 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) + goto err; + } + skb_dst_set(skb, dst); ++ ++ memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); ++ + err = ip6_local_out(net, skb->sk, skb); + if (unlikely(net_xmit_eval(err))) + dev->stats.tx_errors++; +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +index df0e48e4cf5b3..4abb948f607fa 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1349,13 +1349,14 @@ static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e) + static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len) + { + struct brcmf_wsec_pmk_le pmk; +- int i, err; ++ int err; ++ ++ memset(&pmk, 0, sizeof(pmk)); + +- /* convert to firmware key format */ +- pmk.key_len = cpu_to_le16(pmk_len << 1); +- pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE); +- for (i = 0; i < pmk_len; i++) +- snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]); ++ /* pass pmk directly */ ++ pmk.key_len = cpu_to_le16(pmk_len); ++ pmk.flags = cpu_to_le16(0); ++ memcpy(pmk.key, pmk_data, pmk_len); + + /* store psk in firmware */ + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK, +diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c +index de6ec9b7ace45..f30bac02d32ce 100644 +--- a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c ++++ b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c +@@ -1101,6 +1101,7 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv, + { + __le16 key_flags; + struct iwl_addsta_cmd sta_cmd; ++ size_t to_copy; + int i; + + spin_lock_bh(&priv->sta_lock); +@@ -1120,7 +1121,9 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv, + sta_cmd.key.tkip_rx_tsc_byte2 = tkip_iv32; + for (i = 0; i < 5; i++) + sta_cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]); +- memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen); ++ /* keyconf may contain MIC rx/tx keys which iwl does not use */ ++ to_copy = min_t(size_t, sizeof(sta_cmd.key.key), keyconf->keylen); ++ memcpy(sta_cmd.key.key, keyconf->key, to_copy); + break; + case WLAN_CIPHER_SUITE_WEP104: + key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; +diff --git a/drivers/phy/st/phy-miphy28lp.c b/drivers/phy/st/phy-miphy28lp.c +index 213e2e15339c4..fe23432e5b1a6 100644 +--- a/drivers/phy/st/phy-miphy28lp.c ++++ b/drivers/phy/st/phy-miphy28lp.c +@@ -13,6 +13,7 @@ + + #include <linux/platform_device.h> + #include <linux/io.h> ++#include <linux/iopoll.h> + #include <linux/kernel.h> + #include <linux/module.h> + #include <linux/of.h> +@@ -488,19 +489,11 @@ static inline void miphy28lp_pcie_config_gen(struct miphy28lp_phy *miphy_phy) + + static inline int miphy28lp_wait_compensation(struct miphy28lp_phy *miphy_phy) + { +- unsigned long finish = jiffies + 5 * HZ; + u8 val; + + /* Waiting for Compensation to complete */ +- do { +- val = readb_relaxed(miphy_phy->base + MIPHY_COMP_FSM_6); +- +- if (time_after_eq(jiffies, finish)) +- return -EBUSY; +- cpu_relax(); +- } while (!(val & COMP_DONE)); +- +- return 0; ++ return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_COMP_FSM_6, ++ val, val & COMP_DONE, 1, 5 * USEC_PER_SEC); + } + + +@@ -809,7 +802,6 @@ static inline void miphy28lp_configure_usb3(struct miphy28lp_phy *miphy_phy) + + static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy) + { +- unsigned long finish = jiffies + 5 * HZ; + u8 mask = HFC_PLL | HFC_RDY; + u8 val; + +@@ -820,21 +812,14 @@ static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy) + if (miphy_phy->type == PHY_TYPE_SATA) + mask |= PHY_RDY; + +- do { +- val = readb_relaxed(miphy_phy->base + MIPHY_STATUS_1); +- if ((val & mask) != mask) +- cpu_relax(); +- else +- return 0; +- } while (!time_after_eq(jiffies, finish)); +- +- return -EBUSY; ++ return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_STATUS_1, ++ val, (val & mask) == mask, 1, ++ 5 * USEC_PER_SEC); + } + + static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy) + { + struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; +- unsigned long finish = jiffies + 5 * HZ; + u32 val; + + if (!miphy_phy->osc_rdy) +@@ -843,17 +828,10 @@ static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy) + if (!miphy_phy->syscfg_reg[SYSCFG_STATUS]) + return -EINVAL; + +- do { +- regmap_read(miphy_dev->regmap, +- miphy_phy->syscfg_reg[SYSCFG_STATUS], &val); +- +- if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY) +- cpu_relax(); +- else +- return 0; +- } while (!time_after_eq(jiffies, finish)); +- +- return -EBUSY; ++ return regmap_read_poll_timeout(miphy_dev->regmap, ++ miphy_phy->syscfg_reg[SYSCFG_STATUS], ++ val, val & MIPHY_OSC_RDY, 1, ++ 5 * USEC_PER_SEC); + } + + static int miphy28lp_get_resource_byname(struct device_node *child, +diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c +index 3e8466064bb2c..37b5743ce35e4 100644 +--- a/drivers/power/supply/bq27xxx_battery.c ++++ b/drivers/power/supply/bq27xxx_battery.c +@@ -1506,7 +1506,7 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di) + return POWER_SUPPLY_HEALTH_GOOD; + } + +-void bq27xxx_battery_update(struct bq27xxx_device_info *di) ++static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di) + { + struct bq27xxx_reg_cache cache = {0, }; + bool has_ci_flag = di->opts & BQ27XXX_O_ZERO; +@@ -1554,6 +1554,16 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di) + di->cache = cache; + + di->last_update = jiffies; ++ ++ if (!di->removed && poll_interval > 0) ++ mod_delayed_work(system_wq, &di->work, poll_interval * HZ); ++} ++ ++void bq27xxx_battery_update(struct bq27xxx_device_info *di) ++{ ++ mutex_lock(&di->lock); ++ bq27xxx_battery_update_unlocked(di); ++ mutex_unlock(&di->lock); + } + EXPORT_SYMBOL_GPL(bq27xxx_battery_update); + +@@ -1564,9 +1574,6 @@ static void bq27xxx_battery_poll(struct work_struct *work) + work.work); + + bq27xxx_battery_update(di); +- +- if (poll_interval > 0) +- schedule_delayed_work(&di->work, poll_interval * HZ); + } + + /* +@@ -1725,10 +1732,8 @@ static int bq27xxx_battery_get_property(struct power_supply *psy, + struct bq27xxx_device_info *di = power_supply_get_drvdata(psy); + + mutex_lock(&di->lock); +- if (time_is_before_jiffies(di->last_update + 5 * HZ)) { +- cancel_delayed_work_sync(&di->work); +- bq27xxx_battery_poll(&di->work.work); +- } ++ if (time_is_before_jiffies(di->last_update + 5 * HZ)) ++ bq27xxx_battery_update_unlocked(di); + mutex_unlock(&di->lock); + + if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0) +@@ -1865,22 +1870,18 @@ EXPORT_SYMBOL_GPL(bq27xxx_battery_setup); + + void bq27xxx_battery_teardown(struct bq27xxx_device_info *di) + { +- /* +- * power_supply_unregister call bq27xxx_battery_get_property which +- * call bq27xxx_battery_poll. +- * Make sure that bq27xxx_battery_poll will not call +- * schedule_delayed_work again after unregister (which cause OOPS). +- */ +- poll_interval = 0; +- +- cancel_delayed_work_sync(&di->work); +- +- power_supply_unregister(di->bat); +- + mutex_lock(&bq27xxx_list_lock); + list_del(&di->list); + mutex_unlock(&bq27xxx_list_lock); + ++ /* Set removed to avoid bq27xxx_battery_update() re-queuing the work */ ++ mutex_lock(&di->lock); ++ di->removed = true; ++ mutex_unlock(&di->lock); ++ ++ cancel_delayed_work_sync(&di->work); ++ ++ power_supply_unregister(di->bat); + mutex_destroy(&di->lock); + } + EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown); +diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c +index 12ffe62caa17b..426ce81333a54 100644 +--- a/drivers/power/supply/bq27xxx_battery_i2c.c ++++ b/drivers/power/supply/bq27xxx_battery_i2c.c +@@ -187,7 +187,7 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client, + i2c_set_clientdata(client, di); + + if (client->irq) { +- ret = devm_request_threaded_irq(&client->dev, client->irq, ++ ret = request_threaded_irq(client->irq, + NULL, bq27xxx_battery_irq_handler_thread, + IRQF_ONESHOT, + di->name, di); +@@ -217,6 +217,7 @@ static int bq27xxx_battery_i2c_remove(struct i2c_client *client) + { + struct bq27xxx_device_info *di = i2c_get_clientdata(client); + ++ free_irq(client->irq, di); + bq27xxx_battery_teardown(di); + + mutex_lock(&battery_mutex); +diff --git a/drivers/power/supply/power_supply_leds.c b/drivers/power/supply/power_supply_leds.c +index 2277ad9c2f682..9188b7ccdd4c7 100644 +--- a/drivers/power/supply/power_supply_leds.c ++++ b/drivers/power/supply/power_supply_leds.c +@@ -35,8 +35,9 @@ static void power_supply_update_bat_leds(struct power_supply *psy) + led_trigger_event(psy->charging_full_trig, LED_FULL); + led_trigger_event(psy->charging_trig, LED_OFF); + led_trigger_event(psy->full_trig, LED_FULL); +- led_trigger_event(psy->charging_blink_full_solid_trig, +- LED_FULL); ++ /* Going from blink to LED on requires a LED_OFF event to stop blink */ ++ led_trigger_event(psy->charging_blink_full_solid_trig, LED_OFF); ++ led_trigger_event(psy->charging_blink_full_solid_trig, LED_FULL); + break; + case POWER_SUPPLY_STATUS_CHARGING: + led_trigger_event(psy->charging_full_trig, LED_FULL); +diff --git a/drivers/power/supply/sbs-charger.c b/drivers/power/supply/sbs-charger.c +index 15947dbb511e3..0f9cc82d81618 100644 +--- a/drivers/power/supply/sbs-charger.c ++++ b/drivers/power/supply/sbs-charger.c +@@ -29,7 +29,7 @@ + #define SBS_CHARGER_REG_STATUS 0x13 + #define SBS_CHARGER_REG_ALARM_WARNING 0x16 + +-#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(1) ++#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(0) + #define SBS_CHARGER_STATUS_RES_COLD BIT(9) + #define SBS_CHARGER_STATUS_RES_HOT BIT(10) + #define SBS_CHARGER_STATUS_BATTERY_PRESENT BIT(14) +diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c +index 8f7b26ec181e2..0485593dc2f5b 100644 +--- a/drivers/spi/spi-fsl-cpm.c ++++ b/drivers/spi/spi-fsl-cpm.c +@@ -25,6 +25,7 @@ + #include <linux/spi/spi.h> + #include <linux/types.h> + #include <linux/platform_device.h> ++#include <linux/byteorder/generic.h> + + #include "spi-fsl-cpm.h" + #include "spi-fsl-lib.h" +@@ -124,6 +125,21 @@ int fsl_spi_cpm_bufs(struct mpc8xxx_spi *mspi, + mspi->rx_dma = mspi->dma_dummy_rx; + mspi->map_rx_dma = 0; + } ++ if (t->bits_per_word == 16 && t->tx_buf) { ++ const u16 *src = t->tx_buf; ++ u16 *dst; ++ int i; ++ ++ dst = kmalloc(t->len, GFP_KERNEL); ++ if (!dst) ++ return -ENOMEM; ++ ++ for (i = 0; i < t->len >> 1; i++) ++ dst[i] = cpu_to_le16p(src + i); ++ ++ mspi->tx = dst; ++ mspi->map_tx_dma = 1; ++ } + + if (mspi->map_tx_dma) { + void *nonconst_tx = (void *)mspi->tx; /* shut up gcc */ +@@ -177,6 +193,13 @@ void fsl_spi_cpm_bufs_complete(struct mpc8xxx_spi *mspi) + if (mspi->map_rx_dma) + dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE); + mspi->xfer_in_progress = NULL; ++ ++ if (t->bits_per_word == 16 && t->rx_buf) { ++ int i; ++ ++ for (i = 0; i < t->len; i += 2) ++ le16_to_cpus(t->rx_buf + i); ++ } + } + EXPORT_SYMBOL_GPL(fsl_spi_cpm_bufs_complete); + +diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c +index 479d10dc6cb84..5e49fed487f8a 100644 +--- a/drivers/spi/spi-fsl-spi.c ++++ b/drivers/spi/spi-fsl-spi.c +@@ -201,26 +201,6 @@ static int mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs, + return bits_per_word; + } + +-static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs, +- struct spi_device *spi, +- int bits_per_word) +-{ +- /* CPM/QE uses Little Endian for words > 8 +- * so transform 16 and 32 bits words into 8 bits +- * Unfortnatly that doesn't work for LSB so +- * reject these for now */ +- /* Note: 32 bits word, LSB works iff +- * tfcr/rfcr is set to CPMFCR_GBL */ +- if (spi->mode & SPI_LSB_FIRST && +- bits_per_word > 8) +- return -EINVAL; +- if (bits_per_word <= 8) +- return bits_per_word; +- if (bits_per_word == 16 || bits_per_word == 32) +- return 8; /* pretend its 8 bits */ +- return -EINVAL; +-} +- + static int fsl_spi_setup_transfer(struct spi_device *spi, + struct spi_transfer *t) + { +@@ -248,9 +228,6 @@ static int fsl_spi_setup_transfer(struct spi_device *spi, + bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi, + mpc8xxx_spi, + bits_per_word); +- else +- bits_per_word = mspi_apply_qe_mode_quirks(cs, spi, +- bits_per_word); + + if (bits_per_word < 0) + return bits_per_word; +@@ -357,12 +334,44 @@ static int fsl_spi_bufs(struct spi_device *spi, struct spi_transfer *t, + static int fsl_spi_do_one_msg(struct spi_master *master, + struct spi_message *m) + { ++ struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); + struct spi_device *spi = m->spi; + struct spi_transfer *t, *first; + unsigned int cs_change; + const int nsecs = 50; + int status; + ++ /* ++ * In CPU mode, optimize large byte transfers to use larger ++ * bits_per_word values to reduce number of interrupts taken. ++ */ ++ list_for_each_entry(t, &m->transfers, transfer_list) { ++ if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) { ++ if (t->len < 256 || t->bits_per_word != 8) ++ continue; ++ if ((t->len & 3) == 0) ++ t->bits_per_word = 32; ++ else if ((t->len & 1) == 0) ++ t->bits_per_word = 16; ++ } else { ++ /* ++ * CPM/QE uses Little Endian for words > 8 ++ * so transform 16 and 32 bits words into 8 bits ++ * Unfortnatly that doesn't work for LSB so ++ * reject these for now ++ * Note: 32 bits word, LSB works iff ++ * tfcr/rfcr is set to CPMFCR_GBL ++ */ ++ if (m->spi->mode & SPI_LSB_FIRST && t->bits_per_word > 8) ++ return -EINVAL; ++ if (t->bits_per_word == 16 || t->bits_per_word == 32) ++ t->bits_per_word = 8; /* pretend its 8 bits */ ++ if (t->bits_per_word == 8 && t->len >= 256 && ++ (mpc8xxx_spi->flags & SPI_CPM1)) ++ t->bits_per_word = 16; ++ } ++ } ++ + /* Don't allow changes if CS is active */ + first = list_first_entry(&m->transfers, struct spi_transfer, + transfer_list); +@@ -642,8 +651,14 @@ static struct spi_master * fsl_spi_probe(struct device *dev, + if (mpc8xxx_spi->type == TYPE_GRLIB) + fsl_spi_grlib_probe(dev); + +- master->bits_per_word_mask = +- (SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)) & ++ if (mpc8xxx_spi->flags & SPI_CPM_MODE) ++ master->bits_per_word_mask = ++ (SPI_BPW_RANGE_MASK(4, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32)); ++ else ++ master->bits_per_word_mask = ++ (SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)); ++ ++ master->bits_per_word_mask &= + SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word); + + if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) +diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c +index df18d07d544d5..e306de7009295 100644 +--- a/drivers/spi/spi-imx.c ++++ b/drivers/spi/spi-imx.c +@@ -241,6 +241,18 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, + return true; + } + ++/* ++ * Note the number of natively supported chip selects for MX51 is 4. Some ++ * devices may have less actual SS pins but the register map supports 4. When ++ * using gpio chip selects the cs values passed into the macros below can go ++ * outside the range 0 - 3. We therefore need to limit the cs value to avoid ++ * corrupting bits outside the allocated locations. ++ * ++ * The simplest way to do this is to just mask the cs bits to 2 bits. This ++ * still allows all 4 native chip selects to work as well as gpio chip selects ++ * (which can use any of the 4 chip select configurations). ++ */ ++ + #define MX51_ECSPI_CTRL 0x08 + #define MX51_ECSPI_CTRL_ENABLE (1 << 0) + #define MX51_ECSPI_CTRL_XCH (1 << 2) +@@ -249,16 +261,16 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, + #define MX51_ECSPI_CTRL_DRCTL(drctl) ((drctl) << 16) + #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8 + #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 +-#define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18) ++#define MX51_ECSPI_CTRL_CS(cs) ((cs & 3) << 18) + #define MX51_ECSPI_CTRL_BL_OFFSET 20 + #define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20) + + #define MX51_ECSPI_CONFIG 0x0c +-#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0)) +-#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4)) +-#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8)) +-#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs) + 12)) +-#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs) + 20)) ++#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs & 3) + 0)) ++#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs & 3) + 4)) ++#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs & 3) + 8)) ++#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs & 3) + 12)) ++#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs & 3) + 20)) + + #define MX51_ECSPI_INT 0x10 + #define MX51_ECSPI_INT_TEEN (1 << 0) +diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +index 8420bdae1a5cc..8bccaf9ea7009 100644 +--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c ++++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +@@ -61,9 +61,9 @@ static const struct rtl819x_ops rtl819xp_ops = { + }; + + static struct pci_device_id rtl8192_pci_id_tbl[] = { +- {RTL_PCI_DEVICE(0x10ec, 0x8192, rtl819xp_ops)}, +- {RTL_PCI_DEVICE(0x07aa, 0x0044, rtl819xp_ops)}, +- {RTL_PCI_DEVICE(0x07aa, 0x0047, rtl819xp_ops)}, ++ {PCI_DEVICE(0x10ec, 0x8192)}, ++ {PCI_DEVICE(0x07aa, 0x0044)}, ++ {PCI_DEVICE(0x07aa, 0x0047)}, + {} + }; + +diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +index 9d3089cb6a5af..ff9b544edf875 100644 +--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h ++++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +@@ -67,11 +67,6 @@ + #define IS_HARDWARE_TYPE_8192SE(_priv) \ + (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192SE) + +-#define RTL_PCI_DEVICE(vend, dev, cfg) \ +- .vendor = (vend), .device = (dev), \ +- .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \ +- .driver_data = (kernel_ulong_t)&(cfg) +- + #define TOTAL_CAM_ENTRY 32 + #define CAM_CONTENT_COUNT 8 + +diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c +index 8d46bd612888f..3cc3fab510912 100644 +--- a/drivers/tty/serial/8250/8250_core.c ++++ b/drivers/tty/serial/8250/8250_core.c +@@ -1128,6 +1128,7 @@ void serial8250_unregister_port(int line) + uart->port.type = PORT_UNKNOWN; + uart->port.dev = &serial8250_isa_devs->dev; + uart->capabilities = 0; ++ serial8250_init_port(uart); + serial8250_apply_quirks(uart); + uart_add_one_port(&serial8250_reg, &uart->port); + } else { +diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c +index a22a0ed905d74..e80d742932447 100644 +--- a/drivers/tty/serial/8250/8250_pci.c ++++ b/drivers/tty/serial/8250/8250_pci.c +@@ -1651,6 +1651,8 @@ pci_wch_ch38x_setup(struct serial_private *priv, + #define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530 + #define PCI_VENDOR_ID_ADVANTECH 0x13fe + #define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 ++#define PCI_DEVICE_ID_ADVANTECH_PCI1600 0x1600 ++#define PCI_DEVICE_ID_ADVANTECH_PCI1600_1611 0x1611 + #define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 + #define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618 + #define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618 +@@ -3851,6 +3853,9 @@ static SIMPLE_DEV_PM_OPS(pciserial_pm_ops, pciserial_suspend_one, + pciserial_resume_one); + + static const struct pci_device_id serial_pci_tbl[] = { ++ { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI1600, ++ PCI_DEVICE_ID_ADVANTECH_PCI1600_1611, PCI_ANY_ID, 0, 0, ++ pbn_b0_4_921600 }, + /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */ + { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620, + PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0, +diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c +index 7a4e3da549fef..90c89411ea751 100644 +--- a/drivers/usb/core/usb.c ++++ b/drivers/usb/core/usb.c +@@ -209,6 +209,82 @@ int usb_find_common_endpoints_reverse(struct usb_host_interface *alt, + } + EXPORT_SYMBOL_GPL(usb_find_common_endpoints_reverse); + ++/** ++ * usb_find_endpoint() - Given an endpoint address, search for the endpoint's ++ * usb_host_endpoint structure in an interface's current altsetting. ++ * @intf: the interface whose current altsetting should be searched ++ * @ep_addr: the endpoint address (number and direction) to find ++ * ++ * Search the altsetting's list of endpoints for one with the specified address. ++ * ++ * Return: Pointer to the usb_host_endpoint if found, %NULL otherwise. ++ */ ++static const struct usb_host_endpoint *usb_find_endpoint( ++ const struct usb_interface *intf, unsigned int ep_addr) ++{ ++ int n; ++ const struct usb_host_endpoint *ep; ++ ++ n = intf->cur_altsetting->desc.bNumEndpoints; ++ ep = intf->cur_altsetting->endpoint; ++ for (; n > 0; (--n, ++ep)) { ++ if (ep->desc.bEndpointAddress == ep_addr) ++ return ep; ++ } ++ return NULL; ++} ++ ++/** ++ * usb_check_bulk_endpoints - Check whether an interface's current altsetting ++ * contains a set of bulk endpoints with the given addresses. ++ * @intf: the interface whose current altsetting should be searched ++ * @ep_addrs: 0-terminated array of the endpoint addresses (number and ++ * direction) to look for ++ * ++ * Search for endpoints with the specified addresses and check their types. ++ * ++ * Return: %true if all the endpoints are found and are bulk, %false otherwise. ++ */ ++bool usb_check_bulk_endpoints( ++ const struct usb_interface *intf, const u8 *ep_addrs) ++{ ++ const struct usb_host_endpoint *ep; ++ ++ for (; *ep_addrs; ++ep_addrs) { ++ ep = usb_find_endpoint(intf, *ep_addrs); ++ if (!ep || !usb_endpoint_xfer_bulk(&ep->desc)) ++ return false; ++ } ++ return true; ++} ++EXPORT_SYMBOL_GPL(usb_check_bulk_endpoints); ++ ++/** ++ * usb_check_int_endpoints - Check whether an interface's current altsetting ++ * contains a set of interrupt endpoints with the given addresses. ++ * @intf: the interface whose current altsetting should be searched ++ * @ep_addrs: 0-terminated array of the endpoint addresses (number and ++ * direction) to look for ++ * ++ * Search for endpoints with the specified addresses and check their types. ++ * ++ * Return: %true if all the endpoints are found and are interrupt, ++ * %false otherwise. ++ */ ++bool usb_check_int_endpoints( ++ const struct usb_interface *intf, const u8 *ep_addrs) ++{ ++ const struct usb_host_endpoint *ep; ++ ++ for (; *ep_addrs; ++ep_addrs) { ++ ep = usb_find_endpoint(intf, *ep_addrs); ++ if (!ep || !usb_endpoint_xfer_int(&ep->desc)) ++ return false; ++ } ++ return true; ++} ++EXPORT_SYMBOL_GPL(usb_check_int_endpoints); ++ + /** + * usb_find_alt_setting() - Given a configuration, find the alternate setting + * for the given interface. +diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c +index a020d5eafb4a5..ef10a9066267c 100644 +--- a/drivers/usb/misc/sisusbvga/sisusb.c ++++ b/drivers/usb/misc/sisusbvga/sisusb.c +@@ -3015,6 +3015,20 @@ static int sisusb_probe(struct usb_interface *intf, + struct usb_device *dev = interface_to_usbdev(intf); + struct sisusb_usb_data *sisusb; + int retval = 0, i; ++ static const u8 ep_addresses[] = { ++ SISUSB_EP_GFX_IN | USB_DIR_IN, ++ SISUSB_EP_GFX_OUT | USB_DIR_OUT, ++ SISUSB_EP_GFX_BULK_OUT | USB_DIR_OUT, ++ SISUSB_EP_GFX_LBULK_OUT | USB_DIR_OUT, ++ SISUSB_EP_BRIDGE_IN | USB_DIR_IN, ++ SISUSB_EP_BRIDGE_OUT | USB_DIR_OUT, ++ 0}; ++ ++ /* Are the expected endpoints present? */ ++ if (!usb_check_bulk_endpoints(intf, ep_addresses)) { ++ dev_err(&intf->dev, "Invalid USB2VGA device\n"); ++ return -EINVAL; ++ } + + dev_info(&dev->dev, "USB2VGA dongle found at address %d\n", + dev->devnum); +diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c +index fd5398efce412..028523621f5c5 100644 +--- a/drivers/usb/storage/scsiglue.c ++++ b/drivers/usb/storage/scsiglue.c +@@ -408,22 +408,25 @@ static DEF_SCSI_QCMD(queuecommand) + ***********************************************************************/ + + /* Command timeout and abort */ +-static int command_abort(struct scsi_cmnd *srb) ++static int command_abort_matching(struct us_data *us, struct scsi_cmnd *srb_match) + { +- struct us_data *us = host_to_us(srb->device->host); +- +- usb_stor_dbg(us, "%s called\n", __func__); +- + /* + * us->srb together with the TIMED_OUT, RESETTING, and ABORTING + * bits are protected by the host lock. + */ + scsi_lock(us_to_host(us)); + +- /* Is this command still active? */ +- if (us->srb != srb) { ++ /* is there any active pending command to abort ? */ ++ if (!us->srb) { + scsi_unlock(us_to_host(us)); + usb_stor_dbg(us, "-- nothing to abort\n"); ++ return SUCCESS; ++ } ++ ++ /* Does the command match the passed srb if any ? */ ++ if (srb_match && us->srb != srb_match) { ++ scsi_unlock(us_to_host(us)); ++ usb_stor_dbg(us, "-- pending command mismatch\n"); + return FAILED; + } + +@@ -446,6 +449,14 @@ static int command_abort(struct scsi_cmnd *srb) + return SUCCESS; + } + ++static int command_abort(struct scsi_cmnd *srb) ++{ ++ struct us_data *us = host_to_us(srb->device->host); ++ ++ usb_stor_dbg(us, "%s called\n", __func__); ++ return command_abort_matching(us, srb); ++} ++ + /* + * This invokes the transport reset mechanism to reset the state of the + * device +@@ -457,6 +468,9 @@ static int device_reset(struct scsi_cmnd *srb) + + usb_stor_dbg(us, "%s called\n", __func__); + ++ /* abort any pending command before reset */ ++ command_abort_matching(us, NULL); ++ + /* lock the device pointers and do the reset */ + mutex_lock(&(us->dev_mutex)); + result = us->transport_reset(us); +diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c +index b13d03aba791a..e472ed057c175 100644 +--- a/drivers/xen/pvcalls-back.c ++++ b/drivers/xen/pvcalls-back.c +@@ -338,8 +338,10 @@ static struct sock_mapping *pvcalls_new_active_socket( + void *page; + + map = kzalloc(sizeof(*map), GFP_KERNEL); +- if (map == NULL) ++ if (map == NULL) { ++ sock_release(sock); + return NULL; ++ } + + map->fedata = fedata; + map->sock = sock; +@@ -431,10 +433,8 @@ static int pvcalls_back_connect(struct xenbus_device *dev, + req->u.connect.ref, + req->u.connect.evtchn, + sock); +- if (!map) { ++ if (!map) + ret = -EFAULT; +- sock_release(sock); +- } + + out: + rsp = RING_GET_RESPONSE(&fedata->ring, fedata->ring.rsp_prod_pvt++); +@@ -575,7 +575,6 @@ static void __pvcalls_back_accept(struct work_struct *work) + sock); + if (!map) { + ret = -EFAULT; +- sock_release(sock); + goto out_error; + } + +diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c +index 29ed1688a1d3a..e12fa3a723db5 100644 +--- a/fs/ceph/snap.c ++++ b/fs/ceph/snap.c +@@ -959,6 +959,19 @@ skip_inode: + continue; + adjust_snap_realm_parent(mdsc, child, realm->ino); + } ++ } else { ++ /* ++ * In the non-split case both 'num_split_inos' and ++ * 'num_split_realms' should be 0, making this a no-op. ++ * However the MDS happens to populate 'split_realms' list ++ * in one of the UPDATE op cases by mistake. ++ * ++ * Skip both lists just in case to ensure that 'p' is ++ * positioned at the start of realm info, as expected by ++ * ceph_update_snap_trace(). ++ */ ++ p += sizeof(u64) * num_split_inos; ++ p += sizeof(u64) * num_split_realms; + } + + /* +diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h +index 032295e1d3865..b500fed96a692 100644 +--- a/fs/ext2/ext2.h ++++ b/fs/ext2/ext2.h +@@ -177,6 +177,7 @@ static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb) + #define EXT2_MIN_BLOCK_SIZE 1024 + #define EXT2_MAX_BLOCK_SIZE 4096 + #define EXT2_MIN_BLOCK_LOG_SIZE 10 ++#define EXT2_MAX_BLOCK_LOG_SIZE 16 + #define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize) + #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) + #define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) +diff --git a/fs/ext2/super.c b/fs/ext2/super.c +index 5f7079b65426c..7ca9fb0bfc324 100644 +--- a/fs/ext2/super.c ++++ b/fs/ext2/super.c +@@ -965,6 +965,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) + goto failed_mount; + } + ++ if (le32_to_cpu(es->s_log_block_size) > ++ (EXT2_MAX_BLOCK_LOG_SIZE - BLOCK_SIZE_BITS)) { ++ ext2_msg(sb, KERN_ERR, ++ "Invalid log block size: %u", ++ le32_to_cpu(es->s_log_block_size)); ++ goto failed_mount; ++ } + blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size); + + if (sbi->s_mount_opt & EXT2_MOUNT_DAX) { +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index d9f2fde2e3e92..ce21da3f437f0 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -3116,6 +3116,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, + struct ext4_allocation_request *ar) + { + struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); ++ struct ext4_super_block *es = sbi->s_es; + int bsbits, max; + ext4_lblk_t end; + loff_t size, start_off; +@@ -3296,18 +3297,21 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, + ac->ac_g_ex.fe_len = EXT4_NUM_B2C(sbi, size); + + /* define goal start in order to merge */ +- if (ar->pright && (ar->lright == (start + size))) { ++ if (ar->pright && (ar->lright == (start + size)) && ++ ar->pright >= size && ++ ar->pright - size >= le32_to_cpu(es->s_first_data_block)) { + /* merge to the right */ + ext4_get_group_no_and_offset(ac->ac_sb, ar->pright - size, +- &ac->ac_f_ex.fe_group, +- &ac->ac_f_ex.fe_start); ++ &ac->ac_g_ex.fe_group, ++ &ac->ac_g_ex.fe_start); + ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL; + } +- if (ar->pleft && (ar->lleft + 1 == start)) { ++ if (ar->pleft && (ar->lleft + 1 == start) && ++ ar->pleft + 1 < ext4_blocks_count(es)) { + /* merge to the left */ + ext4_get_group_no_and_offset(ac->ac_sb, ar->pleft + 1, +- &ac->ac_f_ex.fe_group, +- &ac->ac_f_ex.fe_start); ++ &ac->ac_g_ex.fe_group, ++ &ac->ac_g_ex.fe_start); + ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL; + } + +@@ -3399,6 +3403,7 @@ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac, + BUG_ON(start < pa->pa_pstart); + BUG_ON(end > pa->pa_pstart + EXT4_C2B(sbi, pa->pa_len)); + BUG_ON(pa->pa_free < len); ++ BUG_ON(ac->ac_b_ex.fe_len <= 0); + pa->pa_free -= len; + + mb_debug(1, "use %llu/%u from inode pa %p\n", start, len, pa); +@@ -3703,10 +3708,8 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) + return -ENOMEM; + + if (ac->ac_b_ex.fe_len < ac->ac_g_ex.fe_len) { +- int winl; +- int wins; +- int win; +- int offs; ++ int new_bex_start; ++ int new_bex_end; + + /* we can't allocate as much as normalizer wants. + * so, found space must get proper lstart +@@ -3714,26 +3717,40 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) + BUG_ON(ac->ac_g_ex.fe_logical > ac->ac_o_ex.fe_logical); + BUG_ON(ac->ac_g_ex.fe_len < ac->ac_o_ex.fe_len); + +- /* we're limited by original request in that +- * logical block must be covered any way +- * winl is window we can move our chunk within */ +- winl = ac->ac_o_ex.fe_logical - ac->ac_g_ex.fe_logical; ++ /* ++ * Use the below logic for adjusting best extent as it keeps ++ * fragmentation in check while ensuring logical range of best ++ * extent doesn't overflow out of goal extent: ++ * ++ * 1. Check if best ex can be kept at end of goal and still ++ * cover original start ++ * 2. Else, check if best ex can be kept at start of goal and ++ * still cover original start ++ * 3. Else, keep the best ex at start of original request. ++ */ ++ new_bex_end = ac->ac_g_ex.fe_logical + ++ EXT4_C2B(sbi, ac->ac_g_ex.fe_len); ++ new_bex_start = new_bex_end - EXT4_C2B(sbi, ac->ac_b_ex.fe_len); ++ if (ac->ac_o_ex.fe_logical >= new_bex_start) ++ goto adjust_bex; + +- /* also, we should cover whole original request */ +- wins = EXT4_C2B(sbi, ac->ac_b_ex.fe_len - ac->ac_o_ex.fe_len); ++ new_bex_start = ac->ac_g_ex.fe_logical; ++ new_bex_end = ++ new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len); ++ if (ac->ac_o_ex.fe_logical < new_bex_end) ++ goto adjust_bex; + +- /* the smallest one defines real window */ +- win = min(winl, wins); ++ new_bex_start = ac->ac_o_ex.fe_logical; ++ new_bex_end = ++ new_bex_start + EXT4_C2B(sbi, ac->ac_b_ex.fe_len); + +- offs = ac->ac_o_ex.fe_logical % +- EXT4_C2B(sbi, ac->ac_b_ex.fe_len); +- if (offs && offs < win) +- win = offs; ++adjust_bex: ++ ac->ac_b_ex.fe_logical = new_bex_start; + +- ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical - +- EXT4_NUM_B2C(sbi, win); + BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical); + BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len); ++ BUG_ON(new_bex_end > (ac->ac_g_ex.fe_logical + ++ EXT4_C2B(sbi, ac->ac_g_ex.fe_len))); + } + + /* preallocation can change ac_b_ex, thus we store actually +diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c +index f1844af4005b6..4838e26c06f74 100644 +--- a/fs/gfs2/glops.c ++++ b/fs/gfs2/glops.c +@@ -333,6 +333,7 @@ static int inode_go_demote_ok(const struct gfs2_glock *gl) + + static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) + { ++ struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + const struct gfs2_dinode *str = buf; + struct timespec atime; + u16 height, depth; +@@ -372,7 +373,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) + /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */ + gfs2_set_inode_flags(&ip->i_inode); + height = be16_to_cpu(str->di_height); +- if (unlikely(height > GFS2_MAX_META_HEIGHT)) ++ if (unlikely(height > sdp->sd_max_height)) + goto corrupt; + ip->i_height = (u8)height; + +diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c +index ccb2a94c2032a..4924a489c8ac0 100644 +--- a/fs/hfsplus/inode.c ++++ b/fs/hfsplus/inode.c +@@ -488,7 +488,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + if (type == HFSPLUS_FOLDER) { + struct hfsplus_cat_folder *folder = &entry.folder; + +- WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_folder)); ++ if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) { ++ pr_err("bad catalog folder entry\n"); ++ res = -EIO; ++ goto out; ++ } + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_folder)); + hfsplus_get_perms(inode, &folder->permissions, 1); +@@ -508,7 +512,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + } else if (type == HFSPLUS_FILE) { + struct hfsplus_cat_file *file = &entry.file; + +- WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_file)); ++ if (fd->entrylength < sizeof(struct hfsplus_cat_file)) { ++ pr_err("bad catalog file entry\n"); ++ res = -EIO; ++ goto out; ++ } + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, + sizeof(struct hfsplus_cat_file)); + +@@ -539,6 +547,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) + pr_err("bad catalog entry used to create inode\n"); + res = -EIO; + } ++out: + return res; + } + +@@ -547,6 +556,7 @@ int hfsplus_cat_write_inode(struct inode *inode) + struct inode *main_inode = inode; + struct hfs_find_data fd; + hfsplus_cat_entry entry; ++ int res = 0; + + if (HFSPLUS_IS_RSRC(inode)) + main_inode = HFSPLUS_I(inode)->rsrc_inode; +@@ -565,7 +575,11 @@ int hfsplus_cat_write_inode(struct inode *inode) + if (S_ISDIR(main_inode->i_mode)) { + struct hfsplus_cat_folder *folder = &entry.folder; + +- WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_folder)); ++ if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) { ++ pr_err("bad catalog folder entry\n"); ++ res = -EIO; ++ goto out; ++ } + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, + sizeof(struct hfsplus_cat_folder)); + /* simple node checks? */ +@@ -590,7 +604,11 @@ int hfsplus_cat_write_inode(struct inode *inode) + } else { + struct hfsplus_cat_file *file = &entry.file; + +- WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_file)); ++ if (fd.entrylength < sizeof(struct hfsplus_cat_file)) { ++ pr_err("bad catalog file entry\n"); ++ res = -EIO; ++ goto out; ++ } + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, + sizeof(struct hfsplus_cat_file)); + hfsplus_inode_write_fork(inode, &file->data_fork); +@@ -611,5 +629,5 @@ int hfsplus_cat_write_inode(struct inode *inode) + set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags); + out: + hfs_find_exit(&fd); +- return 0; ++ return res; + } +diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c +index 39ef2d336265e..9c7971c196c9c 100644 +--- a/fs/nilfs2/inode.c ++++ b/fs/nilfs2/inode.c +@@ -939,6 +939,7 @@ void nilfs_evict_inode(struct inode *inode) + struct nilfs_transaction_info ti; + struct super_block *sb = inode->i_sb; + struct nilfs_inode_info *ii = NILFS_I(inode); ++ struct the_nilfs *nilfs; + int ret; + + if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) { +@@ -951,6 +952,23 @@ void nilfs_evict_inode(struct inode *inode) + + truncate_inode_pages_final(&inode->i_data); + ++ nilfs = sb->s_fs_info; ++ if (unlikely(sb_rdonly(sb) || !nilfs->ns_writer)) { ++ /* ++ * If this inode is about to be disposed after the file system ++ * has been degraded to read-only due to file system corruption ++ * or after the writer has been detached, do not make any ++ * changes that cause writes, just clear it. ++ * Do this check after read-locking ns_segctor_sem by ++ * nilfs_transaction_begin() in order to avoid a race with ++ * the writer detach operation. ++ */ ++ clear_inode(inode); ++ nilfs_clear_inode(inode); ++ nilfs_transaction_abort(sb); ++ return; ++ } ++ + /* TODO: some of the following operations may fail. */ + nilfs_truncate_bmap(ii, 0); + nilfs_mark_inode_dirty(inode); +diff --git a/fs/statfs.c b/fs/statfs.c +index ca1084cbe03cf..e6ceb3e8774f6 100644 +--- a/fs/statfs.c ++++ b/fs/statfs.c +@@ -114,6 +114,7 @@ static int do_statfs_native(struct kstatfs *st, struct statfs __user *p) + if (sizeof(buf) == sizeof(*st)) + memcpy(&buf, st, sizeof(*st)); + else { ++ memset(&buf, 0, sizeof(buf)); + if (sizeof buf.f_blocks == 4) { + if ((st->f_blocks | st->f_bfree | st->f_bavail | + st->f_bsize | st->f_frsize) & +@@ -142,7 +143,6 @@ static int do_statfs_native(struct kstatfs *st, struct statfs __user *p) + buf.f_namelen = st->f_namelen; + buf.f_frsize = st->f_frsize; + buf.f_flags = st->f_flags; +- memset(buf.f_spare, 0, sizeof(buf.f_spare)); + } + if (copy_to_user(p, &buf, sizeof(buf))) + return -EFAULT; +@@ -155,6 +155,7 @@ static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p) + if (sizeof(buf) == sizeof(*st)) + memcpy(&buf, st, sizeof(*st)); + else { ++ memset(&buf, 0, sizeof(buf)); + buf.f_type = st->f_type; + buf.f_bsize = st->f_bsize; + buf.f_blocks = st->f_blocks; +@@ -166,7 +167,6 @@ static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p) + buf.f_namelen = st->f_namelen; + buf.f_frsize = st->f_frsize; + buf.f_flags = st->f_flags; +- memset(buf.f_spare, 0, sizeof(buf.f_spare)); + } + if (copy_to_user(p, &buf, sizeof(buf))) + return -EFAULT; +diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h +index 534a8080c6a3b..2fd8a204ab81b 100644 +--- a/include/linux/power/bq27xxx_battery.h ++++ b/include/linux/power/bq27xxx_battery.h +@@ -61,6 +61,7 @@ struct bq27xxx_device_info { + struct bq27xxx_access_methods bus; + struct bq27xxx_reg_cache cache; + int charge_design_full; ++ bool removed; + unsigned long last_update; + struct delayed_work work; + struct power_supply *bat; +diff --git a/include/linux/sched/task_stack.h b/include/linux/sched/task_stack.h +index 3461beb89b040..62d1cd4db27af 100644 +--- a/include/linux/sched/task_stack.h ++++ b/include/linux/sched/task_stack.h +@@ -23,7 +23,7 @@ static inline void *task_stack_page(const struct task_struct *task) + + #define setup_thread_stack(new,old) do { } while(0) + +-static inline unsigned long *end_of_stack(const struct task_struct *task) ++static __always_inline unsigned long *end_of_stack(const struct task_struct *task) + { + #ifdef CONFIG_STACK_GROWSUP + return (unsigned long *)((unsigned long)task->stack + THREAD_SIZE) - 1; +diff --git a/include/linux/usb.h b/include/linux/usb.h +index b2c35d3b83726..89f9865921cba 100644 +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -279,6 +279,11 @@ void usb_put_intf(struct usb_interface *intf); + #define USB_MAXINTERFACES 32 + #define USB_MAXIADS (USB_MAXINTERFACES/2) + ++bool usb_check_bulk_endpoints( ++ const struct usb_interface *intf, const u8 *ep_addrs); ++bool usb_check_int_endpoints( ++ const struct usb_interface *intf, const u8 *ep_addrs); ++ + /* + * USB Resume Timer: Every Host controller driver should drive the resume + * signalling on the bus for the amount of time defined by this macro. +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index 2db486e9724c6..0d625ff7841ad 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -195,14 +195,13 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type) + } + + int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest); +-unsigned int nft_parse_register(const struct nlattr *attr); + int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg); + +-int nft_validate_register_load(enum nft_registers reg, unsigned int len); +-int nft_validate_register_store(const struct nft_ctx *ctx, +- enum nft_registers reg, +- const struct nft_data *data, +- enum nft_data_types type, unsigned int len); ++int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len); ++int nft_parse_register_store(const struct nft_ctx *ctx, ++ const struct nlattr *attr, u8 *dreg, ++ const struct nft_data *data, ++ enum nft_data_types type, unsigned int len); + + /** + * struct nft_userdata - user defined data associated with an object +@@ -230,6 +229,10 @@ struct nft_set_elem { + u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)]; + struct nft_data val; + } key; ++ union { ++ u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)]; ++ struct nft_data val; ++ } data; + void *priv; + }; + +@@ -378,6 +381,7 @@ void nft_unregister_set(struct nft_set_type *type); + * + * @list: table set list node + * @bindings: list of set bindings ++ * @table: table this set belongs to + * @name: name of the set + * @ktype: key type (numeric type defined by userspace, not used in the kernel) + * @dtype: data type (verdict or numeric type defined by userspace) +@@ -401,6 +405,7 @@ void nft_unregister_set(struct nft_set_type *type); + struct nft_set { + struct list_head list; + struct list_head bindings; ++ struct nft_table *table; + char *name; + u32 ktype; + u32 dtype; +diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h +index ea5aab568be83..98bd13fbfa896 100644 +--- a/include/net/netfilter/nf_tables_core.h ++++ b/include/net/netfilter/nf_tables_core.h +@@ -14,9 +14,17 @@ extern struct nft_expr_type nft_range_type; + int nf_tables_core_module_init(void); + void nf_tables_core_module_exit(void); + ++struct nft_bitwise_fast_expr { ++ u32 mask; ++ u32 xor; ++ u8 sreg; ++ u8 dreg; ++}; ++ + struct nft_cmp_fast_expr { + u32 data; +- enum nft_registers sreg:8; ++ u32 mask; ++ u8 sreg; + u8 len; + }; + +@@ -36,14 +44,14 @@ struct nft_payload { + enum nft_payload_bases base:8; + u8 offset; + u8 len; +- enum nft_registers dreg:8; ++ u8 dreg; + }; + + struct nft_payload_set { + enum nft_payload_bases base:8; + u8 offset; + u8 len; +- enum nft_registers sreg:8; ++ u8 sreg; + u8 csum_type; + u8 csum_offset; + u8 csum_flags; +diff --git a/include/net/netfilter/nft_fib.h b/include/net/netfilter/nft_fib.h +index a88f92737308d..1f87267395291 100644 +--- a/include/net/netfilter/nft_fib.h ++++ b/include/net/netfilter/nft_fib.h +@@ -3,7 +3,7 @@ + #define _NFT_FIB_H_ + + struct nft_fib { +- enum nft_registers dreg:8; ++ u8 dreg; + u8 result; + u32 flags; + }; +diff --git a/include/net/netfilter/nft_masq.h b/include/net/netfilter/nft_masq.h +index e51ab3815797b..e69a8277b70b3 100644 +--- a/include/net/netfilter/nft_masq.h ++++ b/include/net/netfilter/nft_masq.h +@@ -4,8 +4,8 @@ + + struct nft_masq { + u32 flags; +- enum nft_registers sreg_proto_min:8; +- enum nft_registers sreg_proto_max:8; ++ u8 sreg_proto_min; ++ u8 sreg_proto_max; + }; + + extern const struct nla_policy nft_masq_policy[]; +diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h +index 5c69e9b093887..f64b8197c8074 100644 +--- a/include/net/netfilter/nft_meta.h ++++ b/include/net/netfilter/nft_meta.h +@@ -5,8 +5,8 @@ + struct nft_meta { + enum nft_meta_keys key:8; + union { +- enum nft_registers dreg:8; +- enum nft_registers sreg:8; ++ u8 dreg; ++ u8 sreg; + }; + }; + +diff --git a/include/net/netfilter/nft_redir.h b/include/net/netfilter/nft_redir.h +index 4a970737c03c8..2b4036c94cb3e 100644 +--- a/include/net/netfilter/nft_redir.h ++++ b/include/net/netfilter/nft_redir.h +@@ -3,8 +3,8 @@ + #define _NFT_REDIR_H_ + + struct nft_redir { +- enum nft_registers sreg_proto_min:8; +- enum nft_registers sreg_proto_max:8; ++ u8 sreg_proto_min; ++ u8 sreg_proto_max; + u16 flags; + }; + +diff --git a/include/net/sock.h b/include/net/sock.h +index f6d0d96419b1e..ee1a2217a98c0 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -2317,7 +2317,7 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, + __sock_recv_ts_and_drops(msg, sk, skb); + else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP))) + sock_write_timestamp(sk, skb->tstamp); +- else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP)) ++ else if (unlikely(sock_read_timestamp(sk) == SK_DEFAULT_STAMP)) + sock_write_timestamp(sk, 0); + } + +diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h +index 49b6997c32550..c7bb18ea49623 100644 +--- a/include/uapi/linux/netfilter/nf_tables.h ++++ b/include/uapi/linux/netfilter/nf_tables.h +@@ -258,7 +258,7 @@ enum nft_rule_compat_attributes { + * @NFT_SET_INTERVAL: set contains intervals + * @NFT_SET_MAP: set is used as a dictionary + * @NFT_SET_TIMEOUT: set uses timeouts +- * @NFT_SET_EVAL: set contains expressions for evaluation ++ * @NFT_SET_EVAL: set can be updated from the evaluation path + * @NFT_SET_OBJECT: set contains stateful objects + */ + enum nft_set_flags { +diff --git a/lib/cpu_rmap.c b/lib/cpu_rmap.c +index f610b2a10b3ed..f52389054a24f 100644 +--- a/lib/cpu_rmap.c ++++ b/lib/cpu_rmap.c +@@ -235,7 +235,8 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap) + + for (index = 0; index < rmap->used; index++) { + glue = rmap->obj[index]; +- irq_set_affinity_notifier(glue->notify.irq, NULL); ++ if (glue) ++ irq_set_affinity_notifier(glue->notify.irq, NULL); + } + + cpu_rmap_put(rmap); +@@ -271,6 +272,7 @@ static void irq_cpu_rmap_release(struct kref *ref) + container_of(ref, struct irq_glue, notify.kref); + + cpu_rmap_put(glue->rmap); ++ glue->rmap->obj[glue->index] = NULL; + kfree(glue); + } + +@@ -300,6 +302,7 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq) + rc = irq_set_affinity_notifier(irq, &glue->notify); + if (rc) { + cpu_rmap_put(glue->rmap); ++ rmap->obj[glue->index] = NULL; + kfree(glue); + } + return rc; +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index e871d3b27c479..c436c9973455b 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -115,8 +115,8 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, + * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING + * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... + */ +- if (veth->h_vlan_proto != vlan->vlan_proto || +- vlan->flags & VLAN_FLAG_REORDER_HDR) { ++ if (vlan->flags & VLAN_FLAG_REORDER_HDR || ++ veth->h_vlan_proto != vlan->vlan_proto) { + u16 vlan_tci; + vlan_tci = vlan->vlan_id; + vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb->priority); +diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c +index 6f47cb69775d6..b0bb4cf52a7ee 100644 +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -4392,7 +4392,6 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, + + chan = l2cap_get_chan_by_scid(conn, scid); + if (!chan) { +- mutex_unlock(&conn->chan_lock); + return 0; + } + +diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c +index bb63c9aed55d2..985ff136b674c 100644 +--- a/net/bridge/netfilter/nft_meta_bridge.c ++++ b/net/bridge/netfilter/nft_meta_bridge.c +@@ -65,9 +65,8 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx, + return nft_meta_get_init(ctx, expr, tb); + } + +- priv->dreg = nft_parse_register(tb[NFTA_META_DREG]); +- return nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, len); ++ return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg, ++ NULL, NFT_DATA_VALUE, len); + } + + static struct nft_expr_type nft_meta_bridge_type; +diff --git a/net/core/dev.c b/net/core/dev.c +index 86f762a1cf7ac..a4d68da682322 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2165,6 +2165,8 @@ int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask, + struct xps_map *map, *new_map; + bool active = false; + ++ WARN_ON_ONCE(index >= dev->num_tx_queues); ++ + if (dev->num_tc) { + num_tc = dev->num_tc; + tc = netdev_txq_to_tc(dev, index); +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 71827da47274c..6b6309ec7b1bb 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -4421,8 +4421,10 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, + } else { + skb = skb_clone(orig_skb, GFP_ATOMIC); + +- if (skb_orphan_frags_rx(skb, GFP_ATOMIC)) ++ if (skb_orphan_frags_rx(skb, GFP_ATOMIC)) { ++ kfree_skb(skb); + return; ++ } + } + if (!skb) + return; +diff --git a/net/ipv4/netfilter/nft_dup_ipv4.c b/net/ipv4/netfilter/nft_dup_ipv4.c +index 0af3d8df70dd7..157bca240edce 100644 +--- a/net/ipv4/netfilter/nft_dup_ipv4.c ++++ b/net/ipv4/netfilter/nft_dup_ipv4.c +@@ -16,8 +16,8 @@ + #include <net/netfilter/ipv4/nf_dup_ipv4.h> + + struct nft_dup_ipv4 { +- enum nft_registers sreg_addr:8; +- enum nft_registers sreg_dev:8; ++ u8 sreg_addr; ++ u8 sreg_dev; + }; + + static void nft_dup_ipv4_eval(const struct nft_expr *expr, +@@ -43,16 +43,16 @@ static int nft_dup_ipv4_init(const struct nft_ctx *ctx, + if (tb[NFTA_DUP_SREG_ADDR] == NULL) + return -EINVAL; + +- priv->sreg_addr = nft_parse_register(tb[NFTA_DUP_SREG_ADDR]); +- err = nft_validate_register_load(priv->sreg_addr, sizeof(struct in_addr)); ++ err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr, ++ sizeof(struct in_addr)); + if (err < 0) + return err; + +- if (tb[NFTA_DUP_SREG_DEV] != NULL) { +- priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]); +- return nft_validate_register_load(priv->sreg_dev, sizeof(int)); +- } +- return 0; ++ if (tb[NFTA_DUP_SREG_DEV]) ++ err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], ++ &priv->sreg_dev, sizeof(int)); ++ ++ return err; + } + + static int nft_dup_ipv4_dump(struct sk_buff *skb, const struct nft_expr *expr) +diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c +index 305e2ed730bf4..d57d62efa6bdd 100644 +--- a/net/ipv6/exthdrs_core.c ++++ b/net/ipv6/exthdrs_core.c +@@ -142,6 +142,8 @@ int ipv6_find_tlv(const struct sk_buff *skb, int offset, int type) + optlen = 1; + break; + default: ++ if (len < 2) ++ goto bad; + optlen = nh[offset + 1] + 2; + if (optlen > len) + goto bad; +diff --git a/net/ipv6/netfilter/nft_dup_ipv6.c b/net/ipv6/netfilter/nft_dup_ipv6.c +index d8b5b60b7d531..d8bb7c85287cb 100644 +--- a/net/ipv6/netfilter/nft_dup_ipv6.c ++++ b/net/ipv6/netfilter/nft_dup_ipv6.c +@@ -16,8 +16,8 @@ + #include <net/netfilter/ipv6/nf_dup_ipv6.h> + + struct nft_dup_ipv6 { +- enum nft_registers sreg_addr:8; +- enum nft_registers sreg_dev:8; ++ u8 sreg_addr; ++ u8 sreg_dev; + }; + + static void nft_dup_ipv6_eval(const struct nft_expr *expr, +@@ -41,16 +41,16 @@ static int nft_dup_ipv6_init(const struct nft_ctx *ctx, + if (tb[NFTA_DUP_SREG_ADDR] == NULL) + return -EINVAL; + +- priv->sreg_addr = nft_parse_register(tb[NFTA_DUP_SREG_ADDR]); +- err = nft_validate_register_load(priv->sreg_addr, sizeof(struct in6_addr)); ++ err = nft_parse_register_load(tb[NFTA_DUP_SREG_ADDR], &priv->sreg_addr, ++ sizeof(struct in6_addr)); + if (err < 0) + return err; + +- if (tb[NFTA_DUP_SREG_DEV] != NULL) { +- priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]); +- return nft_validate_register_load(priv->sreg_dev, sizeof(int)); +- } +- return 0; ++ if (tb[NFTA_DUP_SREG_DEV]) ++ err = nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], ++ &priv->sreg_dev, sizeof(int)); ++ ++ return err; + } + + static int nft_dup_ipv6_dump(struct sk_buff *skb, const struct nft_expr *expr) +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 09a0ea651f577..49813e6d05ed7 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -1950,7 +1950,8 @@ static u32 gen_reqid(struct net *net) + } + + static int +-parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) ++parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_policy *pol, ++ struct sadb_x_ipsecrequest *rq) + { + struct net *net = xp_net(xp); + struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; +@@ -1968,9 +1969,12 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) + if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0) + return -EINVAL; + t->mode = mode; +- if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE) ++ if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_USE) { ++ if ((mode == XFRM_MODE_TUNNEL || mode == XFRM_MODE_BEET) && ++ pol->sadb_x_policy_dir == IPSEC_DIR_OUTBOUND) ++ return -EINVAL; + t->optional = 1; +- else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) { ++ } else if (rq->sadb_x_ipsecrequest_level == IPSEC_LEVEL_UNIQUE) { + t->reqid = rq->sadb_x_ipsecrequest_reqid; + if (t->reqid > IPSEC_MANUAL_REQID_MAX) + t->reqid = 0; +@@ -2012,7 +2016,7 @@ parse_ipsecrequests(struct xfrm_policy *xp, struct sadb_x_policy *pol) + rq->sadb_x_ipsecrequest_len < sizeof(*rq)) + return -EINVAL; + +- if ((err = parse_ipsecrequest(xp, rq)) < 0) ++ if ((err = parse_ipsecrequest(xp, pol, rq)) < 0) + return err; + len -= rq->sadb_x_ipsecrequest_len; + rq = (void*)((u8*)rq + rq->sadb_x_ipsecrequest_len); +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index c683a45b8ae53..241a3032d0e66 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -2475,6 +2475,7 @@ err1: + } + + static struct nft_rule *nft_rule_lookup_byid(const struct net *net, ++ const struct nft_chain *chain, + const struct nlattr *nla) + { + u32 id = ntohl(nla_get_be32(nla)); +@@ -2484,6 +2485,7 @@ static struct nft_rule *nft_rule_lookup_byid(const struct net *net, + struct nft_rule *rule = nft_trans_rule(trans); + + if (trans->msg_type == NFT_MSG_NEWRULE && ++ trans->ctx.chain == chain && + id == nft_trans_rule_id(trans)) + return rule; + } +@@ -2530,7 +2532,7 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk, + + err = nft_delrule(&ctx, rule); + } else if (nla[NFTA_RULE_ID]) { +- rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]); ++ rule = nft_rule_lookup_byid(net, chain, nla[NFTA_RULE_ID]); + if (IS_ERR(rule)) + return PTR_ERR(rule); + +@@ -2744,6 +2746,7 @@ static struct nft_set *nf_tables_set_lookup(const struct nft_table *table, + } + + static struct nft_set *nf_tables_set_lookup_byid(const struct net *net, ++ const struct nft_table *table, + const struct nlattr *nla, + u8 genmask) + { +@@ -2755,6 +2758,7 @@ static struct nft_set *nf_tables_set_lookup_byid(const struct net *net, + struct nft_set *set = nft_trans_set(trans); + + if (id == nft_trans_set_id(trans) && ++ set->table == table && + nft_active_genmask(set, genmask)) + return set; + } +@@ -2775,7 +2779,7 @@ struct nft_set *nft_set_lookup(const struct net *net, + if (!nla_set_id) + return set; + +- set = nf_tables_set_lookup_byid(net, nla_set_id, genmask); ++ set = nf_tables_set_lookup_byid(net, table, nla_set_id, genmask); + } + return set; + } +@@ -3270,6 +3274,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, + } + + INIT_LIST_HEAD(&set->bindings); ++ set->table = table; + set->ops = ops; + set->ktype = ktype; + set->klen = desc.klen; +@@ -3349,6 +3354,12 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk, + return nft_delset(&ctx, set); + } + ++static int nft_validate_register_store(const struct nft_ctx *ctx, ++ enum nft_registers reg, ++ const struct nft_data *data, ++ enum nft_data_types type, ++ unsigned int len); ++ + static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx, + struct nft_set *set, + const struct nft_set_iter *iter, +@@ -3730,6 +3741,24 @@ static int nf_tables_dump_set_done(struct netlink_callback *cb) + return 0; + } + ++static int nft_setelem_parse_key(struct nft_ctx *ctx, struct nft_set *set, ++ struct nft_data *key, struct nlattr *attr) ++{ ++ struct nft_data_desc desc; ++ int err; ++ ++ err = nft_data_init(ctx, key, NFT_DATA_VALUE_MAXLEN, &desc, attr); ++ if (err < 0) ++ return err; ++ ++ if (desc.type != NFT_DATA_VALUE || desc.len != set->klen) { ++ nft_data_release(key, desc.type); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static int nf_tables_getsetelem(struct net *net, struct sock *nlsk, + struct sk_buff *skb, const struct nlmsghdr *nlh, + const struct nlattr * const nla[], +@@ -3930,19 +3959,44 @@ static int nft_setelem_parse_flags(const struct nft_set *set, + return 0; + } + ++static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set, ++ struct nft_data_desc *desc, ++ struct nft_data *data, ++ struct nlattr *attr) ++{ ++ u32 dtype; ++ int err; ++ ++ err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr); ++ if (err < 0) ++ return err; ++ ++ if (set->dtype == NFT_DATA_VERDICT) ++ dtype = NFT_DATA_VERDICT; ++ else ++ dtype = NFT_DATA_VALUE; ++ ++ if (dtype != desc->type || ++ set->dlen != desc->len) { ++ nft_data_release(data, desc->type); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + const struct nlattr *attr, u32 nlmsg_flags) + { + struct nlattr *nla[NFTA_SET_ELEM_MAX + 1]; + u8 genmask = nft_genmask_next(ctx->net); +- struct nft_data_desc d1, d2; + struct nft_set_ext_tmpl tmpl; + struct nft_set_ext *ext, *ext2; + struct nft_set_elem elem; + struct nft_set_binding *binding; + struct nft_object *obj = NULL; + struct nft_userdata *udata; +- struct nft_data data; ++ struct nft_data_desc desc; + enum nft_registers dreg; + struct nft_trans *trans; + u32 flags = 0; +@@ -3994,15 +4048,12 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + timeout = set->timeout; + } + +- err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1, +- nla[NFTA_SET_ELEM_KEY]); ++ err = nft_setelem_parse_key(ctx, set, &elem.key.val, ++ nla[NFTA_SET_ELEM_KEY]); + if (err < 0) + goto err1; +- err = -EINVAL; +- if (d1.type != NFT_DATA_VALUE || d1.len != set->klen) +- goto err2; + +- nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len); ++ nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen); + if (timeout > 0) { + nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION); + if (timeout != set->timeout) +@@ -4024,15 +4075,11 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + } + + if (nla[NFTA_SET_ELEM_DATA] != NULL) { +- err = nft_data_init(ctx, &data, sizeof(data), &d2, +- nla[NFTA_SET_ELEM_DATA]); ++ err = nft_setelem_parse_data(ctx, set, &desc, &elem.data.val, ++ nla[NFTA_SET_ELEM_DATA]); + if (err < 0) + goto err2; + +- err = -EINVAL; +- if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen) +- goto err3; +- + dreg = nft_type_to_reg(set->dtype); + list_for_each_entry(binding, &set->bindings, list) { + struct nft_ctx bind_ctx = { +@@ -4046,13 +4093,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + continue; + + err = nft_validate_register_store(&bind_ctx, dreg, +- &data, +- d2.type, d2.len); ++ &elem.data.val, ++ desc.type, desc.len); + if (err < 0) + goto err3; + } + +- nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len); ++ nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, desc.len); + } + + /* The full maximum length of userdata can exceed the maximum +@@ -4068,7 +4115,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, + } + + err = -ENOMEM; +- elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data, ++ elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, ++ elem.data.val.data, + timeout, GFP_KERNEL); + if (elem.priv == NULL) + goto err3; +@@ -4135,9 +4183,9 @@ err4: + kfree(elem.priv); + err3: + if (nla[NFTA_SET_ELEM_DATA] != NULL) +- nft_data_release(&data, d2.type); ++ nft_data_release(&elem.data.val, desc.type); + err2: +- nft_data_release(&elem.key.val, d1.type); ++ nft_data_release(&elem.key.val, NFT_DATA_VALUE); + err1: + return err; + } +@@ -4164,7 +4212,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk, + genmask); + if (IS_ERR(set)) { + if (nla[NFTA_SET_ELEM_LIST_SET_ID]) { +- set = nf_tables_set_lookup_byid(net, ++ set = nf_tables_set_lookup_byid(net, ctx.table, + nla[NFTA_SET_ELEM_LIST_SET_ID], + genmask); + } +@@ -4235,7 +4283,6 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, + { + struct nlattr *nla[NFTA_SET_ELEM_MAX + 1]; + struct nft_set_ext_tmpl tmpl; +- struct nft_data_desc desc; + struct nft_set_elem elem; + struct nft_set_ext *ext; + struct nft_trans *trans; +@@ -4246,11 +4293,10 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, + err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr, + nft_set_elem_policy, NULL); + if (err < 0) +- goto err1; ++ return err; + +- err = -EINVAL; + if (nla[NFTA_SET_ELEM_KEY] == NULL) +- goto err1; ++ return -EINVAL; + + nft_set_ext_prepare(&tmpl); + +@@ -4260,37 +4306,31 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, + if (flags != 0) + nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS); + +- err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc, +- nla[NFTA_SET_ELEM_KEY]); ++ err = nft_setelem_parse_key(ctx, set, &elem.key.val, ++ nla[NFTA_SET_ELEM_KEY]); + if (err < 0) +- goto err1; +- +- err = -EINVAL; +- if (desc.type != NFT_DATA_VALUE || desc.len != set->klen) +- goto err2; ++ return err; + +- nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len); ++ nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen); + + err = -ENOMEM; + elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0, + GFP_KERNEL); + if (elem.priv == NULL) +- goto err2; ++ goto fail_elem; + + ext = nft_set_elem_ext(set, elem.priv); + if (flags) + *nft_set_ext_flags(ext) = flags; + + trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set); +- if (trans == NULL) { +- err = -ENOMEM; +- goto err3; +- } ++ if (trans == NULL) ++ goto fail_trans; + + priv = set->ops->deactivate(ctx->net, set, &elem); + if (priv == NULL) { + err = -ENOENT; +- goto err4; ++ goto fail_ops; + } + kfree(elem.priv); + elem.priv = priv; +@@ -4301,13 +4341,12 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, + list_add_tail(&trans->list, &ctx->net->nft.commit_list); + return 0; + +-err4: ++fail_ops: + kfree(trans); +-err3: ++fail_trans: + kfree(elem.priv); +-err2: +- nft_data_release(&elem.key.val, desc.type); +-err1: ++fail_elem: ++ nft_data_release(&elem.key.val, NFT_DATA_VALUE); + return err; + } + +@@ -5609,28 +5648,24 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest) + } + EXPORT_SYMBOL_GPL(nft_parse_u32_check); + +-/** +- * nft_parse_register - parse a register value from a netlink attribute +- * +- * @attr: netlink attribute +- * +- * Parse and translate a register value from a netlink attribute. +- * Registers used to be 128 bit wide, these register numbers will be +- * mapped to the corresponding 32 bit register numbers. +- */ +-unsigned int nft_parse_register(const struct nlattr *attr) ++static int nft_parse_register(const struct nlattr *attr, u32 *preg) + { + unsigned int reg; + + reg = ntohl(nla_get_be32(attr)); + switch (reg) { + case NFT_REG_VERDICT...NFT_REG_4: +- return reg * NFT_REG_SIZE / NFT_REG32_SIZE; ++ *preg = reg * NFT_REG_SIZE / NFT_REG32_SIZE; ++ break; ++ case NFT_REG32_00...NFT_REG32_15: ++ *preg = reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00; ++ break; + default: +- return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00; ++ return -ERANGE; + } ++ ++ return 0; + } +-EXPORT_SYMBOL_GPL(nft_parse_register); + + /** + * nft_dump_register - dump a register value to a netlink attribute +@@ -5663,7 +5698,7 @@ EXPORT_SYMBOL_GPL(nft_dump_register); + * Validate that the input register is one of the general purpose + * registers and that the length of the load is within the bounds. + */ +-int nft_validate_register_load(enum nft_registers reg, unsigned int len) ++static int nft_validate_register_load(enum nft_registers reg, unsigned int len) + { + if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE) + return -EINVAL; +@@ -5674,7 +5709,24 @@ int nft_validate_register_load(enum nft_registers reg, unsigned int len) + + return 0; + } +-EXPORT_SYMBOL_GPL(nft_validate_register_load); ++ ++int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len) ++{ ++ u32 reg; ++ int err; ++ ++ err = nft_parse_register(attr, ®); ++ if (err < 0) ++ return err; ++ ++ err = nft_validate_register_load(reg, len); ++ if (err < 0) ++ return err; ++ ++ *sreg = reg; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(nft_parse_register_load); + + /** + * nft_validate_register_store - validate an expressions' register store +@@ -5690,10 +5742,11 @@ EXPORT_SYMBOL_GPL(nft_validate_register_load); + * A value of NULL for the data means that its runtime gathered + * data. + */ +-int nft_validate_register_store(const struct nft_ctx *ctx, +- enum nft_registers reg, +- const struct nft_data *data, +- enum nft_data_types type, unsigned int len) ++static int nft_validate_register_store(const struct nft_ctx *ctx, ++ enum nft_registers reg, ++ const struct nft_data *data, ++ enum nft_data_types type, ++ unsigned int len) + { + int err; + +@@ -5732,7 +5785,27 @@ int nft_validate_register_store(const struct nft_ctx *ctx, + return 0; + } + } +-EXPORT_SYMBOL_GPL(nft_validate_register_store); ++ ++int nft_parse_register_store(const struct nft_ctx *ctx, ++ const struct nlattr *attr, u8 *dreg, ++ const struct nft_data *data, ++ enum nft_data_types type, unsigned int len) ++{ ++ int err; ++ u32 reg; ++ ++ err = nft_parse_register(attr, ®); ++ if (err < 0) ++ return err; ++ ++ err = nft_validate_register_store(ctx, reg, data, type, len); ++ if (err < 0) ++ return err; ++ ++ *dreg = reg; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(nft_parse_register_store); + + static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = { + [NFTA_VERDICT_CODE] = { .type = NLA_U32 }, +@@ -6032,18 +6105,25 @@ static int __init nf_tables_module_init(void) + goto err1; + } + +- err = nf_tables_core_module_init(); ++ err = register_pernet_subsys(&nf_tables_net_ops); + if (err < 0) + goto err2; + +- err = nfnetlink_subsys_register(&nf_tables_subsys); ++ err = nf_tables_core_module_init(); + if (err < 0) + goto err3; + ++ /* must be last */ ++ err = nfnetlink_subsys_register(&nf_tables_subsys); ++ if (err < 0) ++ goto err4; ++ + pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <ka...@trash.net>\n"); +- return register_pernet_subsys(&nf_tables_net_ops); +-err3: ++ return err; ++err4: + nf_tables_core_module_exit(); ++err3: ++ unregister_pernet_subsys(&nf_tables_net_ops); + err2: + kfree(info); + err1: +diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c +index fff8073e2a569..a89152cd60ecf 100644 +--- a/net/netfilter/nft_bitwise.c ++++ b/net/netfilter/nft_bitwise.c +@@ -18,8 +18,8 @@ + #include <net/netfilter/nf_tables.h> + + struct nft_bitwise { +- enum nft_registers sreg:8; +- enum nft_registers dreg:8; ++ u8 sreg; ++ u8 dreg; + u8 len; + struct nft_data mask; + struct nft_data xor; +@@ -68,14 +68,14 @@ static int nft_bitwise_init(const struct nft_ctx *ctx, + + priv->len = len; + +- priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]); +- err = nft_validate_register_load(priv->sreg, priv->len); ++ err = nft_parse_register_load(tb[NFTA_BITWISE_SREG], &priv->sreg, ++ priv->len); + if (err < 0) + return err; + +- priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]); +- err = nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, priv->len); ++ err = nft_parse_register_store(ctx, tb[NFTA_BITWISE_DREG], ++ &priv->dreg, NULL, NFT_DATA_VALUE, ++ priv->len); + if (err < 0) + return err; + +diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c +index 13d4e421a6b33..5e1fbdd7b2846 100644 +--- a/net/netfilter/nft_byteorder.c ++++ b/net/netfilter/nft_byteorder.c +@@ -19,8 +19,8 @@ + #include <net/netfilter/nf_tables.h> + + struct nft_byteorder { +- enum nft_registers sreg:8; +- enum nft_registers dreg:8; ++ u8 sreg; ++ u8 dreg; + enum nft_byteorder_ops op:8; + u8 len; + u8 size; +@@ -133,20 +133,20 @@ static int nft_byteorder_init(const struct nft_ctx *ctx, + return -EINVAL; + } + +- priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]); + err = nft_parse_u32_check(tb[NFTA_BYTEORDER_LEN], U8_MAX, &len); + if (err < 0) + return err; + + priv->len = len; + +- err = nft_validate_register_load(priv->sreg, priv->len); ++ err = nft_parse_register_load(tb[NFTA_BYTEORDER_SREG], &priv->sreg, ++ priv->len); + if (err < 0) + return err; + +- priv->dreg = nft_parse_register(tb[NFTA_BYTEORDER_DREG]); +- return nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, priv->len); ++ return nft_parse_register_store(ctx, tb[NFTA_BYTEORDER_DREG], ++ &priv->dreg, NULL, NFT_DATA_VALUE, ++ priv->len); + } + + static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr) +diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c +index c2945eb3397c8..ad7b300ed911c 100644 +--- a/net/netfilter/nft_cmp.c ++++ b/net/netfilter/nft_cmp.c +@@ -19,7 +19,7 @@ + + struct nft_cmp_expr { + struct nft_data data; +- enum nft_registers sreg:8; ++ u8 sreg; + u8 len; + enum nft_cmp_ops op:8; + }; +@@ -79,8 +79,7 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + tb[NFTA_CMP_DATA]); + BUG_ON(err < 0); + +- priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); +- err = nft_validate_register_load(priv->sreg, desc.len); ++ err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len); + if (err < 0) + return err; + +@@ -129,8 +128,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx, + tb[NFTA_CMP_DATA]); + BUG_ON(err < 0); + +- priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); +- err = nft_validate_register_load(priv->sreg, desc.len); ++ err = nft_parse_register_load(tb[NFTA_CMP_SREG], &priv->sreg, desc.len); + if (err < 0) + return err; + +diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c +index 5e0d367a09882..2af2a10382711 100644 +--- a/net/netfilter/nft_ct.c ++++ b/net/netfilter/nft_ct.c +@@ -27,8 +27,8 @@ struct nft_ct { + enum nft_ct_keys key:8; + enum ip_conntrack_dir dir:8; + union { +- enum nft_registers dreg:8; +- enum nft_registers sreg:8; ++ u8 dreg; ++ u8 sreg; + }; + }; + +@@ -483,9 +483,8 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, + } + } + +- priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]); +- err = nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, len); ++ err = nft_parse_register_store(ctx, tb[NFTA_CT_DREG], &priv->dreg, NULL, ++ NFT_DATA_VALUE, len); + if (err < 0) + return err; + +@@ -578,8 +577,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, + } + } + +- priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]); +- err = nft_validate_register_load(priv->sreg, len); ++ err = nft_parse_register_load(tb[NFTA_CT_SREG], &priv->sreg, len); + if (err < 0) + goto err1; + +diff --git a/net/netfilter/nft_dup_netdev.c b/net/netfilter/nft_dup_netdev.c +index 2cc1e0ef56e88..e862f916efa09 100644 +--- a/net/netfilter/nft_dup_netdev.c ++++ b/net/netfilter/nft_dup_netdev.c +@@ -16,7 +16,7 @@ + #include <net/netfilter/nf_dup_netdev.h> + + struct nft_dup_netdev { +- enum nft_registers sreg_dev:8; ++ u8 sreg_dev; + }; + + static void nft_dup_netdev_eval(const struct nft_expr *expr, +@@ -42,8 +42,8 @@ static int nft_dup_netdev_init(const struct nft_ctx *ctx, + if (tb[NFTA_DUP_SREG_DEV] == NULL) + return -EINVAL; + +- priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]); +- return nft_validate_register_load(priv->sreg_dev, sizeof(int)); ++ return nft_parse_register_load(tb[NFTA_DUP_SREG_DEV], &priv->sreg_dev, ++ sizeof(int)); + } + + static const struct nft_expr_ops nft_dup_netdev_ingress_ops; +diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c +index 74e8fdaa34321..d1dc5c8937a56 100644 +--- a/net/netfilter/nft_dynset.c ++++ b/net/netfilter/nft_dynset.c +@@ -20,8 +20,8 @@ struct nft_dynset { + struct nft_set *set; + struct nft_set_ext_tmpl tmpl; + enum nft_dynset_ops op:8; +- enum nft_registers sreg_key:8; +- enum nft_registers sreg_data:8; ++ u8 sreg_key; ++ u8 sreg_data; + bool invert; + u64 timeout; + struct nft_expr *expr; +@@ -163,8 +163,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx, + tb[NFTA_DYNSET_TIMEOUT]))); + } + +- priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]); +- err = nft_validate_register_load(priv->sreg_key, set->klen);; ++ err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_KEY], &priv->sreg_key, ++ set->klen); + if (err < 0) + return err; + +@@ -174,8 +174,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx, + if (set->dtype == NFT_DATA_VERDICT) + return -EOPNOTSUPP; + +- priv->sreg_data = nft_parse_register(tb[NFTA_DYNSET_SREG_DATA]); +- err = nft_validate_register_load(priv->sreg_data, set->dlen); ++ err = nft_parse_register_load(tb[NFTA_DYNSET_SREG_DATA], ++ &priv->sreg_data, set->dlen); + if (err < 0) + return err; + } else if (set->flags & NFT_SET_MAP) +@@ -190,9 +190,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx, + priv->expr = nft_expr_init(ctx, tb[NFTA_DYNSET_EXPR]); + if (IS_ERR(priv->expr)) + return PTR_ERR(priv->expr); +- +- } else if (set->flags & NFT_SET_EVAL) +- return -EINVAL; ++ } + + nft_set_ext_prepare(&priv->tmpl); + nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen); +diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c +index e73a1503e8d7c..9f1e801ae34f9 100644 +--- a/net/netfilter/nft_exthdr.c ++++ b/net/netfilter/nft_exthdr.c +@@ -23,8 +23,8 @@ struct nft_exthdr { + u8 offset; + u8 len; + u8 op; +- enum nft_registers dreg:8; +- enum nft_registers sreg:8; ++ u8 dreg; ++ u8 sreg; + u8 flags; + }; + +@@ -257,12 +257,12 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, + priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); + priv->offset = offset; + priv->len = len; +- priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]); + priv->flags = flags; + priv->op = op; + +- return nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, priv->len); ++ return nft_parse_register_store(ctx, tb[NFTA_EXTHDR_DREG], ++ &priv->dreg, NULL, NFT_DATA_VALUE, ++ priv->len); + } + + static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx, +@@ -307,11 +307,11 @@ static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx, + priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); + priv->offset = offset; + priv->len = len; +- priv->sreg = nft_parse_register(tb[NFTA_EXTHDR_SREG]); + priv->flags = flags; + priv->op = op; + +- return nft_validate_register_load(priv->sreg, priv->len); ++ return nft_parse_register_load(tb[NFTA_EXTHDR_SREG], &priv->sreg, ++ priv->len); + } + + static int nft_exthdr_dump_common(struct sk_buff *skb, const struct nft_exthdr *priv) +diff --git a/net/netfilter/nft_fib.c b/net/netfilter/nft_fib.c +index 21df8cccea658..ce6891337304d 100644 +--- a/net/netfilter/nft_fib.c ++++ b/net/netfilter/nft_fib.c +@@ -88,7 +88,6 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + return -EINVAL; + + priv->result = ntohl(nla_get_be32(tb[NFTA_FIB_RESULT])); +- priv->dreg = nft_parse_register(tb[NFTA_FIB_DREG]); + + switch (priv->result) { + case NFT_FIB_RESULT_OIF: +@@ -108,8 +107,8 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + return -EINVAL; + } + +- err = nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, len); ++ err = nft_parse_register_store(ctx, tb[NFTA_FIB_DREG], &priv->dreg, ++ NULL, NFT_DATA_VALUE, len); + if (err < 0) + return err; + +diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c +index ee190fa4dc347..c717e3a442472 100644 +--- a/net/netfilter/nft_fwd_netdev.c ++++ b/net/netfilter/nft_fwd_netdev.c +@@ -16,7 +16,7 @@ + #include <net/netfilter/nf_dup_netdev.h> + + struct nft_fwd_netdev { +- enum nft_registers sreg_dev:8; ++ u8 sreg_dev; + }; + + static void nft_fwd_netdev_eval(const struct nft_expr *expr, +@@ -43,8 +43,8 @@ static int nft_fwd_netdev_init(const struct nft_ctx *ctx, + if (tb[NFTA_FWD_SREG_DEV] == NULL) + return -EINVAL; + +- priv->sreg_dev = nft_parse_register(tb[NFTA_FWD_SREG_DEV]); +- return nft_validate_register_load(priv->sreg_dev, sizeof(int)); ++ return nft_parse_register_load(tb[NFTA_FWD_SREG_DEV], &priv->sreg_dev, ++ sizeof(int)); + } + + static const struct nft_expr_ops nft_fwd_netdev_ingress_ops; +diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c +index 010a565b40001..5d067ca294465 100644 +--- a/net/netfilter/nft_hash.c ++++ b/net/netfilter/nft_hash.c +@@ -18,8 +18,8 @@ + #include <linux/jhash.h> + + struct nft_jhash { +- enum nft_registers sreg:8; +- enum nft_registers dreg:8; ++ u8 sreg; ++ u8 dreg; + u8 len; + bool autogen_seed:1; + u32 modulus; +@@ -40,7 +40,7 @@ static void nft_jhash_eval(const struct nft_expr *expr, + } + + struct nft_symhash { +- enum nft_registers dreg:8; ++ u8 dreg; + u32 modulus; + u32 offset; + }; +@@ -85,9 +85,6 @@ static int nft_jhash_init(const struct nft_ctx *ctx, + if (tb[NFTA_HASH_OFFSET]) + priv->offset = ntohl(nla_get_be32(tb[NFTA_HASH_OFFSET])); + +- priv->sreg = nft_parse_register(tb[NFTA_HASH_SREG]); +- priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]); +- + err = nft_parse_u32_check(tb[NFTA_HASH_LEN], U8_MAX, &len); + if (err < 0) + return err; +@@ -96,6 +93,10 @@ static int nft_jhash_init(const struct nft_ctx *ctx, + + priv->len = len; + ++ err = nft_parse_register_load(tb[NFTA_HASH_SREG], &priv->sreg, len); ++ if (err < 0) ++ return err; ++ + priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS])); + if (priv->modulus <= 1) + return -ERANGE; +@@ -110,9 +111,8 @@ static int nft_jhash_init(const struct nft_ctx *ctx, + get_random_bytes(&priv->seed, sizeof(priv->seed)); + } + +- return nft_validate_register_load(priv->sreg, len) && +- nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, sizeof(u32)); ++ return nft_parse_register_store(ctx, tb[NFTA_HASH_DREG], &priv->dreg, ++ NULL, NFT_DATA_VALUE, sizeof(u32)); + } + + static int nft_symhash_init(const struct nft_ctx *ctx, +@@ -128,8 +128,6 @@ static int nft_symhash_init(const struct nft_ctx *ctx, + if (tb[NFTA_HASH_OFFSET]) + priv->offset = ntohl(nla_get_be32(tb[NFTA_HASH_OFFSET])); + +- priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]); +- + priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS])); + if (priv->modulus < 1) + return -ERANGE; +@@ -137,8 +135,9 @@ static int nft_symhash_init(const struct nft_ctx *ctx, + if (priv->offset + priv->modulus - 1 < priv->offset) + return -EOVERFLOW; + +- return nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, sizeof(u32)); ++ return nft_parse_register_store(ctx, tb[NFTA_HASH_DREG], ++ &priv->dreg, NULL, NFT_DATA_VALUE, ++ sizeof(u32)); + } + + static int nft_jhash_dump(struct sk_buff *skb, +diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c +index 86fd35018b4a6..99f528e5f1542 100644 +--- a/net/netfilter/nft_immediate.c ++++ b/net/netfilter/nft_immediate.c +@@ -19,7 +19,7 @@ + + struct nft_immediate_expr { + struct nft_data data; +- enum nft_registers dreg:8; ++ u8 dreg; + u8 dlen; + }; + +@@ -56,9 +56,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx, + + priv->dlen = desc.len; + +- priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]); +- err = nft_validate_register_store(ctx, priv->dreg, &priv->data, +- desc.type, desc.len); ++ err = nft_parse_register_store(ctx, tb[NFTA_IMMEDIATE_DREG], ++ &priv->dreg, &priv->data, desc.type, ++ desc.len); + if (err < 0) + goto err1; + +diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c +index 4fcbe51e88c76..7577a486635ae 100644 +--- a/net/netfilter/nft_lookup.c ++++ b/net/netfilter/nft_lookup.c +@@ -20,8 +20,8 @@ + + struct nft_lookup { + struct nft_set *set; +- enum nft_registers sreg:8; +- enum nft_registers dreg:8; ++ u8 sreg; ++ u8 dreg; + bool invert; + struct nft_set_binding binding; + }; +@@ -76,8 +76,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx, + if (IS_ERR(set)) + return PTR_ERR(set); + +- priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]); +- err = nft_validate_register_load(priv->sreg, set->klen); ++ err = nft_parse_register_load(tb[NFTA_LOOKUP_SREG], &priv->sreg, ++ set->klen); + if (err < 0) + return err; + +@@ -100,9 +100,9 @@ static int nft_lookup_init(const struct nft_ctx *ctx, + if (!(set->flags & NFT_SET_MAP)) + return -EINVAL; + +- priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]); +- err = nft_validate_register_store(ctx, priv->dreg, NULL, +- set->dtype, set->dlen); ++ err = nft_parse_register_store(ctx, tb[NFTA_LOOKUP_DREG], ++ &priv->dreg, NULL, set->dtype, ++ set->dlen); + if (err < 0) + return err; + } else if (set->flags & NFT_SET_MAP) +diff --git a/net/netfilter/nft_masq.c b/net/netfilter/nft_masq.c +index 6ac03d4266c90..712a187983e6e 100644 +--- a/net/netfilter/nft_masq.c ++++ b/net/netfilter/nft_masq.c +@@ -53,19 +53,15 @@ int nft_masq_init(const struct nft_ctx *ctx, + } + + if (tb[NFTA_MASQ_REG_PROTO_MIN]) { +- priv->sreg_proto_min = +- nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MIN]); +- +- err = nft_validate_register_load(priv->sreg_proto_min, plen); ++ err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MIN], ++ &priv->sreg_proto_min, plen); + if (err < 0) + return err; + + if (tb[NFTA_MASQ_REG_PROTO_MAX]) { +- priv->sreg_proto_max = +- nft_parse_register(tb[NFTA_MASQ_REG_PROTO_MAX]); +- +- err = nft_validate_register_load(priv->sreg_proto_max, +- plen); ++ err = nft_parse_register_load(tb[NFTA_MASQ_REG_PROTO_MAX], ++ &priv->sreg_proto_max, ++ plen); + if (err < 0) + return err; + } else { +diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c +index c71184d4eac1b..c9bf2b17b7bdd 100644 +--- a/net/netfilter/nft_meta.c ++++ b/net/netfilter/nft_meta.c +@@ -314,9 +314,8 @@ int nft_meta_get_init(const struct nft_ctx *ctx, + return -EOPNOTSUPP; + } + +- priv->dreg = nft_parse_register(tb[NFTA_META_DREG]); +- return nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, len); ++ return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg, ++ NULL, NFT_DATA_VALUE, len); + } + EXPORT_SYMBOL_GPL(nft_meta_get_init); + +@@ -374,8 +373,7 @@ int nft_meta_set_init(const struct nft_ctx *ctx, + return -EOPNOTSUPP; + } + +- priv->sreg = nft_parse_register(tb[NFTA_META_SREG]); +- err = nft_validate_register_load(priv->sreg, len); ++ err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len); + if (err < 0) + return err; + +diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c +index 04dd813ed7755..c3f6c41823ec0 100644 +--- a/net/netfilter/nft_nat.c ++++ b/net/netfilter/nft_nat.c +@@ -27,10 +27,10 @@ + #include <net/ip.h> + + struct nft_nat { +- enum nft_registers sreg_addr_min:8; +- enum nft_registers sreg_addr_max:8; +- enum nft_registers sreg_proto_min:8; +- enum nft_registers sreg_proto_max:8; ++ u8 sreg_addr_min; ++ u8 sreg_addr_max; ++ u8 sreg_proto_min; ++ u8 sreg_proto_max; + enum nf_nat_manip_type type:8; + u8 family; + u16 flags; +@@ -160,18 +160,15 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + priv->family = family; + + if (tb[NFTA_NAT_REG_ADDR_MIN]) { +- priv->sreg_addr_min = +- nft_parse_register(tb[NFTA_NAT_REG_ADDR_MIN]); +- err = nft_validate_register_load(priv->sreg_addr_min, alen); ++ err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MIN], ++ &priv->sreg_addr_min, alen); + if (err < 0) + return err; + + if (tb[NFTA_NAT_REG_ADDR_MAX]) { +- priv->sreg_addr_max = +- nft_parse_register(tb[NFTA_NAT_REG_ADDR_MAX]); +- +- err = nft_validate_register_load(priv->sreg_addr_max, +- alen); ++ err = nft_parse_register_load(tb[NFTA_NAT_REG_ADDR_MAX], ++ &priv->sreg_addr_max, ++ alen); + if (err < 0) + return err; + } else { +@@ -181,19 +178,15 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, + + plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all); + if (tb[NFTA_NAT_REG_PROTO_MIN]) { +- priv->sreg_proto_min = +- nft_parse_register(tb[NFTA_NAT_REG_PROTO_MIN]); +- +- err = nft_validate_register_load(priv->sreg_proto_min, plen); ++ err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MIN], ++ &priv->sreg_proto_min, plen); + if (err < 0) + return err; + + if (tb[NFTA_NAT_REG_PROTO_MAX]) { +- priv->sreg_proto_max = +- nft_parse_register(tb[NFTA_NAT_REG_PROTO_MAX]); +- +- err = nft_validate_register_load(priv->sreg_proto_max, +- plen); ++ err = nft_parse_register_load(tb[NFTA_NAT_REG_PROTO_MAX], ++ &priv->sreg_proto_max, ++ plen); + if (err < 0) + return err; + } else { +diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c +index 5a3a52c71545a..befc715cb06fb 100644 +--- a/net/netfilter/nft_numgen.c ++++ b/net/netfilter/nft_numgen.c +@@ -20,7 +20,7 @@ + static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state); + + struct nft_ng_inc { +- enum nft_registers dreg:8; ++ u8 dreg; + u32 modulus; + atomic_t counter; + u32 offset; +@@ -64,11 +64,10 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx, + if (priv->offset + priv->modulus - 1 < priv->offset) + return -EOVERFLOW; + +- priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]); + atomic_set(&priv->counter, priv->modulus - 1); + +- return nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, sizeof(u32)); ++ return nft_parse_register_store(ctx, tb[NFTA_NG_DREG], &priv->dreg, ++ NULL, NFT_DATA_VALUE, sizeof(u32)); + } + + static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg, +@@ -98,7 +97,7 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const struct nft_expr *expr) + } + + struct nft_ng_random { +- enum nft_registers dreg:8; ++ u8 dreg; + u32 modulus; + u32 offset; + }; +@@ -133,10 +132,8 @@ static int nft_ng_random_init(const struct nft_ctx *ctx, + + prandom_init_once(&nft_numgen_prandom_state); + +- priv->dreg = nft_parse_register(tb[NFTA_NG_DREG]); +- +- return nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, sizeof(u32)); ++ return nft_parse_register_store(ctx, tb[NFTA_NG_DREG], &priv->dreg, ++ NULL, NFT_DATA_VALUE, sizeof(u32)); + } + + static int nft_ng_random_dump(struct sk_buff *skb, const struct nft_expr *expr) +diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c +index 49a067a67e723..8ad0be6c53fd3 100644 +--- a/net/netfilter/nft_objref.c ++++ b/net/netfilter/nft_objref.c +@@ -64,27 +64,40 @@ nla_put_failure: + return -1; + } + +-static void nft_objref_destroy(const struct nft_ctx *ctx, +- const struct nft_expr *expr) ++static void nft_objref_deactivate(const struct nft_ctx *ctx, ++ const struct nft_expr *expr, ++ enum nft_trans_phase phase) + { + struct nft_object *obj = nft_objref_priv(expr); + ++ if (phase == NFT_TRANS_COMMIT) ++ return; ++ + obj->use--; + } + ++static void nft_objref_activate(const struct nft_ctx *ctx, ++ const struct nft_expr *expr) ++{ ++ struct nft_object *obj = nft_objref_priv(expr); ++ ++ obj->use++; ++} ++ + static struct nft_expr_type nft_objref_type; + static const struct nft_expr_ops nft_objref_ops = { + .type = &nft_objref_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_object *)), + .eval = nft_objref_eval, + .init = nft_objref_init, +- .destroy = nft_objref_destroy, ++ .activate = nft_objref_activate, ++ .deactivate = nft_objref_deactivate, + .dump = nft_objref_dump, + }; + + struct nft_objref_map { + struct nft_set *set; +- enum nft_registers sreg:8; ++ u8 sreg; + struct nft_set_binding binding; + }; + +@@ -125,8 +138,8 @@ static int nft_objref_map_init(const struct nft_ctx *ctx, + if (!(set->flags & NFT_SET_OBJECT)) + return -EINVAL; + +- priv->sreg = nft_parse_register(tb[NFTA_OBJREF_SET_SREG]); +- err = nft_validate_register_load(priv->sreg, set->klen); ++ err = nft_parse_register_load(tb[NFTA_OBJREF_SET_SREG], &priv->sreg, ++ set->klen); + if (err < 0) + return err; + +diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c +index 5732b32ab9320..77cfd5182784f 100644 +--- a/net/netfilter/nft_payload.c ++++ b/net/netfilter/nft_payload.c +@@ -135,10 +135,10 @@ static int nft_payload_init(const struct nft_ctx *ctx, + priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE])); + priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); + priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); +- priv->dreg = nft_parse_register(tb[NFTA_PAYLOAD_DREG]); + +- return nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, priv->len); ++ return nft_parse_register_store(ctx, tb[NFTA_PAYLOAD_DREG], ++ &priv->dreg, NULL, NFT_DATA_VALUE, ++ priv->len); + } + + static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr) +@@ -338,7 +338,6 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, + priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE])); + priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); + priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); +- priv->sreg = nft_parse_register(tb[NFTA_PAYLOAD_SREG]); + + if (tb[NFTA_PAYLOAD_CSUM_TYPE]) + csum_type = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE])); +@@ -369,7 +368,8 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, + } + priv->csum_type = csum_type; + +- return nft_validate_register_load(priv->sreg, priv->len); ++ return nft_parse_register_load(tb[NFTA_PAYLOAD_SREG], &priv->sreg, ++ priv->len); + } + + static int nft_payload_set_dump(struct sk_buff *skb, const struct nft_expr *expr) +diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c +index 98613658d4ac5..de5f1bda9d6f1 100644 +--- a/net/netfilter/nft_queue.c ++++ b/net/netfilter/nft_queue.c +@@ -22,10 +22,10 @@ + static u32 jhash_initval __read_mostly; + + struct nft_queue { +- enum nft_registers sreg_qnum:8; +- u16 queuenum; +- u16 queues_total; +- u16 flags; ++ u8 sreg_qnum; ++ u16 queuenum; ++ u16 queues_total; ++ u16 flags; + }; + + static void nft_queue_eval(const struct nft_expr *expr, +@@ -114,8 +114,8 @@ static int nft_queue_sreg_init(const struct nft_ctx *ctx, + struct nft_queue *priv = nft_expr_priv(expr); + int err; + +- priv->sreg_qnum = nft_parse_register(tb[NFTA_QUEUE_SREG_QNUM]); +- err = nft_validate_register_load(priv->sreg_qnum, sizeof(u32)); ++ err = nft_parse_register_load(tb[NFTA_QUEUE_SREG_QNUM], ++ &priv->sreg_qnum, sizeof(u32)); + if (err < 0) + return err; + +diff --git a/net/netfilter/nft_range.c b/net/netfilter/nft_range.c +index cedb96c3619fa..658d68522013e 100644 +--- a/net/netfilter/nft_range.c ++++ b/net/netfilter/nft_range.c +@@ -18,7 +18,7 @@ + struct nft_range_expr { + struct nft_data data_from; + struct nft_data data_to; +- enum nft_registers sreg:8; ++ u8 sreg; + u8 len; + enum nft_range_ops op:8; + }; +@@ -80,8 +80,8 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr + goto err2; + } + +- priv->sreg = nft_parse_register(tb[NFTA_RANGE_SREG]); +- err = nft_validate_register_load(priv->sreg, desc_from.len); ++ err = nft_parse_register_load(tb[NFTA_RANGE_SREG], &priv->sreg, ++ desc_from.len); + if (err < 0) + goto err2; + +diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c +index 1e66538bf0ff2..723e07a5640c2 100644 +--- a/net/netfilter/nft_redir.c ++++ b/net/netfilter/nft_redir.c +@@ -49,19 +49,15 @@ int nft_redir_init(const struct nft_ctx *ctx, + + plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all); + if (tb[NFTA_REDIR_REG_PROTO_MIN]) { +- priv->sreg_proto_min = +- nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MIN]); +- +- err = nft_validate_register_load(priv->sreg_proto_min, plen); ++ err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MIN], ++ &priv->sreg_proto_min, plen); + if (err < 0) + return err; + + if (tb[NFTA_REDIR_REG_PROTO_MAX]) { +- priv->sreg_proto_max = +- nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MAX]); +- +- err = nft_validate_register_load(priv->sreg_proto_max, +- plen); ++ err = nft_parse_register_load(tb[NFTA_REDIR_REG_PROTO_MAX], ++ &priv->sreg_proto_max, ++ plen); + if (err < 0) + return err; + } else { +diff --git a/net/netfilter/nft_rt.c b/net/netfilter/nft_rt.c +index a6b7d05aeacf4..60d3f86a1fd91 100644 +--- a/net/netfilter/nft_rt.c ++++ b/net/netfilter/nft_rt.c +@@ -20,7 +20,7 @@ + + struct nft_rt { + enum nft_rt_keys key:8; +- enum nft_registers dreg:8; ++ u8 dreg; + }; + + static u16 get_tcpmss(const struct nft_pktinfo *pkt, const struct dst_entry *skbdst) +@@ -141,9 +141,8 @@ static int nft_rt_get_init(const struct nft_ctx *ctx, + return -EOPNOTSUPP; + } + +- priv->dreg = nft_parse_register(tb[NFTA_RT_DREG]); +- return nft_validate_register_store(ctx, priv->dreg, NULL, +- NFT_DATA_VALUE, len); ++ return nft_parse_register_store(ctx, tb[NFTA_RT_DREG], &priv->dreg, ++ NULL, NFT_DATA_VALUE, len); + } + + static int nft_rt_get_dump(struct sk_buff *skb, +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index d7b0a7aa29a83..4b40edb51b9e5 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1977,7 +1977,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, + + skb_free_datagram(sk, skb); + +- if (nlk->cb_running && ++ if (READ_ONCE(nlk->cb_running) && + atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { + ret = netlink_dump(sk); + if (ret) { +@@ -2259,7 +2259,7 @@ static int netlink_dump(struct sock *sk) + if (cb->done) + cb->done(cb); + +- nlk->cb_running = false; ++ WRITE_ONCE(nlk->cb_running, false); + module = cb->module; + skb = cb->skb; + mutex_unlock(nlk->cb_mutex); +@@ -2320,7 +2320,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, + goto error_put; + } + +- nlk->cb_running = true; ++ WRITE_ONCE(nlk->cb_running, true); + nlk->dump_done_errno = INT_MAX; + + mutex_unlock(nlk->cb_mutex); +@@ -2633,7 +2633,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v) + nlk->groups ? (u32)nlk->groups[0] : 0, + sk_rmem_alloc_get(s), + sk_wmem_alloc_get(s), +- nlk->cb_running, ++ READ_ONCE(nlk->cb_running), + refcount_read(&s->sk_refcnt), + atomic_read(&s->sk_drops), + sock_i_ino(s) +diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c +index 5647905c88d66..f8eeef85ffa6e 100644 +--- a/net/nsh/nsh.c ++++ b/net/nsh/nsh.c +@@ -18,13 +18,12 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, + netdev_features_t features) + { + struct sk_buff *segs = ERR_PTR(-EINVAL); ++ u16 mac_offset = skb->mac_header; + unsigned int nsh_len, mac_len; + __be16 proto; +- int nhoff; + + skb_reset_network_header(skb); + +- nhoff = skb->network_header - skb->mac_header; + mac_len = skb->mac_len; + + if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN))) +@@ -49,15 +48,14 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, + segs = skb_mac_gso_segment(skb, features); + if (IS_ERR_OR_NULL(segs)) { + skb_gso_error_unwind(skb, htons(ETH_P_NSH), nsh_len, +- skb->network_header - nhoff, +- mac_len); ++ mac_offset, mac_len); + goto out; + } + + for (skb = segs; skb; skb = skb->next) { + skb->protocol = htons(ETH_P_NSH); + __skb_push(skb, nsh_len); +- skb_set_mac_header(skb, -nhoff); ++ skb->mac_header = mac_offset; + skb->network_header = skb->mac_header + mac_len; + skb->mac_len = mac_len; + } +diff --git a/net/socket.c b/net/socket.c +index 7bcd7053e61f2..e59b114e16ba7 100644 +--- a/net/socket.c ++++ b/net/socket.c +@@ -2383,7 +2383,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + * error to return on the next call or if the + * app asks about it using getsockopt(SO_ERROR). + */ +- sock->sk->sk_err = -err; ++ WRITE_ONCE(sock->sk->sk_err, -err); + } + out_put: + fput_light(sock->file, fput_needed); +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 0e494902fadaa..375d4e20efd6b 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1236,7 +1236,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo) + + sched = !sock_flag(other, SOCK_DEAD) && + !(other->sk_shutdown & RCV_SHUTDOWN) && +- unix_recvq_full(other); ++ unix_recvq_full_lockless(other); + + unix_state_unlock(other); + +diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c +index 2ec4359d7321d..356f5525a0028 100644 +--- a/net/vmw_vsock/af_vsock.c ++++ b/net/vmw_vsock/af_vsock.c +@@ -1247,7 +1247,7 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr, + vsock_transport_cancel_pkt(vsk); + vsock_remove_connected(vsk); + goto out_wait; +- } else if (timeout == 0) { ++ } else if ((sk->sk_state != TCP_ESTABLISHED) && (timeout == 0)) { + err = -ETIMEDOUT; + sk->sk_state = TCP_CLOSE; + sock->state = SS_UNCONNECTED; +diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c +index 9012e33ae22f8..731600de03893 100644 +--- a/scripts/recordmcount.c ++++ b/scripts/recordmcount.c +@@ -146,6 +146,7 @@ uwrite(int const fd, void const *const buf, size_t const count) + { + size_t cnt = count; + off_t idx = 0; ++ void *p = NULL; + + file_updated = 1; + +@@ -153,7 +154,10 @@ uwrite(int const fd, void const *const buf, size_t const count) + off_t aoffset = (file_ptr + count) - file_end; + + if (aoffset > file_append_size) { +- file_append = realloc(file_append, aoffset); ++ p = realloc(file_append, aoffset); ++ if (!p) ++ free(file_append); ++ file_append = p; + file_append_size = aoffset; + } + if (!file_append) { +diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c +index cf406f22f406f..383c3d7fa5d70 100644 +--- a/sound/pci/hda/hda_generic.c ++++ b/sound/pci/hda/hda_generic.c +@@ -1157,8 +1157,8 @@ static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type) + return path && path->ctls[ctl_type]; + } + +-static const char * const channel_name[4] = { +- "Front", "Surround", "CLFE", "Side" ++static const char * const channel_name[] = { ++ "Front", "Surround", "CLFE", "Side", "Back", + }; + + /* give some appropriate ctl name prefix for the given line out channel */ +@@ -1184,7 +1184,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch, + + /* multi-io channels */ + if (ch >= cfg->line_outs) +- return channel_name[ch]; ++ goto fixed_name; + + switch (cfg->line_out_type) { + case AUTO_PIN_SPEAKER_OUT: +@@ -1236,6 +1236,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch, + if (cfg->line_outs == 1 && !spec->multi_ios) + return "Line Out"; + ++ fixed_name: + if (ch >= ARRAY_SIZE(channel_name)) { + snd_BUG(); + return "PCM"; +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index d89c0a9982d16..a86100fb56cef 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -3889,6 +3889,11 @@ HDA_CODEC_ENTRY(0x10de009d, "GPU 9d HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de009e, "GPU 9e HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de009f, "GPU 9f HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de00a0, "GPU a0 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00a3, "GPU a3 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00a4, "GPU a4 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00a5, "GPU a5 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00a6, "GPU a6 HDMI/DP", patch_nvhdmi), ++HDA_CODEC_ENTRY(0x10de00a7, "GPU a7 HDMI/DP", patch_nvhdmi), + HDA_CODEC_ENTRY(0x10de8001, "MCP73 HDMI", patch_nvhdmi_2ch), + HDA_CODEC_ENTRY(0x10de8067, "MCP67/68 HDMI", patch_nvhdmi_2ch), + HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi), +diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +index d7c2a6d13dea1..2221e43c63ce0 100644 +--- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c ++++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +@@ -67,8 +67,8 @@ static int max_freq_mode; + */ + static unsigned long max_frequency; + +-static unsigned long long tsc_at_measure_start; +-static unsigned long long tsc_at_measure_end; ++static unsigned long long *tsc_at_measure_start; ++static unsigned long long *tsc_at_measure_end; + static unsigned long long *mperf_previous_count; + static unsigned long long *aperf_previous_count; + static unsigned long long *mperf_current_count; +@@ -131,7 +131,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent, + aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu]; + + if (max_freq_mode == MAX_FREQ_TSC_REF) { +- tsc_diff = tsc_at_measure_end - tsc_at_measure_start; ++ tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu]; + *percent = 100.0 * mperf_diff / tsc_diff; + dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n", + mperf_cstates[id].name, mperf_diff, tsc_diff); +@@ -168,7 +168,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count, + + if (max_freq_mode == MAX_FREQ_TSC_REF) { + /* Calculate max_freq from TSC count */ +- tsc_diff = tsc_at_measure_end - tsc_at_measure_start; ++ tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu]; + time_diff = timespec_diff_us(time_start, time_end); + max_frequency = tsc_diff / time_diff; + } +@@ -187,33 +187,27 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count, + static int mperf_start(void) + { + int cpu; +- unsigned long long dbg; + + clock_gettime(CLOCK_REALTIME, &time_start); +- mperf_get_tsc(&tsc_at_measure_start); + +- for (cpu = 0; cpu < cpu_count; cpu++) ++ for (cpu = 0; cpu < cpu_count; cpu++) { ++ mperf_get_tsc(&tsc_at_measure_start[cpu]); + mperf_init_stats(cpu); ++ } + +- mperf_get_tsc(&dbg); +- dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start); + return 0; + } + + static int mperf_stop(void) + { +- unsigned long long dbg; + int cpu; + +- for (cpu = 0; cpu < cpu_count; cpu++) ++ for (cpu = 0; cpu < cpu_count; cpu++) { + mperf_measure_stats(cpu); ++ mperf_get_tsc(&tsc_at_measure_end[cpu]); ++ } + +- mperf_get_tsc(&tsc_at_measure_end); + clock_gettime(CLOCK_REALTIME, &time_end); +- +- mperf_get_tsc(&dbg); +- dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end); +- + return 0; + } + +@@ -311,7 +305,8 @@ struct cpuidle_monitor *mperf_register(void) + aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long)); + mperf_current_count = calloc(cpu_count, sizeof(unsigned long long)); + aperf_current_count = calloc(cpu_count, sizeof(unsigned long long)); +- ++ tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long)); ++ tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long)); + mperf_monitor.name_len = strlen(mperf_monitor.name); + return &mperf_monitor; + } +@@ -322,6 +317,8 @@ void mperf_unregister(void) + free(aperf_previous_count); + free(mperf_current_count); + free(aperf_current_count); ++ free(tsc_at_measure_start); ++ free(tsc_at_measure_end); + free(is_valid); + } + +diff --git a/tools/testing/selftests/memfd/fuse_test.c b/tools/testing/selftests/memfd/fuse_test.c +index 1ccb7a3eb14bf..179946f8346e1 100644 +--- a/tools/testing/selftests/memfd/fuse_test.c ++++ b/tools/testing/selftests/memfd/fuse_test.c +@@ -22,6 +22,7 @@ + #include <linux/falloc.h> + #include <linux/fcntl.h> + #include <linux/memfd.h> ++#include <linux/types.h> + #include <sched.h> + #include <stdio.h> + #include <stdlib.h>