commit: 06da349a3ac5eb143f7d5acba8abe3d8d6cad642 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Fri Mar 20 11:56:16 2020 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Fri Mar 20 11:56:16 2020 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=06da349a
Linux patch 4.14.174 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 1173_linux-4.14.174.patch | 3145 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3149 insertions(+) diff --git a/0000_README b/0000_README index fad3b75..37451f3 100644 --- a/0000_README +++ b/0000_README @@ -735,6 +735,10 @@ Patch: 1172_linux-4.14.173.patch From: https://www.kernel.org Desc: Linux 4.14.173 +Patch: 1173_linux-4.14.174.patch +From: https://www.kernel.org +Desc: Linux 4.14.174 + 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/1173_linux-4.14.174.patch b/1173_linux-4.14.174.patch new file mode 100644 index 0000000..bfe0e9e --- /dev/null +++ b/1173_linux-4.14.174.patch @@ -0,0 +1,3145 @@ +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 7e0a4be3503d..ae51b1b7b67f 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -137,6 +137,10 @@ + dynamic table installation which will install SSDT + tables to /sys/firmware/acpi/tables/dynamic. + ++ acpi_no_watchdog [HW,ACPI,WDT] ++ Ignore the ACPI-based watchdog interface (WDAT) and let ++ a native driver control the watchdog device instead. ++ + acpi_rsdp= [ACPI,EFI,KEXEC] + Pass the RSDP address to the kernel, mostly used + on machines running EFI runtime service to boot the +diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting +index 93e0a2404532..c757c1c3cb81 100644 +--- a/Documentation/filesystems/porting ++++ b/Documentation/filesystems/porting +@@ -606,3 +606,10 @@ in your dentry operations instead. + dentry separately, and it now has request_mask and query_flags arguments + to specify the fields and sync type requested by statx. Filesystems not + supporting any statx-specific features may ignore the new arguments. ++-- ++[mandatory] ++ ++ [should've been added in 2016] stale comment in finish_open() ++ nonwithstanding, failure exits in ->atomic_open() instances should ++ *NOT* fput() the file, no matter what. Everything is handled by the ++ caller. +diff --git a/Makefile b/Makefile +index 9a524b5c1d55..edc6b62bd892 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 14 +-SUBLEVEL = 173 ++SUBLEVEL = 174 + EXTRAVERSION = + NAME = Petit Gorille + +diff --git a/arch/arc/include/asm/linkage.h b/arch/arc/include/asm/linkage.h +index b29f1a9fd6f7..07c8e1a6c56e 100644 +--- a/arch/arc/include/asm/linkage.h ++++ b/arch/arc/include/asm/linkage.h +@@ -14,6 +14,8 @@ + #ifdef __ASSEMBLY__ + + #define ASM_NL ` /* use '`' to mark new line in macro */ ++#define __ALIGN .align 4 ++#define __ALIGN_STR __stringify(__ALIGN) + + /* annotation for data we want in DCCM - if enabled in .config */ + .macro ARCFP_DATA nm +diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c +index f4dd7f9663c1..0001742c131d 100644 +--- a/arch/arm/kernel/vdso.c ++++ b/arch/arm/kernel/vdso.c +@@ -103,6 +103,8 @@ static bool __init cntvct_functional(void) + * this. + */ + np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); ++ if (!np) ++ np = of_find_compatible_node(NULL, NULL, "arm,armv8-timer"); + if (!np) + goto out_put; + +diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S +index 6709a8d33963..f1e34f16cfab 100644 +--- a/arch/arm/lib/copy_from_user.S ++++ b/arch/arm/lib/copy_from_user.S +@@ -100,7 +100,7 @@ ENTRY(arm_copy_from_user) + + ENDPROC(arm_copy_from_user) + +- .pushsection .fixup,"ax" ++ .pushsection .text.fixup,"ax" + .align 0 + copy_abort_preamble + ldmfd sp!, {r1, r2, r3} +diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c +index baa7e36073f9..604a8558752d 100644 +--- a/arch/x86/events/amd/uncore.c ++++ b/arch/x86/events/amd/uncore.c +@@ -193,20 +193,18 @@ static int amd_uncore_event_init(struct perf_event *event) + + /* + * NB and Last level cache counters (MSRs) are shared across all cores +- * that share the same NB / Last level cache. Interrupts can be directed +- * to a single target core, however, event counts generated by processes +- * running on other cores cannot be masked out. So we do not support +- * sampling and per-thread events. ++ * that share the same NB / Last level cache. On family 16h and below, ++ * Interrupts can be directed to a single target core, however, event ++ * counts generated by processes running on other cores cannot be masked ++ * out. So we do not support sampling and per-thread events via ++ * CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts: + */ +- if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) +- return -EINVAL; + + /* NB and Last level cache counters do not have usr/os/guest/host bits */ + if (event->attr.exclude_user || event->attr.exclude_kernel || + event->attr.exclude_host || event->attr.exclude_guest) + return -EINVAL; + +- /* and we do not enable counter overflow interrupts */ + hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; + hwc->idx = -1; + +@@ -314,6 +312,7 @@ static struct pmu amd_nb_pmu = { + .start = amd_uncore_start, + .stop = amd_uncore_stop, + .read = amd_uncore_read, ++ .capabilities = PERF_PMU_CAP_NO_INTERRUPT, + }; + + static struct pmu amd_llc_pmu = { +@@ -324,6 +323,7 @@ static struct pmu amd_llc_pmu = { + .start = amd_uncore_start, + .stop = amd_uncore_stop, + .read = amd_uncore_read, ++ .capabilities = PERF_PMU_CAP_NO_INTERRUPT, + }; + + static struct amd_uncore *amd_uncore_alloc(unsigned int cpu) +diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c +index d05be307d081..1d87b85150db 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce_intel.c ++++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c +@@ -489,17 +489,18 @@ static void intel_ppin_init(struct cpuinfo_x86 *c) + return; + + if ((val & 3UL) == 1UL) { +- /* PPIN available but disabled: */ ++ /* PPIN locked in disabled mode */ + return; + } + +- /* If PPIN is disabled, but not locked, try to enable: */ +- if (!(val & 3UL)) { ++ /* If PPIN is disabled, try to enable */ ++ if (!(val & 2UL)) { + wrmsrl_safe(MSR_PPIN_CTL, val | 2UL); + rdmsrl_safe(MSR_PPIN_CTL, &val); + } + +- if ((val & 3UL) == 2UL) ++ /* Is the enable bit set? */ ++ if (val & 2UL) + set_cpu_cap(c, X86_FEATURE_INTEL_PPIN); + } + } +diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c +index 70f3636aff11..4cc8a4a6f1d0 100644 +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -5062,6 +5062,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) + ctxt->fetch.ptr = ctxt->fetch.data; + ctxt->fetch.end = ctxt->fetch.data + insn_len; + ctxt->opcode_len = 1; ++ ctxt->intercept = x86_intercept_none; + if (insn_len > 0) + memcpy(ctxt->fetch.data, insn, insn_len); + else { +diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c +index 23cde3d8e8fb..0bd1899a287f 100644 +--- a/drivers/acpi/acpi_watchdog.c ++++ b/drivers/acpi/acpi_watchdog.c +@@ -58,12 +58,14 @@ static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) + } + #endif + ++static bool acpi_no_watchdog; ++ + static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) + { + const struct acpi_table_wdat *wdat = NULL; + acpi_status status; + +- if (acpi_disabled) ++ if (acpi_disabled || acpi_no_watchdog) + return NULL; + + status = acpi_get_table(ACPI_SIG_WDAT, 0, +@@ -91,6 +93,14 @@ bool acpi_has_watchdog(void) + } + EXPORT_SYMBOL_GPL(acpi_has_watchdog); + ++/* ACPI watchdog can be disabled on boot command line */ ++static int __init disable_acpi_watchdog(char *str) ++{ ++ acpi_no_watchdog = true; ++ return 1; ++} ++__setup("acpi_no_watchdog", disable_acpi_watchdog); ++ + void __init acpi_watchdog_init(void) + { + const struct acpi_wdat_entry *entries; +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index 8767401f75e0..19d226ff15ef 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -271,10 +271,12 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, + err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num); + if (err) { + virtqueue_kick(vblk->vqs[qid].vq); +- blk_mq_stop_hw_queue(hctx); ++ /* Don't stop the queue if -ENOMEM: we may have failed to ++ * bounce the buffer due to global resource outage. ++ */ ++ if (err == -ENOSPC) ++ blk_mq_stop_hw_queue(hctx); + spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); +- /* Out of mem doesn't actually happen, since we fall back +- * to direct descriptors */ + if (err == -ENOMEM || err == -ENOSPC) + return BLK_STS_RESOURCE; + return BLK_STS_IOERR; +diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c +index 3e626fd9bd4e..1c65f5ac4368 100644 +--- a/drivers/firmware/efi/efivars.c ++++ b/drivers/firmware/efi/efivars.c +@@ -139,13 +139,16 @@ static ssize_t + efivar_attr_read(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; ++ unsigned long size = sizeof(var->Data); + char *str = buf; ++ int ret; + + if (!entry || !buf) + return -EINVAL; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); ++ var->DataSize = size; ++ if (ret) + return -EIO; + + if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) +@@ -172,13 +175,16 @@ static ssize_t + efivar_size_read(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; ++ unsigned long size = sizeof(var->Data); + char *str = buf; ++ int ret; + + if (!entry || !buf) + return -EINVAL; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); ++ var->DataSize = size; ++ if (ret) + return -EIO; + + str += sprintf(str, "0x%lx\n", var->DataSize); +@@ -189,12 +195,15 @@ static ssize_t + efivar_data_read(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; ++ unsigned long size = sizeof(var->Data); ++ int ret; + + if (!entry || !buf) + return -EINVAL; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); ++ var->DataSize = size; ++ if (ret) + return -EIO; + + memcpy(buf, var->Data, var->DataSize); +@@ -263,6 +272,9 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) + u8 *data; + int err; + ++ if (!entry || !buf) ++ return -EINVAL; ++ + if (is_compat()) { + struct compat_efi_variable *compat; + +@@ -314,14 +326,16 @@ efivar_show_raw(struct efivar_entry *entry, char *buf) + { + struct efi_variable *var = &entry->var; + struct compat_efi_variable *compat; ++ unsigned long datasize = sizeof(var->Data); + size_t size; ++ int ret; + + if (!entry || !buf) + return 0; + +- var->DataSize = 1024; +- if (efivar_entry_get(entry, &entry->var.Attributes, +- &entry->var.DataSize, entry->var.Data)) ++ ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data); ++ var->DataSize = datasize; ++ if (ret) + return -EIO; + + if (is_compat()) { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +index 4779740421a8..2153f19e59cc 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +@@ -363,8 +363,7 @@ bool amdgpu_atombios_get_connector_info_from_object_table(struct amdgpu_device * + router.ddc_valid = false; + router.cd_valid = false; + for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) { +- uint8_t grph_obj_type= +- grph_obj_type = ++ uint8_t grph_obj_type = + (le16_to_cpu(path->usGraphicObjIds[j]) & + OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; + +diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c +index d0a81a03ddbd..8ab8f2350bbc 100644 +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -343,7 +343,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, + unsigned long **bit, int *max) + { + if (usage->hid == (HID_UP_CUSTOM | 0x0003) || +- usage->hid == (HID_UP_MSVENDOR | 0x0003)) { ++ usage->hid == (HID_UP_MSVENDOR | 0x0003) || ++ usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) { + /* The fn key on Apple USB keyboards */ + set_bit(EV_REP, hi->input->evbit); + hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); +diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +index 10af8585c820..95052373a828 100644 +--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c ++++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +@@ -341,6 +341,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { + }, + .driver_data = (void *)&sipodev_desc + }, ++ { ++ .ident = "Trekstor SURFBOOK E11B", ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"), ++ }, ++ .driver_data = (void *)&sipodev_desc ++ }, + { + .ident = "Direkt-Tek DTLAPY116-2", + .matches = { +diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c +index df9800aaeac7..0d4d5dcf94f3 100644 +--- a/drivers/i2c/i2c-core-acpi.c ++++ b/drivers/i2c/i2c-core-acpi.c +@@ -352,10 +352,18 @@ static struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle) + static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) + { + struct device *dev; ++ struct i2c_client *client; + + dev = bus_find_device(&i2c_bus_type, NULL, adev, + i2c_acpi_find_match_device); +- return dev ? i2c_verify_client(dev) : NULL; ++ if (!dev) ++ return NULL; ++ ++ client = i2c_verify_client(dev); ++ if (!client) ++ put_device(dev); ++ ++ return client; + } + + static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, +diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c +index c87764a4e212..8000b798e6e6 100644 +--- a/drivers/iommu/dma-iommu.c ++++ b/drivers/iommu/dma-iommu.c +@@ -208,15 +208,15 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie, + start -= iova_offset(iovad, start); + num_pages = iova_align(iovad, end - start) >> iova_shift(iovad); + +- msi_page = kcalloc(num_pages, sizeof(*msi_page), GFP_KERNEL); +- if (!msi_page) +- return -ENOMEM; +- + for (i = 0; i < num_pages; i++) { +- msi_page[i].phys = start; +- msi_page[i].iova = start; +- INIT_LIST_HEAD(&msi_page[i].list); +- list_add(&msi_page[i].list, &cookie->msi_page_list); ++ msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL); ++ if (!msi_page) ++ return -ENOMEM; ++ ++ msi_page->phys = start; ++ msi_page->iova = start; ++ INIT_LIST_HEAD(&msi_page->list); ++ list_add(&msi_page->list, &cookie->msi_page_list); + start += iovad->granule; + } + +diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c +index 38d0128b8135..1f527ca60955 100644 +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -39,6 +39,7 @@ + #include <linux/dmi.h> + #include <linux/slab.h> + #include <linux/iommu.h> ++#include <linux/limits.h> + #include <asm/irq_remapping.h> + #include <asm/iommu_table.h> + +@@ -139,6 +140,13 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) + + BUG_ON(dev->is_virtfn); + ++ /* ++ * Ignore devices that have a domain number higher than what can ++ * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000 ++ */ ++ if (pci_domain_nr(dev->bus) > U16_MAX) ++ return NULL; ++ + /* Only generate path[] for device addition event */ + if (event == BUS_NOTIFY_ADD_DEVICE) + for (tmp = dev; tmp; tmp = tmp->bus->self) +@@ -451,12 +459,13 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header, + + /* Check for NUL termination within the designated length */ + if (strnlen(andd->device_name, header->length - 8) == header->length - 8) { +- WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, ++ pr_warn(FW_BUG + "Your BIOS is broken; ANDD object name is not NUL-terminated\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + return -EINVAL; + } + pr_info("ANDD device: %x name: %s\n", andd->device_number, +@@ -482,14 +491,14 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg) + return 0; + } + } +- WARN_TAINT( +- 1, TAINT_FIRMWARE_WORKAROUND, ++ pr_warn(FW_BUG + "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", +- drhd->reg_base_addr, ++ rhsa->base_address, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + + return 0; + } +@@ -835,14 +844,14 @@ int __init dmar_table_init(void) + + static void warn_invalid_dmar(u64 addr, const char *message) + { +- WARN_TAINT_ONCE( +- 1, TAINT_FIRMWARE_WORKAROUND, ++ pr_warn_once(FW_BUG + "Your BIOS is broken; DMAR reported at address %llx%s!\n" + "BIOS vendor: %s; Ver: %s; Product Version: %s\n", + addr, message, + dmi_get_system_info(DMI_BIOS_VENDOR), + dmi_get_system_info(DMI_BIOS_VERSION), + dmi_get_system_info(DMI_PRODUCT_VERSION)); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + } + + static int __ref +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index b48666849dbe..db1b546134f5 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -3984,10 +3984,11 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev) + + /* we know that the this iommu should be at offset 0xa000 from vtbar */ + drhd = dmar_find_matched_drhd_unit(pdev); +- if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000, +- TAINT_FIRMWARE_WORKAROUND, +- "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n")) ++ if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) { ++ pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"); ++ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); + pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; ++ } + } + DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu); + +@@ -5123,8 +5124,10 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, + u64 phys = 0; + + pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level); +- if (pte) +- phys = dma_pte_addr(pte); ++ if (pte && dma_pte_present(pte)) ++ phys = dma_pte_addr(pte) + ++ (iova & (BIT_MASK(level_to_offset_bits(level) + ++ VTD_PAGE_SHIFT) - 1)); + + return phys; + } +diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c +index 755d588bbcb1..0b79ddec15b7 100644 +--- a/drivers/net/bonding/bond_alb.c ++++ b/drivers/net/bonding/bond_alb.c +@@ -71,11 +71,6 @@ struct arp_pkt { + }; + #pragma pack() + +-static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb) +-{ +- return (struct arp_pkt *)skb_network_header(skb); +-} +- + /* Forward declaration */ + static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], + bool strict_match); +@@ -574,10 +569,11 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) + spin_unlock(&bond->mode_lock); + } + +-static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond) ++static struct slave *rlb_choose_channel(struct sk_buff *skb, ++ struct bonding *bond, ++ const struct arp_pkt *arp) + { + struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); +- struct arp_pkt *arp = arp_pkt(skb); + struct slave *assigned_slave, *curr_active_slave; + struct rlb_client_info *client_info; + u32 hash_index = 0; +@@ -674,8 +670,12 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon + */ + static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) + { +- struct arp_pkt *arp = arp_pkt(skb); + struct slave *tx_slave = NULL; ++ struct arp_pkt *arp; ++ ++ if (!pskb_network_may_pull(skb, sizeof(*arp))) ++ return NULL; ++ arp = (struct arp_pkt *)skb_network_header(skb); + + /* Don't modify or load balance ARPs that do not originate locally + * (e.g.,arrive via a bridge). +@@ -685,7 +685,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) + + if (arp->op_code == htons(ARPOP_REPLY)) { + /* the arp must be sent on the selected rx channel */ +- tx_slave = rlb_choose_channel(skb, bond); ++ tx_slave = rlb_choose_channel(skb, bond, arp); + if (tx_slave) + bond_hw_addr_copy(arp->mac_src, tx_slave->dev->dev_addr, + tx_slave->dev->addr_len); +@@ -696,7 +696,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) + * When the arp reply is received the entry will be updated + * with the correct unicast address of the client. + */ +- rlb_choose_channel(skb, bond); ++ rlb_choose_channel(skb, bond, arp); + + /* The ARP reply packets must be delayed so that + * they can cancel out the influence of the ARP request. +diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c +index d92113db4fb9..05ad5ed145a3 100644 +--- a/drivers/net/can/dev.c ++++ b/drivers/net/can/dev.c +@@ -867,6 +867,7 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { + = { .len = sizeof(struct can_bittiming) }, + [IFLA_CAN_DATA_BITTIMING_CONST] + = { .len = sizeof(struct can_bittiming_const) }, ++ [IFLA_CAN_TERMINATION] = { .type = NLA_U16 }, + }; + + static int can_validate(struct nlattr *tb[], struct nlattr *data[], +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 41bc7820d2dd..5163da01e54f 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -7310,13 +7310,13 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu) + struct bnxt *bp = netdev_priv(dev); + + if (netif_running(dev)) +- bnxt_close_nic(bp, false, false); ++ bnxt_close_nic(bp, true, false); + + dev->mtu = new_mtu; + bnxt_set_ring_params(bp); + + if (netif_running(dev)) +- return bnxt_open_nic(bp, false, false); ++ return bnxt_open_nic(bp, true, false); + + return 0; + } +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 62bc19bedb06..8ba915cc4c2e 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -2478,15 +2478,15 @@ fec_enet_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec) + return -EINVAL; + } + +- cycle = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr); ++ cycle = fec_enet_us_to_itr_clock(ndev, ec->rx_coalesce_usecs); + if (cycle > 0xFFFF) { + pr_err("Rx coalesced usec exceed hardware limitation\n"); + return -EINVAL; + } + +- cycle = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr); ++ cycle = fec_enet_us_to_itr_clock(ndev, ec->tx_coalesce_usecs); + if (cycle > 0xFFFF) { +- pr_err("Rx coalesced usec exceed hardware limitation\n"); ++ pr_err("Tx coalesced usec exceed hardware limitation\n"); + return -EINVAL; + } + +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +index 79b567447084..46aba02b8672 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +@@ -312,6 +312,7 @@ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth, + } + + hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); ++ hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); + + hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT; + hw_ioctxt.cmdq_depth = 0; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +index 0f5563f3b779..a011fd2d2627 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +@@ -104,8 +104,8 @@ struct hinic_cmd_hw_ioctxt { + + u8 rsvd2; + u8 rsvd3; ++ u8 ppf_idx; + u8 rsvd4; +- u8 rsvd5; + + u16 rq_depth; + u16 rx_buf_sz_idx; +diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +index 5b4760c0e9f5..f683ccbdfca0 100644 +--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h ++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +@@ -146,6 +146,7 @@ + #define HINIC_HWIF_FUNC_IDX(hwif) ((hwif)->attr.func_idx) + #define HINIC_HWIF_PCI_INTF(hwif) ((hwif)->attr.pci_intf_idx) + #define HINIC_HWIF_PF_IDX(hwif) ((hwif)->attr.pf_idx) ++#define HINIC_HWIF_PPF_IDX(hwif) ((hwif)->attr.ppf_idx) + + #define HINIC_FUNC_TYPE(hwif) ((hwif)->attr.func_type) + #define HINIC_IS_PF(hwif) (HINIC_FUNC_TYPE(hwif) == HINIC_PF) +diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c +index 799154d7c047..c699a779757e 100644 +--- a/drivers/net/ethernet/micrel/ks8851_mll.c ++++ b/drivers/net/ethernet/micrel/ks8851_mll.c +@@ -831,14 +831,17 @@ static irqreturn_t ks_irq(int irq, void *pw) + { + struct net_device *netdev = pw; + struct ks_net *ks = netdev_priv(netdev); ++ unsigned long flags; + u16 status; + ++ spin_lock_irqsave(&ks->statelock, flags); + /*this should be the first in IRQ handler */ + ks_save_cmd_reg(ks); + + status = ks_rdreg16(ks, KS_ISR); + if (unlikely(!status)) { + ks_restore_cmd_reg(ks); ++ spin_unlock_irqrestore(&ks->statelock, flags); + return IRQ_NONE; + } + +@@ -864,6 +867,7 @@ static irqreturn_t ks_irq(int irq, void *pw) + ks->netdev->stats.rx_over_errors++; + /* this should be the last in IRQ handler*/ + ks_restore_cmd_reg(ks); ++ spin_unlock_irqrestore(&ks->statelock, flags); + return IRQ_HANDLED; + } + +@@ -933,6 +937,7 @@ static int ks_net_stop(struct net_device *netdev) + + /* shutdown RX/TX QMU */ + ks_disable_qmu(ks); ++ ks_disable_int(ks); + + /* set powermode to soft power down to save power */ + ks_set_powermode(ks, PMECR_PM_SOFTDOWN); +@@ -989,10 +994,9 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) + { + netdev_tx_t retv = NETDEV_TX_OK; + struct ks_net *ks = netdev_priv(netdev); ++ unsigned long flags; + +- disable_irq(netdev->irq); +- ks_disable_int(ks); +- spin_lock(&ks->statelock); ++ spin_lock_irqsave(&ks->statelock, flags); + + /* Extra space are required: + * 4 byte for alignment, 4 for status/length, 4 for CRC +@@ -1006,9 +1010,7 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) + dev_kfree_skb(skb); + } else + retv = NETDEV_TX_BUSY; +- spin_unlock(&ks->statelock); +- ks_enable_int(ks); +- enable_irq(netdev->irq); ++ spin_unlock_irqrestore(&ks->statelock, flags); + return retv; + } + +diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +index 7d8303e45f09..b7df8c1121e3 100644 +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +@@ -157,6 +157,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, + int err = 0; + u16 mux_id; + ++ if (!tb[IFLA_LINK]) { ++ NL_SET_ERR_MSG_MOD(extack, "link not specified"); ++ return -EINVAL; ++ } ++ + real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK])); + if (!real_dev || !dev) + return -ENODEV; +diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c +index b9cb697b2818..e0d4c1e850cf 100644 +--- a/drivers/net/ethernet/sfc/efx.c ++++ b/drivers/net/ethernet/sfc/efx.c +@@ -505,6 +505,7 @@ efx_copy_channel(const struct efx_channel *old_channel) + if (tx_queue->channel) + tx_queue->channel = channel; + tx_queue->buffer = NULL; ++ tx_queue->cb_page = NULL; + memset(&tx_queue->txd, 0, sizeof(tx_queue->txd)); + } + +diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c +index 71ff6bd4be9f..baf8aab59f82 100644 +--- a/drivers/net/ipvlan/ipvlan_core.c ++++ b/drivers/net/ipvlan/ipvlan_core.c +@@ -256,6 +256,7 @@ void ipvlan_process_multicast(struct work_struct *work) + } + if (dev) + dev_put(dev); ++ cond_resched(); + } + } + +@@ -448,19 +449,21 @@ static int ipvlan_process_outbound(struct sk_buff *skb) + struct ethhdr *ethh = eth_hdr(skb); + int ret = NET_XMIT_DROP; + +- /* In this mode we dont care about multicast and broadcast traffic */ +- if (is_multicast_ether_addr(ethh->h_dest)) { +- pr_warn_ratelimited("Dropped {multi|broad}cast of type= [%x]\n", +- ntohs(skb->protocol)); +- kfree_skb(skb); +- goto out; +- } +- + /* The ipvlan is a pseudo-L2 device, so the packets that we receive + * will have L2; which need to discarded and processed further + * in the net-ns of the main-device. + */ + if (skb_mac_header_was_set(skb)) { ++ /* In this mode we dont care about ++ * multicast and broadcast traffic */ ++ if (is_multicast_ether_addr(ethh->h_dest)) { ++ pr_debug_ratelimited( ++ "Dropped {multi|broad}cast of type=[%x]\n", ++ ntohs(skb->protocol)); ++ kfree_skb(skb); ++ goto out; ++ } ++ + skb_pull(skb, sizeof(*ethh)); + skb->mac_header = (typeof(skb->mac_header))~0U; + skb_reset_network_header(skb); +diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c +index 09f6795cce53..cd32d6623f6a 100644 +--- a/drivers/net/ipvlan/ipvlan_main.c ++++ b/drivers/net/ipvlan/ipvlan_main.c +@@ -236,7 +236,6 @@ static void ipvlan_uninit(struct net_device *dev) + static int ipvlan_open(struct net_device *dev) + { + struct ipvl_dev *ipvlan = netdev_priv(dev); +- struct net_device *phy_dev = ipvlan->phy_dev; + struct ipvl_addr *addr; + + if (ipvlan->port->mode == IPVLAN_MODE_L3 || +@@ -248,7 +247,7 @@ static int ipvlan_open(struct net_device *dev) + list_for_each_entry(addr, &ipvlan->addrs, anode) + ipvlan_ht_addr_add(ipvlan, addr); + +- return dev_uc_add(phy_dev, phy_dev->dev_addr); ++ return 0; + } + + static int ipvlan_stop(struct net_device *dev) +@@ -260,8 +259,6 @@ static int ipvlan_stop(struct net_device *dev) + dev_uc_unsync(phy_dev, dev); + dev_mc_unsync(phy_dev, dev); + +- dev_uc_del(phy_dev, phy_dev->dev_addr); +- + list_for_each_entry(addr, &ipvlan->addrs, anode) + ipvlan_ht_addr_del(addr); + +diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c +index 9bb65e0af7dd..c2c3ce5653db 100644 +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -2871,6 +2871,11 @@ static void macsec_dev_set_rx_mode(struct net_device *dev) + dev_uc_sync(real_dev, dev); + } + ++static sci_t dev_to_sci(struct net_device *dev, __be16 port) ++{ ++ return make_sci(dev->dev_addr, port); ++} ++ + static int macsec_set_mac_address(struct net_device *dev, void *p) + { + struct macsec_dev *macsec = macsec_priv(dev); +@@ -2892,6 +2897,7 @@ static int macsec_set_mac_address(struct net_device *dev, void *p) + + out: + ether_addr_copy(dev->dev_addr, addr->sa_data); ++ macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES); + return 0; + } + +@@ -2974,6 +2980,7 @@ static const struct device_type macsec_type = { + + static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = { + [IFLA_MACSEC_SCI] = { .type = NLA_U64 }, ++ [IFLA_MACSEC_PORT] = { .type = NLA_U16 }, + [IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 }, + [IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 }, + [IFLA_MACSEC_WINDOW] = { .type = NLA_U32 }, +@@ -3159,11 +3166,6 @@ static bool sci_exists(struct net_device *dev, sci_t sci) + return false; + } + +-static sci_t dev_to_sci(struct net_device *dev, __be16 port) +-{ +- return make_sci(dev->dev_addr, port); +-} +- + static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len) + { + struct macsec_dev *macsec = macsec_priv(dev); +diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c +index ab539136d5bf..6989e84670e5 100644 +--- a/drivers/net/macvlan.c ++++ b/drivers/net/macvlan.c +@@ -338,6 +338,8 @@ static void macvlan_process_broadcast(struct work_struct *w) + if (src) + dev_put(src->dev); + kfree_skb(skb); ++ ++ cond_resched(); + } + } + +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index 99dae55cd334..27f1f0b5b8f6 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -76,7 +76,7 @@ static LIST_HEAD(phy_fixup_list); + static DEFINE_MUTEX(phy_fixup_lock); + + #ifdef CONFIG_PM +-static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend) ++static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) + { + struct device_driver *drv = phydev->mdio.dev.driver; + struct phy_driver *phydrv = to_phy_driver(drv); +@@ -88,11 +88,10 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend) + /* PHY not attached? May suspend if the PHY has not already been + * suspended as part of a prior call to phy_disconnect() -> + * phy_detach() -> phy_suspend() because the parent netdev might be the +- * MDIO bus driver and clock gated at this point. Also may resume if +- * PHY is not attached. ++ * MDIO bus driver and clock gated at this point. + */ + if (!netdev) +- return suspend ? !phydev->suspended : phydev->suspended; ++ goto out; + + /* Don't suspend PHY if the attached netdev parent may wakeup. + * The parent may point to a PCI device, as in tg3 driver. +@@ -107,7 +106,8 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev, bool suspend) + if (device_may_wakeup(&netdev->dev)) + return false; + +- return true; ++out: ++ return !phydev->suspended; + } + + static int mdio_bus_phy_suspend(struct device *dev) +@@ -122,9 +122,11 @@ static int mdio_bus_phy_suspend(struct device *dev) + if (phydev->attached_dev && phydev->adjust_link) + phy_stop_machine(phydev); + +- if (!mdio_bus_phy_may_suspend(phydev, true)) ++ if (!mdio_bus_phy_may_suspend(phydev)) + return 0; + ++ phydev->suspended_by_mdio_bus = true; ++ + return phy_suspend(phydev); + } + +@@ -133,9 +135,11 @@ static int mdio_bus_phy_resume(struct device *dev) + struct phy_device *phydev = to_phy_device(dev); + int ret; + +- if (!mdio_bus_phy_may_suspend(phydev, false)) ++ if (!phydev->suspended_by_mdio_bus) + goto no_resume; + ++ phydev->suspended_by_mdio_bus = false; ++ + ret = phy_resume(phydev); + if (ret < 0) + return ret; +diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c +index ea90db3c7705..01334aeac577 100644 +--- a/drivers/net/slip/slhc.c ++++ b/drivers/net/slip/slhc.c +@@ -232,7 +232,7 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + register struct cstate *cs = lcs->next; + register unsigned long deltaS, deltaA; + register short changes = 0; +- int hlen; ++ int nlen, hlen; + unsigned char new_seq[16]; + register unsigned char *cp = new_seq; + struct iphdr *ip; +@@ -248,6 +248,8 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + return isize; + + ip = (struct iphdr *) icp; ++ if (ip->version != 4 || ip->ihl < 5) ++ return isize; + + /* Bail if this packet isn't TCP, or is an IP fragment */ + if (ip->protocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) { +@@ -258,10 +260,14 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + comp->sls_o_tcp++; + return isize; + } +- /* Extract TCP header */ ++ nlen = ip->ihl * 4; ++ if (isize < nlen + sizeof(*th)) ++ return isize; + +- th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); +- hlen = ip->ihl*4 + th->doff*4; ++ th = (struct tcphdr *)(icp + nlen); ++ if (th->doff < sizeof(struct tcphdr) / 4) ++ return isize; ++ hlen = nlen + th->doff * 4; + + /* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or + * some other control bit is set). Also uncompressible if +diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c +index b07f367abd91..d7882b548b79 100644 +--- a/drivers/net/slip/slip.c ++++ b/drivers/net/slip/slip.c +@@ -867,7 +867,10 @@ err_free_chan: + tty->disc_data = NULL; + clear_bit(SLF_INUSE, &sl->flags); + sl_free_netdev(sl->dev); ++ /* do not call free_netdev before rtnl_unlock */ ++ rtnl_unlock(); + free_netdev(sl->dev); ++ return err; + + err_exit: + rtnl_unlock(); +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index f1aabf8a16c2..3dba58fa3433 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -2207,6 +2207,8 @@ team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = { + [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG }, + [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 }, + [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY }, ++ [TEAM_ATTR_OPTION_PORT_IFINDEX] = { .type = NLA_U32 }, ++ [TEAM_ATTR_OPTION_ARRAY_INDEX] = { .type = NLA_U32 }, + }; + + static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index 189715438328..a8d5561afc7d 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -274,6 +274,9 @@ static void qmi_wwan_netdev_setup(struct net_device *net) + netdev_dbg(net, "mode: raw IP\n"); + } else if (!net->header_ops) { /* don't bother if already set */ + ether_setup(net); ++ /* Restoring min/max mtu values set originally by usbnet */ ++ net->min_mtu = 0; ++ net->max_mtu = ETH_MAX_MTU; + clear_bit(EVENT_NO_IP_ALIGN, &dev->flags); + netdev_dbg(net, "mode: Ethernet\n"); + } +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index a7f9c1886bd4..cadf5ded45a9 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -2696,6 +2696,8 @@ static u16 r8153_phy_status(struct r8152 *tp, u16 desired) + } + + msleep(20); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ break; + } + + return data; +@@ -4055,7 +4057,10 @@ static void r8153_init(struct r8152 *tp) + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & + AUTOLOAD_DONE) + break; ++ + msleep(20); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ break; + } + + data = r8153_phy_status(tp, 0); +@@ -4170,7 +4175,10 @@ static void r8153b_init(struct r8152 *tp) + if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & + AUTOLOAD_DONE) + break; ++ + msleep(20); ++ if (test_bit(RTL8152_UNPLUG, &tp->flags)) ++ break; + } + + data = r8153_phy_status(tp, 0); +diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +index 8f3032b7174d..b2e393c4fab5 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c ++++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +@@ -326,7 +326,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) + } + + /* PHY_SKU section is mandatory in B0 */ +- if (!mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { ++ if (mvm->trans->cfg->nvm_type == IWL_NVM_EXT && ++ !mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { + IWL_ERR(mvm, + "Can't parse phy_sku in B0, empty sections\n"); + return NULL; +diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c +index c55517312485..08ea74177de2 100644 +--- a/drivers/pinctrl/core.c ++++ b/drivers/pinctrl/core.c +@@ -2031,7 +2031,6 @@ static int pinctrl_claim_hogs(struct pinctrl_dev *pctldev) + return PTR_ERR(pctldev->p); + } + +- kref_get(&pctldev->p->users); + pctldev->hog_default = + pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT); + if (IS_ERR(pctldev->hog_default)) { +diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +index 36c14b85fc7c..8db182067ecb 100644 +--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c ++++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c +@@ -158,8 +158,8 @@ static const unsigned int sdio_d0_pins[] = { PIN(GPIOX_0, EE_OFF) }; + static const unsigned int sdio_d1_pins[] = { PIN(GPIOX_1, EE_OFF) }; + static const unsigned int sdio_d2_pins[] = { PIN(GPIOX_2, EE_OFF) }; + static const unsigned int sdio_d3_pins[] = { PIN(GPIOX_3, EE_OFF) }; +-static const unsigned int sdio_cmd_pins[] = { PIN(GPIOX_4, EE_OFF) }; +-static const unsigned int sdio_clk_pins[] = { PIN(GPIOX_5, EE_OFF) }; ++static const unsigned int sdio_clk_pins[] = { PIN(GPIOX_4, EE_OFF) }; ++static const unsigned int sdio_cmd_pins[] = { PIN(GPIOX_5, EE_OFF) }; + static const unsigned int sdio_irq_pins[] = { PIN(GPIOX_7, EE_OFF) }; + + static const unsigned int nand_ce0_pins[] = { PIN(BOOT_8, EE_OFF) }; +diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c +index bb9c1c016643..28b50ab2fbb0 100644 +--- a/drivers/scsi/libfc/fc_disc.c ++++ b/drivers/scsi/libfc/fc_disc.c +@@ -652,6 +652,8 @@ redisc: + } + out: + kref_put(&rdata->kref, fc_rport_destroy); ++ if (!IS_ERR(fp)) ++ fc_frame_free(fp); + } + + /** +diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c +index f00a7ce3eb6e..03293e543c07 100644 +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -562,7 +562,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, + if (server->ops->close) + server->ops->close(xid, tcon, &fid); + cifs_del_pending_open(&open); +- fput(file); + rc = -ENOMEM; + } + +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index c850579ae5a4..6c6401084d3d 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -1255,7 +1255,7 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, + if (!(*opened & FILE_OPENED)) + return finish_no_open(file, d); + dput(d); +- return 0; ++ return excl && (flags & O_CREAT) ? -EEXIST : 0; + } + + BUG_ON(d != NULL); +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index f2ff141a4479..a355ca418e78 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -1050,8 +1050,8 @@ static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh, + /* For undo access buffer must have data copied */ + if (undo && !jh->b_committed_data) + goto out; +- if (jh->b_transaction != handle->h_transaction && +- jh->b_next_transaction != handle->h_transaction) ++ if (READ_ONCE(jh->b_transaction) != handle->h_transaction && ++ READ_ONCE(jh->b_next_transaction) != handle->h_transaction) + goto out; + /* + * There are two reasons for the barrier here: +@@ -2466,8 +2466,8 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh) + * our jh reference and thus __jbd2_journal_file_buffer() must not + * take a new one. + */ +- jh->b_transaction = jh->b_next_transaction; +- jh->b_next_transaction = NULL; ++ WRITE_ONCE(jh->b_transaction, jh->b_next_transaction); ++ WRITE_ONCE(jh->b_next_transaction, NULL); + if (buffer_freed(bh)) + jlist = BJ_Forget; + else if (jh->b_modified) +diff --git a/fs/open.c b/fs/open.c +index 29a2cdcbcb17..49fd070be0ec 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -824,9 +824,6 @@ cleanup_file: + * the return value of d_splice_alias(), then the caller needs to perform dput() + * on it after finish_open(). + * +- * On successful return @file is a fully instantiated open file. After this, if +- * an error occurs in ->atomic_open(), it needs to clean up with fput(). +- * + * Returns zero on success or -errno if the open failed. + */ + int finish_open(struct file *file, struct dentry *dentry, +diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h +index 0e21619f1c03..61ab21c34866 100644 +--- a/include/linux/cgroup.h ++++ b/include/linux/cgroup.h +@@ -61,6 +61,7 @@ struct css_task_iter { + struct list_head *mg_tasks_head; + struct list_head *dying_tasks_head; + ++ struct list_head *cur_tasks_head; + struct css_set *cur_cset; + struct css_set *cur_dcset; + struct task_struct *cur_task; +diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h +index 39faaaf843e1..c91cf2dee12a 100644 +--- a/include/linux/inet_diag.h ++++ b/include/linux/inet_diag.h +@@ -2,15 +2,10 @@ + #ifndef _INET_DIAG_H_ + #define _INET_DIAG_H_ 1 + ++#include <net/netlink.h> + #include <uapi/linux/inet_diag.h> + +-struct net; +-struct sock; + struct inet_hashinfo; +-struct nlattr; +-struct nlmsghdr; +-struct sk_buff; +-struct netlink_callback; + + struct inet_diag_handler { + void (*dump)(struct sk_buff *skb, +@@ -62,6 +57,17 @@ int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk); + + void inet_diag_msg_common_fill(struct inet_diag_msg *r, struct sock *sk); + ++static inline size_t inet_diag_msg_attrs_size(void) ++{ ++ return nla_total_size(1) /* INET_DIAG_SHUTDOWN */ ++ + nla_total_size(1) /* INET_DIAG_TOS */ ++#if IS_ENABLED(CONFIG_IPV6) ++ + nla_total_size(1) /* INET_DIAG_TCLASS */ ++ + nla_total_size(1) /* INET_DIAG_SKV6ONLY */ ++#endif ++ + nla_total_size(4) /* INET_DIAG_MARK */ ++ + nla_total_size(4); /* INET_DIAG_CLASS_ID */ ++} + int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb, + struct inet_diag_msg *r, int ext, + struct user_namespace *user_ns, bool net_admin); +diff --git a/include/linux/phy.h b/include/linux/phy.h +index efc04c2d92c9..8b6850707e62 100644 +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -372,6 +372,7 @@ struct phy_c45_device_ids { + * is_pseudo_fixed_link: Set to true if this phy is an Ethernet switch, etc. + * has_fixups: Set to true if this phy has fixups/quirks. + * suspended: Set to true if this phy has been suspended successfully. ++ * suspended_by_mdio_bus: Set to true if this phy was suspended by MDIO bus. + * sysfs_links: Internal boolean tracking sysfs symbolic links setup/removal. + * loopback_enabled: Set true if this phy has been loopbacked successfully. + * state: state of the PHY for management purposes +@@ -410,6 +411,7 @@ struct phy_device { + bool is_pseudo_fixed_link; + bool has_fixups; + bool suspended; ++ bool suspended_by_mdio_bus; + bool sysfs_links; + bool loopback_enabled; + +diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h +index 648caf90ec07..b8fd023ba625 100644 +--- a/include/net/fib_rules.h ++++ b/include/net/fib_rules.h +@@ -102,6 +102,7 @@ struct fib_rule_notifier_info { + [FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ + [FRA_PRIORITY] = { .type = NLA_U32 }, \ + [FRA_FWMARK] = { .type = NLA_U32 }, \ ++ [FRA_TUN_ID] = { .type = NLA_U64 }, \ + [FRA_FWMASK] = { .type = NLA_U32 }, \ + [FRA_TABLE] = { .type = NLA_U32 }, \ + [FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \ +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index 829943aad7be..2b3f2ea6a8a3 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -4051,12 +4051,16 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it) + } + } while (!css_set_populated(cset) && list_empty(&cset->dying_tasks)); + +- if (!list_empty(&cset->tasks)) ++ if (!list_empty(&cset->tasks)) { + it->task_pos = cset->tasks.next; +- else if (!list_empty(&cset->mg_tasks)) ++ it->cur_tasks_head = &cset->tasks; ++ } else if (!list_empty(&cset->mg_tasks)) { + it->task_pos = cset->mg_tasks.next; +- else ++ it->cur_tasks_head = &cset->mg_tasks; ++ } else { + it->task_pos = cset->dying_tasks.next; ++ it->cur_tasks_head = &cset->dying_tasks; ++ } + + it->tasks_head = &cset->tasks; + it->mg_tasks_head = &cset->mg_tasks; +@@ -4114,10 +4118,14 @@ repeat: + else + it->task_pos = it->task_pos->next; + +- if (it->task_pos == it->tasks_head) ++ if (it->task_pos == it->tasks_head) { + it->task_pos = it->mg_tasks_head->next; +- if (it->task_pos == it->mg_tasks_head) ++ it->cur_tasks_head = it->mg_tasks_head; ++ } ++ if (it->task_pos == it->mg_tasks_head) { + it->task_pos = it->dying_tasks_head->next; ++ it->cur_tasks_head = it->dying_tasks_head; ++ } + if (it->task_pos == it->dying_tasks_head) + css_task_iter_advance_css_set(it); + } else { +@@ -4136,11 +4144,12 @@ repeat: + goto repeat; + + /* and dying leaders w/o live member threads */ +- if (!atomic_read(&task->signal->live)) ++ if (it->cur_tasks_head == it->dying_tasks_head && ++ !atomic_read(&task->signal->live)) + goto repeat; + } else { + /* skip all dying ones */ +- if (task->flags & PF_EXITING) ++ if (it->cur_tasks_head == it->dying_tasks_head) + goto repeat; + } + } +@@ -4249,6 +4258,9 @@ static void *cgroup_procs_next(struct seq_file *s, void *v, loff_t *pos) + struct kernfs_open_file *of = s->private; + struct css_task_iter *it = of->priv; + ++ if (pos) ++ (*pos)++; ++ + return css_task_iter_next(it); + } + +@@ -4264,7 +4276,7 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos, + * from position 0, so we can simply keep iterating on !0 *pos. + */ + if (!it) { +- if (WARN_ON_ONCE((*pos)++)) ++ if (WARN_ON_ONCE((*pos))) + return ERR_PTR(-EINVAL); + + it = kzalloc(sizeof(*it), GFP_KERNEL); +@@ -4272,10 +4284,11 @@ static void *__cgroup_procs_start(struct seq_file *s, loff_t *pos, + return ERR_PTR(-ENOMEM); + of->priv = it; + css_task_iter_start(&cgrp->self, iter_flags, it); +- } else if (!(*pos)++) { ++ } else if (!(*pos)) { + css_task_iter_end(it); + css_task_iter_start(&cgrp->self, iter_flags, it); +- } ++ } else ++ return it->cur_task; + + return cgroup_procs_next(s, NULL, NULL); + } +@@ -5799,6 +5812,10 @@ void cgroup_sk_alloc(struct sock_cgroup_data *skcd) + return; + } + ++ /* Don't associate the sock with unrelated interrupted task's cgroup. */ ++ if (in_interrupt()) ++ return; ++ + rcu_read_lock(); + + while (true) { +diff --git a/kernel/signal.c b/kernel/signal.c +index 8fee1f2eba2f..c066168f8854 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -379,27 +379,32 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi + { + struct sigqueue *q = NULL; + struct user_struct *user; ++ int sigpending; + + /* + * Protect access to @t credentials. This can go away when all + * callers hold rcu read lock. ++ * ++ * NOTE! A pending signal will hold on to the user refcount, ++ * and we get/put the refcount only when the sigpending count ++ * changes from/to zero. + */ + rcu_read_lock(); +- user = get_uid(__task_cred(t)->user); +- atomic_inc(&user->sigpending); ++ user = __task_cred(t)->user; ++ sigpending = atomic_inc_return(&user->sigpending); ++ if (sigpending == 1) ++ get_uid(user); + rcu_read_unlock(); + +- if (override_rlimit || +- atomic_read(&user->sigpending) <= +- task_rlimit(t, RLIMIT_SIGPENDING)) { ++ if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) { + q = kmem_cache_alloc(sigqueue_cachep, flags); + } else { + print_dropped_signal(sig); + } + + if (unlikely(q == NULL)) { +- atomic_dec(&user->sigpending); +- free_uid(user); ++ if (atomic_dec_and_test(&user->sigpending)) ++ free_uid(user); + } else { + INIT_LIST_HEAD(&q->list); + q->flags = 0; +@@ -413,8 +418,8 @@ static void __sigqueue_free(struct sigqueue *q) + { + if (q->flags & SIGQUEUE_PREALLOC) + return; +- atomic_dec(&q->user->sigpending); +- free_uid(q->user); ++ if (atomic_dec_and_test(&q->user->sigpending)) ++ free_uid(q->user); + kmem_cache_free(sigqueue_cachep, q); + } + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index a37f5dc7cb39..18fae55713b0 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -1386,14 +1386,16 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, + WARN_ON_ONCE(!is_chained_work(wq))) + return; + retry: +- if (req_cpu == WORK_CPU_UNBOUND) +- cpu = wq_select_unbound_cpu(raw_smp_processor_id()); +- + /* pwq which will be used unless @work is executing elsewhere */ +- if (!(wq->flags & WQ_UNBOUND)) +- pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); +- else ++ if (wq->flags & WQ_UNBOUND) { ++ if (req_cpu == WORK_CPU_UNBOUND) ++ cpu = wq_select_unbound_cpu(raw_smp_processor_id()); + pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu)); ++ } else { ++ if (req_cpu == WORK_CPU_UNBOUND) ++ cpu = raw_smp_processor_id(); ++ pwq = per_cpu_ptr(wq->cpu_pwqs, cpu); ++ } + + /* + * If @work was previously on a different pool, it might still be +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index 326525a97c47..5d6ebd1449f0 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -5867,19 +5867,9 @@ void mem_cgroup_sk_alloc(struct sock *sk) + if (!mem_cgroup_sockets_enabled) + return; + +- /* +- * Socket cloning can throw us here with sk_memcg already +- * filled. It won't however, necessarily happen from +- * process context. So the test for root memcg given +- * the current task's memcg won't help us in this case. +- * +- * Respecting the original socket's memcg is a better +- * decision in this case. +- */ +- if (sk->sk_memcg) { +- css_get(&sk->sk_memcg->css); ++ /* Do not associate the sock with unrelated interrupted task's memcg. */ ++ if (in_interrupt()) + return; +- } + + rcu_read_lock(); + memcg = mem_cgroup_from_task(current); +diff --git a/mm/slub.c b/mm/slub.c +index 07aeb129f3f8..099c7a85ede0 100644 +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -3122,6 +3122,15 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, + void *object = c->freelist; + + if (unlikely(!object)) { ++ /* ++ * We may have removed an object from c->freelist using ++ * the fastpath in the previous iteration; in that case, ++ * c->tid has not been bumped yet. ++ * Since ___slab_alloc() may reenable interrupts while ++ * allocating memory, we should bump c->tid now. ++ */ ++ c->tid = next_tid(c->tid); ++ + /* + * Invoking slow path likely have side-effect + * of re-populating per CPU c->freelist +diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c +index 8b3f9441b3a0..7a723e124dbb 100644 +--- a/net/batman-adv/bat_iv_ogm.c ++++ b/net/batman-adv/bat_iv_ogm.c +@@ -34,6 +34,7 @@ + #include <linux/kref.h> + #include <linux/list.h> + #include <linux/lockdep.h> ++#include <linux/mutex.h> + #include <linux/netdevice.h> + #include <linux/netlink.h> + #include <linux/pkt_sched.h> +@@ -149,7 +150,7 @@ static void batadv_iv_ogm_orig_free(struct batadv_orig_node *orig_node) + * Return: 0 on success, a negative error code otherwise. + */ + static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node, +- int max_if_num) ++ unsigned int max_if_num) + { + void *data_ptr; + size_t old_size; +@@ -193,7 +194,8 @@ unlock: + */ + static void + batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node, +- int max_if_num, int del_if_num) ++ unsigned int max_if_num, ++ unsigned int del_if_num) + { + size_t chunk_size; + size_t if_offset; +@@ -231,7 +233,8 @@ batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node, + */ + static void + batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node, +- int max_if_num, int del_if_num) ++ unsigned int max_if_num, ++ unsigned int del_if_num) + { + size_t if_offset; + void *data_ptr; +@@ -268,7 +271,8 @@ batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node, + * Return: 0 on success, a negative error code otherwise. + */ + static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node, +- int max_if_num, int del_if_num) ++ unsigned int max_if_num, ++ unsigned int del_if_num) + { + spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); + +@@ -302,7 +306,8 @@ static struct batadv_orig_node * + batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr) + { + struct batadv_orig_node *orig_node; +- int size, hash_added; ++ int hash_added; ++ size_t size; + + orig_node = batadv_orig_hash_find(bat_priv, addr); + if (orig_node) +@@ -366,14 +371,18 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) + unsigned char *ogm_buff; + u32 random_seqno; + ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ + /* randomize initial seqno to avoid collision */ + get_random_bytes(&random_seqno, sizeof(random_seqno)); + atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno); + + hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN; + ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC); +- if (!ogm_buff) ++ if (!ogm_buff) { ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + return -ENOMEM; ++ } + + hard_iface->bat_iv.ogm_buff = ogm_buff; + +@@ -385,35 +394,59 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) + batadv_ogm_packet->reserved = 0; + batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; + ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); ++ + return 0; + } + + static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) + { ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ + kfree(hard_iface->bat_iv.ogm_buff); + hard_iface->bat_iv.ogm_buff = NULL; ++ ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + } + + static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) + { + struct batadv_ogm_packet *batadv_ogm_packet; +- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; ++ void *ogm_buff; + +- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ ++ ogm_buff = hard_iface->bat_iv.ogm_buff; ++ if (!ogm_buff) ++ goto unlock; ++ ++ batadv_ogm_packet = ogm_buff; + ether_addr_copy(batadv_ogm_packet->orig, + hard_iface->net_dev->dev_addr); + ether_addr_copy(batadv_ogm_packet->prev_sender, + hard_iface->net_dev->dev_addr); ++ ++unlock: ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + } + + static void + batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) + { + struct batadv_ogm_packet *batadv_ogm_packet; +- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; ++ void *ogm_buff; + +- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ ++ ogm_buff = hard_iface->bat_iv.ogm_buff; ++ if (!ogm_buff) ++ goto unlock; ++ ++ batadv_ogm_packet = ogm_buff; + batadv_ogm_packet->ttl = BATADV_TTL; ++ ++unlock: ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + } + + /* when do we schedule our own ogm to be sent */ +@@ -890,7 +923,7 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface) + u32 i; + size_t word_index; + u8 *w; +- int if_num; ++ unsigned int if_num; + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; +@@ -911,7 +944,11 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface) + } + } + +-static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) ++/** ++ * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer ++ * @hard_iface: interface whose ogm buffer should be transmitted ++ */ ++static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface) + { + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff; +@@ -922,8 +959,10 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) + u16 tvlv_len = 0; + unsigned long send_time; + +- if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) || +- (hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)) ++ lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex); ++ ++ /* interface already disabled by batadv_iv_ogm_iface_disable */ ++ if (!*ogm_buff) + return; + + /* the interface gets activated here to avoid race conditions between +@@ -992,6 +1031,17 @@ out: + batadv_hardif_put(primary_if); + } + ++static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) ++{ ++ if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || ++ hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) ++ return; ++ ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ batadv_iv_ogm_schedule_buff(hard_iface); ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); ++} ++ + /** + * batadv_iv_ogm_orig_update - use OGM to update corresponding data in an + * originator +@@ -1020,7 +1070,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, + struct batadv_neigh_node *tmp_neigh_node = NULL; + struct batadv_neigh_node *router = NULL; + struct batadv_orig_node *orig_node_tmp; +- int if_num; ++ unsigned int if_num; + u8 sum_orig, sum_neigh; + u8 *neigh_addr; + u8 tq_avg; +@@ -1179,7 +1229,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, + u8 total_count; + u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; + unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; +- int if_num; ++ unsigned int if_num; + unsigned int tq_asym_penalty, inv_asym_penalty; + unsigned int combined_tq; + unsigned int tq_iface_penalty; +@@ -1220,7 +1270,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, + orig_node->last_seen = jiffies; + + /* find packet count of corresponding one hop neighbor */ +- spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); ++ spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); + if_num = if_incoming->if_num; + orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num]; + neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing); +@@ -1230,7 +1280,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, + } else { + neigh_rq_count = 0; + } +- spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); ++ spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); + + /* pay attention to not get a value bigger than 100 % */ + if (orig_eq_count > neigh_rq_count) +@@ -1698,9 +1748,9 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset, + + if (is_my_orig) { + unsigned long *word; +- int offset; ++ size_t offset; + s32 bit_pos; +- s16 if_num; ++ unsigned int if_num; + u8 *weight; + + orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv, +@@ -2477,7 +2527,7 @@ batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1, + return ret; + } + +-static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface) ++static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface) + { + /* begin scheduling originator messages on that interface */ + batadv_iv_ogm_schedule(hard_iface); +@@ -2817,8 +2867,8 @@ unlock: + static struct batadv_algo_ops batadv_batman_iv __read_mostly = { + .name = "BATMAN_IV", + .iface = { +- .activate = batadv_iv_iface_activate, + .enable = batadv_iv_ogm_iface_enable, ++ .enabled = batadv_iv_iface_enabled, + .disable = batadv_iv_ogm_iface_disable, + .update_mac = batadv_iv_ogm_iface_update_mac, + .primary_set = batadv_iv_ogm_primary_iface_set, +diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c +index 371a1f1651b4..eb8cec14b854 100644 +--- a/net/batman-adv/bat_v.c ++++ b/net/batman-adv/bat_v.c +@@ -19,7 +19,6 @@ + #include "main.h" + + #include <linux/atomic.h> +-#include <linux/bug.h> + #include <linux/cache.h> + #include <linux/errno.h> + #include <linux/if_ether.h> +@@ -623,11 +622,11 @@ static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1, + int ret = 0; + + ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); +- if (WARN_ON(!ifinfo1)) ++ if (!ifinfo1) + goto err_ifinfo1; + + ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); +- if (WARN_ON(!ifinfo2)) ++ if (!ifinfo2) + goto err_ifinfo2; + + ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput; +@@ -649,11 +648,11 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, + bool ret = false; + + ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); +- if (WARN_ON(!ifinfo1)) ++ if (!ifinfo1) + goto err_ifinfo1; + + ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); +- if (WARN_ON(!ifinfo2)) ++ if (!ifinfo2) + goto err_ifinfo2; + + threshold = ifinfo1->bat_v.throughput / 4; +@@ -815,7 +814,7 @@ static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv, + } + + orig_gw = batadv_gw_node_get(bat_priv, orig_node); +- if (!orig_node) ++ if (!orig_gw) + goto out; + + if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0) +diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c +index e07f636160b6..cec31769bb3f 100644 +--- a/net/batman-adv/bat_v_ogm.c ++++ b/net/batman-adv/bat_v_ogm.c +@@ -28,6 +28,8 @@ + #include <linux/kernel.h> + #include <linux/kref.h> + #include <linux/list.h> ++#include <linux/lockdep.h> ++#include <linux/mutex.h> + #include <linux/netdevice.h> + #include <linux/random.h> + #include <linux/rculist.h> +@@ -127,14 +129,12 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb, + } + + /** +- * batadv_v_ogm_send - periodic worker broadcasting the own OGM +- * @work: work queue item ++ * batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM ++ * @bat_priv: the bat priv with all the soft interface information + */ +-static void batadv_v_ogm_send(struct work_struct *work) ++static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv) + { + struct batadv_hard_iface *hard_iface; +- struct batadv_priv_bat_v *bat_v; +- struct batadv_priv *bat_priv; + struct batadv_ogm2_packet *ogm_packet; + struct sk_buff *skb, *skb_tmp; + unsigned char *ogm_buff; +@@ -142,8 +142,7 @@ static void batadv_v_ogm_send(struct work_struct *work) + u16 tvlv_len = 0; + int ret; + +- bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); +- bat_priv = container_of(bat_v, struct batadv_priv, bat_v); ++ lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex); + + if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) + goto out; +@@ -234,6 +233,23 @@ out: + return; + } + ++/** ++ * batadv_v_ogm_send() - periodic worker broadcasting the own OGM ++ * @work: work queue item ++ */ ++static void batadv_v_ogm_send(struct work_struct *work) ++{ ++ struct batadv_priv_bat_v *bat_v; ++ struct batadv_priv *bat_priv; ++ ++ bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); ++ bat_priv = container_of(bat_v, struct batadv_priv, bat_v); ++ ++ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); ++ batadv_v_ogm_send_softif(bat_priv); ++ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); ++} ++ + /** + * batadv_v_ogm_iface_enable - prepare an interface for B.A.T.M.A.N. V + * @hard_iface: the interface to prepare +@@ -260,11 +276,15 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) + struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface); + struct batadv_ogm2_packet *ogm_packet; + ++ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); + if (!bat_priv->bat_v.ogm_buff) +- return; ++ goto unlock; + + ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff; + ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr); ++ ++unlock: ++ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); + } + + /** +@@ -886,6 +906,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv) + atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno); + INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send); + ++ mutex_init(&bat_priv->bat_v.ogm_buff_mutex); ++ + return 0; + } + +@@ -897,7 +919,11 @@ void batadv_v_ogm_free(struct batadv_priv *bat_priv) + { + cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq); + ++ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); ++ + kfree(bat_priv->bat_v.ogm_buff); + bat_priv->bat_v.ogm_buff = NULL; + bat_priv->bat_v.ogm_buff_len = 0; ++ ++ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); + } +diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c +index e32ad47c6efd..4957d4824437 100644 +--- a/net/batman-adv/debugfs.c ++++ b/net/batman-adv/debugfs.c +@@ -18,6 +18,7 @@ + #include "debugfs.h" + #include "main.h" + ++#include <linux/dcache.h> + #include <linux/debugfs.h> + #include <linux/err.h> + #include <linux/errno.h> +@@ -338,7 +339,26 @@ out: + } + + /** +- * batadv_debugfs_del_hardif - delete the base directory for a hard interface ++ * batadv_debugfs_rename_hardif() - Fix debugfs path for renamed hardif ++ * @hard_iface: hard interface which was renamed ++ */ ++void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface) ++{ ++ const char *name = hard_iface->net_dev->name; ++ struct dentry *dir; ++ struct dentry *d; ++ ++ dir = hard_iface->debug_dir; ++ if (!dir) ++ return; ++ ++ d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name); ++ if (!d) ++ pr_err("Can't rename debugfs dir to %s\n", name); ++} ++ ++/** ++ * batadv_debugfs_del_hardif() - delete the base directory for a hard interface + * in debugfs. + * @hard_iface: hard interface which is deleted. + */ +@@ -401,6 +421,30 @@ out: + return -ENOMEM; + } + ++/** ++ * batadv_debugfs_rename_meshif() - Fix debugfs path for renamed softif ++ * @dev: net_device which was renamed ++ */ ++void batadv_debugfs_rename_meshif(struct net_device *dev) ++{ ++ struct batadv_priv *bat_priv = netdev_priv(dev); ++ const char *name = dev->name; ++ struct dentry *dir; ++ struct dentry *d; ++ ++ dir = bat_priv->debug_dir; ++ if (!dir) ++ return; ++ ++ d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name); ++ if (!d) ++ pr_err("Can't rename debugfs dir to %s\n", name); ++} ++ ++/** ++ * batadv_debugfs_del_meshif() - Remove interface dependent debugfs entries ++ * @dev: netdev struct of the soft interface ++ */ + void batadv_debugfs_del_meshif(struct net_device *dev) + { + struct batadv_priv *bat_priv = netdev_priv(dev); +diff --git a/net/batman-adv/debugfs.h b/net/batman-adv/debugfs.h +index 9c5d4a65b98c..901bbc357bf4 100644 +--- a/net/batman-adv/debugfs.h ++++ b/net/batman-adv/debugfs.h +@@ -29,8 +29,10 @@ struct net_device; + void batadv_debugfs_init(void); + void batadv_debugfs_destroy(void); + int batadv_debugfs_add_meshif(struct net_device *dev); ++void batadv_debugfs_rename_meshif(struct net_device *dev); + void batadv_debugfs_del_meshif(struct net_device *dev); + int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface); ++void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface); + void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface); + + #else +@@ -48,6 +50,10 @@ static inline int batadv_debugfs_add_meshif(struct net_device *dev) + return 0; + } + ++static inline void batadv_debugfs_rename_meshif(struct net_device *dev) ++{ ++} ++ + static inline void batadv_debugfs_del_meshif(struct net_device *dev) + { + } +@@ -58,6 +64,11 @@ int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface) + return 0; + } + ++static inline ++void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface) ++{ ++} ++ + static inline + void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface) + { +diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c +index c6d37d22bd12..788d62073964 100644 +--- a/net/batman-adv/fragmentation.c ++++ b/net/batman-adv/fragmentation.c +@@ -500,6 +500,8 @@ int batadv_frag_send_packet(struct sk_buff *skb, + */ + if (skb->priority >= 256 && skb->priority <= 263) + frag_header.priority = skb->priority - 256; ++ else ++ frag_header.priority = 0; + + ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr); + ether_addr_copy(frag_header.dest, orig_node->orig); +diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c +index 2e1a084b0bd2..9fdfa9984f02 100644 +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -28,6 +28,7 @@ + #include <linux/kernel.h> + #include <linux/kref.h> + #include <linux/list.h> ++#include <linux/mutex.h> + #include <linux/netdevice.h> + #include <linux/printk.h> + #include <linux/rculist.h> +@@ -738,6 +739,11 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, + hard_iface->soft_iface = soft_iface; + bat_priv = netdev_priv(hard_iface->soft_iface); + ++ if (bat_priv->num_ifaces >= UINT_MAX) { ++ ret = -ENOSPC; ++ goto err_dev; ++ } ++ + ret = netdev_master_upper_dev_link(hard_iface->net_dev, + soft_iface, NULL, NULL); + if (ret) +@@ -790,6 +796,9 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, + + batadv_hardif_recalc_extra_skbroom(soft_iface); + ++ if (bat_priv->algo_ops->iface.enabled) ++ bat_priv->algo_ops->iface.enabled(hard_iface); ++ + out: + return 0; + +@@ -845,7 +854,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface, + batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface); + + /* nobody uses this interface anymore */ +- if (!bat_priv->num_ifaces) { ++ if (bat_priv->num_ifaces == 0) { + batadv_gw_check_client_stop(bat_priv); + + if (autodel == BATADV_IF_CLEANUP_AUTO) +@@ -881,7 +890,7 @@ batadv_hardif_add_interface(struct net_device *net_dev) + if (ret) + goto free_if; + +- hard_iface->if_num = -1; ++ hard_iface->if_num = 0; + hard_iface->net_dev = net_dev; + hard_iface->soft_iface = NULL; + hard_iface->if_status = BATADV_IF_NOT_IN_USE; +@@ -893,6 +902,7 @@ batadv_hardif_add_interface(struct net_device *net_dev) + INIT_LIST_HEAD(&hard_iface->list); + INIT_HLIST_HEAD(&hard_iface->neigh_list); + ++ mutex_init(&hard_iface->bat_iv.ogm_buff_mutex); + spin_lock_init(&hard_iface->neigh_list_lock); + kref_init(&hard_iface->refcount); + +@@ -950,6 +960,32 @@ void batadv_hardif_remove_interfaces(void) + rtnl_unlock(); + } + ++/** ++ * batadv_hard_if_event_softif() - Handle events for soft interfaces ++ * @event: NETDEV_* event to handle ++ * @net_dev: net_device which generated an event ++ * ++ * Return: NOTIFY_* result ++ */ ++static int batadv_hard_if_event_softif(unsigned long event, ++ struct net_device *net_dev) ++{ ++ struct batadv_priv *bat_priv; ++ ++ switch (event) { ++ case NETDEV_REGISTER: ++ batadv_sysfs_add_meshif(net_dev); ++ bat_priv = netdev_priv(net_dev); ++ batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS); ++ break; ++ case NETDEV_CHANGENAME: ++ batadv_debugfs_rename_meshif(net_dev); ++ break; ++ } ++ ++ return NOTIFY_DONE; ++} ++ + static int batadv_hard_if_event(struct notifier_block *this, + unsigned long event, void *ptr) + { +@@ -958,12 +994,8 @@ static int batadv_hard_if_event(struct notifier_block *this, + struct batadv_hard_iface *primary_if = NULL; + struct batadv_priv *bat_priv; + +- if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) { +- batadv_sysfs_add_meshif(net_dev); +- bat_priv = netdev_priv(net_dev); +- batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS); +- return NOTIFY_DONE; +- } ++ if (batadv_softif_is_valid(net_dev)) ++ return batadv_hard_if_event_softif(event, net_dev); + + hard_iface = batadv_hardif_get_by_netdev(net_dev); + if (!hard_iface && (event == NETDEV_REGISTER || +@@ -1012,6 +1044,9 @@ static int batadv_hard_if_event(struct notifier_block *this, + if (batadv_is_wifi_hardif(hard_iface)) + hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS; + break; ++ case NETDEV_CHANGENAME: ++ batadv_debugfs_rename_hardif(hard_iface); ++ break; + default: + break; + } +diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c +index 8e2a4b205257..653eaadcfefb 100644 +--- a/net/batman-adv/originator.c ++++ b/net/batman-adv/originator.c +@@ -1500,7 +1500,7 @@ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb) + } + + int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, +- int max_if_num) ++ unsigned int max_if_num) + { + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + struct batadv_algo_ops *bao = bat_priv->algo_ops; +@@ -1535,7 +1535,7 @@ err: + } + + int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, +- int max_if_num) ++ unsigned int max_if_num) + { + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + struct batadv_hashtable *hash = bat_priv->orig_hash; +diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h +index d94220a6d21a..d6ca52220ec0 100644 +--- a/net/batman-adv/originator.h ++++ b/net/batman-adv/originator.h +@@ -78,9 +78,9 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset); + int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb); + int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset); + int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, +- int max_if_num); ++ unsigned int max_if_num); + int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, +- int max_if_num); ++ unsigned int max_if_num); + struct batadv_orig_node_vlan * + batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node, + unsigned short vid); +diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c +index cd82cff716c7..f59aac06733e 100644 +--- a/net/batman-adv/routing.c ++++ b/net/batman-adv/routing.c +@@ -950,14 +950,10 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, + struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL; + int check, hdr_size = sizeof(*unicast_packet); + enum batadv_subtype subtype; +- struct ethhdr *ethhdr; + int ret = NET_RX_DROP; + bool is4addr, is_gw; + + unicast_packet = (struct batadv_unicast_packet *)skb->data; +- unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; +- ethhdr = eth_hdr(skb); +- + is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR; + /* the caller function should have already pulled 2 bytes */ + if (is4addr) +@@ -977,12 +973,14 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, + if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size)) + goto free_skb; + ++ unicast_packet = (struct batadv_unicast_packet *)skb->data; ++ + /* packet for me */ + if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { + /* If this is a unicast packet from another backgone gw, + * drop it. + */ +- orig_addr_gw = ethhdr->h_source; ++ orig_addr_gw = eth_hdr(skb)->h_source; + orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw); + if (orig_node_gw) { + is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw, +@@ -997,6 +995,8 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, + } + + if (is4addr) { ++ unicast_4addr_packet = ++ (struct batadv_unicast_4addr_packet *)skb->data; + subtype = unicast_4addr_packet->subtype; + batadv_dat_inc_counter(bat_priv, subtype); + +diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c +index 2c2670b85fa9..dbc516824175 100644 +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -872,7 +872,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, + struct batadv_orig_node_vlan *vlan; + u8 *tt_change_ptr; + +- rcu_read_lock(); ++ spin_lock_bh(&orig_node->vlan_list_lock); + hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { + num_vlan++; + num_entries += atomic_read(&vlan->tt.num_entries); +@@ -910,7 +910,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, + *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr; + + out: +- rcu_read_unlock(); ++ spin_unlock_bh(&orig_node->vlan_list_lock); + return tvlv_len; + } + +@@ -941,15 +941,20 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, + struct batadv_tvlv_tt_vlan_data *tt_vlan; + struct batadv_softif_vlan *vlan; + u16 num_vlan = 0; +- u16 num_entries = 0; ++ u16 vlan_entries = 0; ++ u16 total_entries = 0; + u16 tvlv_len; + u8 *tt_change_ptr; + int change_offset; + +- rcu_read_lock(); ++ spin_lock_bh(&bat_priv->softif_vlan_list_lock); + hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { ++ vlan_entries = atomic_read(&vlan->tt.num_entries); ++ if (vlan_entries < 1) ++ continue; ++ + num_vlan++; +- num_entries += atomic_read(&vlan->tt.num_entries); ++ total_entries += vlan_entries; + } + + change_offset = sizeof(**tt_data); +@@ -957,7 +962,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, + + /* if tt_len is negative, allocate the space needed by the full table */ + if (*tt_len < 0) +- *tt_len = batadv_tt_len(num_entries); ++ *tt_len = batadv_tt_len(total_entries); + + tvlv_len = *tt_len; + tvlv_len += change_offset; +@@ -974,6 +979,10 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, + + tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1); + hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) { ++ vlan_entries = atomic_read(&vlan->tt.num_entries); ++ if (vlan_entries < 1) ++ continue; ++ + tt_vlan->vid = htons(vlan->vid); + tt_vlan->crc = htonl(vlan->tt.crc); + +@@ -984,7 +993,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, + *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr; + + out: +- rcu_read_unlock(); ++ spin_unlock_bh(&bat_priv->softif_vlan_list_lock); + return tvlv_len; + } + +@@ -1544,6 +1553,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry, + * by a given originator + * @entry: the TT global entry to check + * @orig_node: the originator to search in the list ++ * @flags: a pointer to store TT flags for the given @entry received ++ * from @orig_node + * + * find out if an orig_node is already in the list of a tt_global_entry. + * +@@ -1551,7 +1562,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry, + */ + static bool + batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, +- const struct batadv_orig_node *orig_node) ++ const struct batadv_orig_node *orig_node, ++ u8 *flags) + { + struct batadv_tt_orig_list_entry *orig_entry; + bool found = false; +@@ -1559,6 +1571,10 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, + orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node); + if (orig_entry) { + found = true; ++ ++ if (flags) ++ *flags = orig_entry->flags; ++ + batadv_tt_orig_list_entry_put(orig_entry); + } + +@@ -1741,7 +1757,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, + if (!(common->flags & BATADV_TT_CLIENT_TEMP)) + goto out; + if (batadv_tt_global_entry_has_orig(tt_global_entry, +- orig_node)) ++ orig_node, NULL)) + goto out_remove; + batadv_tt_global_del_orig_list(tt_global_entry); + goto add_orig_entry; +@@ -2884,23 +2900,46 @@ unlock: + } + + /** +- * batadv_tt_local_valid - verify that given tt entry is a valid one ++ * batadv_tt_local_valid() - verify local tt entry and get flags + * @entry_ptr: to be checked local tt entry + * @data_ptr: not used but definition required to satisfy the callback prototype ++ * @flags: a pointer to store TT flags for this client to ++ * ++ * Checks the validity of the given local TT entry. If it is, then the provided ++ * flags pointer is updated. + * + * Return: true if the entry is a valid, false otherwise. + */ +-static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr) ++static bool batadv_tt_local_valid(const void *entry_ptr, ++ const void *data_ptr, ++ u8 *flags) + { + const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; + + if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW) + return false; ++ ++ if (flags) ++ *flags = tt_common_entry->flags; ++ + return true; + } + ++/** ++ * batadv_tt_global_valid() - verify global tt entry and get flags ++ * @entry_ptr: to be checked global tt entry ++ * @data_ptr: an orig_node object (may be NULL) ++ * @flags: a pointer to store TT flags for this client to ++ * ++ * Checks the validity of the given global TT entry. If it is, then the provided ++ * flags pointer is updated either with the common (summed) TT flags if data_ptr ++ * is NULL or the specific, per originator TT flags otherwise. ++ * ++ * Return: true if the entry is a valid, false otherwise. ++ */ + static bool batadv_tt_global_valid(const void *entry_ptr, +- const void *data_ptr) ++ const void *data_ptr, ++ u8 *flags) + { + const struct batadv_tt_common_entry *tt_common_entry = entry_ptr; + const struct batadv_tt_global_entry *tt_global_entry; +@@ -2914,7 +2953,8 @@ static bool batadv_tt_global_valid(const void *entry_ptr, + struct batadv_tt_global_entry, + common); + +- return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node); ++ return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node, ++ flags); + } + + /** +@@ -2924,25 +2964,34 @@ static bool batadv_tt_global_valid(const void *entry_ptr, + * @hash: hash table containing the tt entries + * @tt_len: expected tvlv tt data buffer length in number of bytes + * @tvlv_buff: pointer to the buffer to fill with the TT data +- * @valid_cb: function to filter tt change entries ++ * @valid_cb: function to filter tt change entries and to return TT flags + * @cb_data: data passed to the filter function as argument ++ * ++ * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb ++ * is not provided then this becomes a no-op. + */ + static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, + struct batadv_hashtable *hash, + void *tvlv_buff, u16 tt_len, + bool (*valid_cb)(const void *, +- const void *), ++ const void *, ++ u8 *flags), + void *cb_data) + { + struct batadv_tt_common_entry *tt_common_entry; + struct batadv_tvlv_tt_change *tt_change; + struct hlist_head *head; + u16 tt_tot, tt_num_entries = 0; ++ u8 flags; ++ bool ret; + u32 i; + + tt_tot = batadv_tt_entries(tt_len); + tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff; + ++ if (!valid_cb) ++ return; ++ + rcu_read_lock(); + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; +@@ -2952,11 +3001,12 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv, + if (tt_tot == tt_num_entries) + break; + +- if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data))) ++ ret = valid_cb(tt_common_entry, cb_data, &flags); ++ if (!ret) + continue; + + ether_addr_copy(tt_change->addr, tt_common_entry->addr); +- tt_change->flags = tt_common_entry->flags; ++ tt_change->flags = flags; + tt_change->vid = htons(tt_common_entry->vid); + memset(tt_change->reserved, 0, + sizeof(tt_change->reserved)); +diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h +index d5e3968619b8..540a9c5c2270 100644 +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -27,6 +27,7 @@ + #include <linux/compiler.h> + #include <linux/if_ether.h> + #include <linux/kref.h> ++#include <linux/mutex.h> + #include <linux/netdevice.h> + #include <linux/netlink.h> + #include <linux/sched.h> /* for linux/wait.h */ +@@ -81,11 +82,13 @@ enum batadv_dhcp_recipient { + * @ogm_buff: buffer holding the OGM packet + * @ogm_buff_len: length of the OGM packet buffer + * @ogm_seqno: OGM sequence number - used to identify each OGM ++ * @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len + */ + struct batadv_hard_iface_bat_iv { + unsigned char *ogm_buff; + int ogm_buff_len; + atomic_t ogm_seqno; ++ struct mutex ogm_buff_mutex; + }; + + /** +@@ -155,7 +158,7 @@ enum batadv_hard_iface_wifi_flags { + */ + struct batadv_hard_iface { + struct list_head list; +- s16 if_num; ++ unsigned int if_num; + char if_status; + u8 num_bcasts; + u32 wifi_flags; +@@ -989,12 +992,14 @@ struct batadv_softif_vlan { + * @ogm_buff: buffer holding the OGM packet + * @ogm_buff_len: length of the OGM packet buffer + * @ogm_seqno: OGM sequence number - used to identify each OGM ++ * @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len + * @ogm_wq: workqueue used to schedule OGM transmissions + */ + struct batadv_priv_bat_v { + unsigned char *ogm_buff; + int ogm_buff_len; + atomic_t ogm_seqno; ++ struct mutex ogm_buff_mutex; + struct delayed_work ogm_wq; + }; + +@@ -1081,7 +1086,7 @@ struct batadv_priv { + atomic_t bcast_seqno; + atomic_t bcast_queue_left; + atomic_t batman_queue_left; +- char num_ifaces; ++ unsigned int num_ifaces; + struct kobject *mesh_obj; + struct dentry *debug_dir; + struct hlist_head forw_bat_list; +@@ -1424,6 +1429,7 @@ struct batadv_forw_packet { + * @activate: start routing mechanisms when hard-interface is brought up + * (optional) + * @enable: init routing info when hard-interface is enabled ++ * @enabled: notification when hard-interface was enabled (optional) + * @disable: de-init routing info when hard-interface is disabled + * @update_mac: (re-)init mac addresses of the protocol information + * belonging to this hard-interface +@@ -1432,6 +1438,7 @@ struct batadv_forw_packet { + struct batadv_algo_iface_ops { + void (*activate)(struct batadv_hard_iface *hard_iface); + int (*enable)(struct batadv_hard_iface *hard_iface); ++ void (*enabled)(struct batadv_hard_iface *hard_iface); + void (*disable)(struct batadv_hard_iface *hard_iface); + void (*update_mac)(struct batadv_hard_iface *hard_iface); + void (*primary_set)(struct batadv_hard_iface *hard_iface); +@@ -1479,9 +1486,10 @@ struct batadv_algo_neigh_ops { + */ + struct batadv_algo_orig_ops { + void (*free)(struct batadv_orig_node *orig_node); +- int (*add_if)(struct batadv_orig_node *orig_node, int max_if_num); +- int (*del_if)(struct batadv_orig_node *orig_node, int max_if_num, +- int del_if_num); ++ int (*add_if)(struct batadv_orig_node *orig_node, ++ unsigned int max_if_num); ++ int (*del_if)(struct batadv_orig_node *orig_node, ++ unsigned int max_if_num, unsigned int del_if_num); + #ifdef CONFIG_BATMAN_ADV_DEBUGFS + void (*print)(struct batadv_priv *priv, struct seq_file *seq, + struct batadv_hard_iface *hard_iface); +diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c +index 7bf833598615..67feeb207dad 100644 +--- a/net/core/netclassid_cgroup.c ++++ b/net/core/netclassid_cgroup.c +@@ -57,30 +57,60 @@ static void cgrp_css_free(struct cgroup_subsys_state *css) + kfree(css_cls_state(css)); + } + ++/* ++ * To avoid freezing of sockets creation for tasks with big number of threads ++ * and opened sockets lets release file_lock every 1000 iterated descriptors. ++ * New sockets will already have been created with new classid. ++ */ ++ ++struct update_classid_context { ++ u32 classid; ++ unsigned int batch; ++}; ++ ++#define UPDATE_CLASSID_BATCH 1000 ++ + static int update_classid_sock(const void *v, struct file *file, unsigned n) + { + int err; ++ struct update_classid_context *ctx = (void *)v; + struct socket *sock = sock_from_file(file, &err); + + if (sock) { + spin_lock(&cgroup_sk_update_lock); +- sock_cgroup_set_classid(&sock->sk->sk_cgrp_data, +- (unsigned long)v); ++ sock_cgroup_set_classid(&sock->sk->sk_cgrp_data, ctx->classid); + spin_unlock(&cgroup_sk_update_lock); + } ++ if (--ctx->batch == 0) { ++ ctx->batch = UPDATE_CLASSID_BATCH; ++ return n + 1; ++ } + return 0; + } + ++static void update_classid_task(struct task_struct *p, u32 classid) ++{ ++ struct update_classid_context ctx = { ++ .classid = classid, ++ .batch = UPDATE_CLASSID_BATCH ++ }; ++ unsigned int fd = 0; ++ ++ do { ++ task_lock(p); ++ fd = iterate_fd(p->files, fd, update_classid_sock, &ctx); ++ task_unlock(p); ++ cond_resched(); ++ } while (fd); ++} ++ + static void cgrp_attach(struct cgroup_taskset *tset) + { + struct cgroup_subsys_state *css; + struct task_struct *p; + + cgroup_taskset_for_each(p, css, tset) { +- task_lock(p); +- iterate_fd(p->files, 0, update_classid_sock, +- (void *)(unsigned long)css_cls_state(css)->classid); +- task_unlock(p); ++ update_classid_task(p, css_cls_state(css)->classid); + } + } + +@@ -102,10 +132,7 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft, + + css_task_iter_start(css, 0, &it); + while ((p = css_task_iter_next(&it))) { +- task_lock(p); +- iterate_fd(p->files, 0, update_classid_sock, +- (void *)(unsigned long)cs->classid); +- task_unlock(p); ++ update_classid_task(p, cs->classid); + cond_resched(); + } + css_task_iter_end(&it); +diff --git a/net/core/sock.c b/net/core/sock.c +index 03ca2f638eb4..d2cb2051d045 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1684,7 +1684,10 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) + atomic_set(&newsk->sk_zckey, 0); + + sock_reset_flag(newsk, SOCK_DONE); +- mem_cgroup_sk_alloc(newsk); ++ ++ /* sk->sk_memcg will be populated at accept() time */ ++ newsk->sk_memcg = NULL; ++ + cgroup_sk_alloc(&newsk->sk_cgrp_data); + + rcu_read_lock(); +diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c +index 35c432668454..040983fc15da 100644 +--- a/net/ieee802154/nl_policy.c ++++ b/net/ieee802154/nl_policy.c +@@ -30,7 +30,13 @@ const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = { + [IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, }, + [IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, }, + [IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_BCN_ORD] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_SF_ORD] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_PAN_COORD] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_BAT_EXT] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_COORD_REALIGN] = { .type = NLA_U8, }, + [IEEE802154_ATTR_PAGE] = { .type = NLA_U8, }, ++ [IEEE802154_ATTR_DEV_TYPE] = { .type = NLA_U8, }, + [IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, }, + [IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, }, + [IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, }, +diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c +index f0165c5f376b..1c21dc5d6dd4 100644 +--- a/net/ipv4/cipso_ipv4.c ++++ b/net/ipv4/cipso_ipv4.c +@@ -1738,6 +1738,7 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) + { + unsigned char optbuf[sizeof(struct ip_options) + 40]; + struct ip_options *opt = (struct ip_options *)optbuf; ++ int res; + + if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES) + return; +@@ -1749,7 +1750,11 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) + + memset(opt, 0, sizeof(struct ip_options)); + opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); +- if (__ip_options_compile(dev_net(skb->dev), opt, skb, NULL)) ++ rcu_read_lock(); ++ res = __ip_options_compile(dev_net(skb->dev), opt, skb, NULL); ++ rcu_read_unlock(); ++ ++ if (res) + return; + + if (gateway) +diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c +index 7efe740c06eb..4a5e55e94a9e 100644 +--- a/net/ipv4/gre_demux.c ++++ b/net/ipv4/gre_demux.c +@@ -60,7 +60,9 @@ int gre_del_protocol(const struct gre_protocol *proto, u8 version) + } + EXPORT_SYMBOL_GPL(gre_del_protocol); + +-/* Fills in tpi and returns header length to be pulled. */ ++/* Fills in tpi and returns header length to be pulled. ++ * Note that caller must use pskb_may_pull() before pulling GRE header. ++ */ + int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, + bool *csum_err, __be16 proto, int nhs) + { +@@ -114,8 +116,14 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, + * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header + */ + if (greh->flags == 0 && tpi->proto == htons(ETH_P_WCCP)) { ++ u8 _val, *val; ++ ++ val = skb_header_pointer(skb, nhs + hdr_len, ++ sizeof(_val), &_val); ++ if (!val) ++ return -EINVAL; + tpi->proto = proto; +- if ((*(u8 *)options & 0xF0) != 0x40) ++ if ((*val & 0xF0) != 0x40) + hdr_len += 4; + } + tpi->hdr_len = hdr_len; +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index da55ce62fe50..7826fba34b14 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -475,8 +475,28 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern) + } + spin_unlock_bh(&queue->fastopenq.lock); + } ++ + out: + release_sock(sk); ++ if (newsk && mem_cgroup_sockets_enabled) { ++ int amt; ++ ++ /* atomically get the memory usage, set and charge the ++ * newsk->sk_memcg. ++ */ ++ lock_sock(newsk); ++ ++ /* The socket has not been accepted yet, no need to look at ++ * newsk->sk_wmem_queued. ++ */ ++ amt = sk_mem_pages(newsk->sk_forward_alloc + ++ atomic_read(&newsk->sk_rmem_alloc)); ++ mem_cgroup_sk_alloc(newsk); ++ if (newsk->sk_memcg && amt) ++ mem_cgroup_charge_skmem(newsk->sk_memcg, amt); ++ ++ release_sock(newsk); ++ } + if (req) + reqsk_put(req); + return newsk; +diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c +index eb158badebc4..7ba013d6c00a 100644 +--- a/net/ipv4/inet_diag.c ++++ b/net/ipv4/inet_diag.c +@@ -105,13 +105,9 @@ static size_t inet_sk_attr_size(struct sock *sk, + aux = handler->idiag_get_aux_size(sk, net_admin); + + return nla_total_size(sizeof(struct tcp_info)) +- + nla_total_size(1) /* INET_DIAG_SHUTDOWN */ +- + nla_total_size(1) /* INET_DIAG_TOS */ +- + nla_total_size(1) /* INET_DIAG_TCLASS */ +- + nla_total_size(4) /* INET_DIAG_MARK */ +- + nla_total_size(4) /* INET_DIAG_CLASS_ID */ +- + nla_total_size(sizeof(struct inet_diag_meminfo)) + + nla_total_size(sizeof(struct inet_diag_msg)) ++ + inet_diag_msg_attrs_size() ++ + nla_total_size(sizeof(struct inet_diag_meminfo)) + + nla_total_size(SK_MEMINFO_VARS * sizeof(u32)) + + nla_total_size(TCP_CA_NAME_MAX) + + nla_total_size(sizeof(struct tcpvegas_info)) +@@ -152,6 +148,24 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb, + if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, sk->sk_mark)) + goto errout; + ++ if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) || ++ ext & (1 << (INET_DIAG_TCLASS - 1))) { ++ u32 classid = 0; ++ ++#ifdef CONFIG_SOCK_CGROUP_DATA ++ classid = sock_cgroup_classid(&sk->sk_cgrp_data); ++#endif ++ /* Fallback to socket priority if class id isn't set. ++ * Classful qdiscs use it as direct reference to class. ++ * For cgroup2 classid is always zero. ++ */ ++ if (!classid) ++ classid = sk->sk_priority; ++ ++ if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid)) ++ goto errout; ++ } ++ + r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk)); + r->idiag_inode = sock_i_ino(sk); + +@@ -289,24 +303,6 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, + goto errout; + } + +- if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) || +- ext & (1 << (INET_DIAG_TCLASS - 1))) { +- u32 classid = 0; +- +-#ifdef CONFIG_SOCK_CGROUP_DATA +- classid = sock_cgroup_classid(&sk->sk_cgrp_data); +-#endif +- /* Fallback to socket priority if class id isn't set. +- * Classful qdiscs use it as direct reference to class. +- * For cgroup2 classid is always zero. +- */ +- if (!classid) +- classid = sk->sk_priority; +- +- if (nla_put_u32(skb, INET_DIAG_CLASS_ID, classid)) +- goto errout; +- } +- + out: + nlmsg_end(skb, nlh); + return 0; +diff --git a/net/ipv4/raw_diag.c b/net/ipv4/raw_diag.c +index 6367ecdf76c4..1d84b02ec765 100644 +--- a/net/ipv4/raw_diag.c ++++ b/net/ipv4/raw_diag.c +@@ -99,8 +99,9 @@ static int raw_diag_dump_one(struct sk_buff *in_skb, + if (IS_ERR(sk)) + return PTR_ERR(sk); + +- rep = nlmsg_new(sizeof(struct inet_diag_msg) + +- sizeof(struct inet_diag_meminfo) + 64, ++ rep = nlmsg_new(nla_total_size(sizeof(struct inet_diag_msg)) + ++ inet_diag_msg_attrs_size() + ++ nla_total_size(sizeof(struct inet_diag_meminfo)) + 64, + GFP_KERNEL); + if (!rep) { + sock_put(sk); +diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c +index d9ad986c7b2c..cc3f6da306c6 100644 +--- a/net/ipv4/udp_diag.c ++++ b/net/ipv4/udp_diag.c +@@ -67,8 +67,9 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, + goto out; + + err = -ENOMEM; +- rep = nlmsg_new(sizeof(struct inet_diag_msg) + +- sizeof(struct inet_diag_meminfo) + 64, ++ rep = nlmsg_new(nla_total_size(sizeof(struct inet_diag_msg)) + ++ inet_diag_msg_attrs_size() + ++ nla_total_size(sizeof(struct inet_diag_meminfo)) + 64, + GFP_KERNEL); + if (!rep) + goto out; +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index a81201dd3a1a..092e72d6a61d 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -3223,6 +3223,10 @@ static void addrconf_dev_config(struct net_device *dev) + (dev->type != ARPHRD_TUNNEL) && + (dev->type != ARPHRD_NONE)) { + /* Alas, we support only Ethernet autoconfiguration. */ ++ idev = __in6_dev_get(dev); ++ if (!IS_ERR_OR_NULL(idev) && dev->flags & IFF_UP && ++ dev->flags & IFF_MULTICAST) ++ ipv6_mc_up(idev); + return; + } + +diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c +index 5c91b05c8d8f..8c492471b0da 100644 +--- a/net/ipv6/ipv6_sockglue.c ++++ b/net/ipv6/ipv6_sockglue.c +@@ -185,9 +185,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, + retv = -EBUSY; + break; + } +- } else if (sk->sk_protocol != IPPROTO_TCP) ++ } else if (sk->sk_protocol == IPPROTO_TCP) { ++ if (sk->sk_prot != &tcpv6_prot) { ++ retv = -EBUSY; ++ break; ++ } + break; +- ++ } else { ++ break; ++ } + if (sk->sk_state != TCP_ESTABLISHED) { + retv = -ENOTCONN; + break; +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index 31000622376d..7c92b1471c34 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -3862,7 +3862,7 @@ void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata) + + lockdep_assert_held(&local->sta_mtx); + +- list_for_each_entry_rcu(sta, &local->sta_list, list) { ++ list_for_each_entry(sta, &local->sta_list, list) { + if (sdata != sta->sdata && + (!sta->sdata->bss || sta->sdata->bss != sdata->bss)) + continue; +diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c +index d33ce6d5ebce..dd1030f5dd5e 100644 +--- a/net/netfilter/nfnetlink_cthelper.c ++++ b/net/netfilter/nfnetlink_cthelper.c +@@ -733,6 +733,8 @@ static const struct nla_policy nfnl_cthelper_policy[NFCTH_MAX+1] = { + [NFCTH_NAME] = { .type = NLA_NUL_STRING, + .len = NF_CT_HELPER_NAME_LEN-1 }, + [NFCTH_QUEUE_NUM] = { .type = NLA_U32, }, ++ [NFCTH_PRIV_DATA_LEN] = { .type = NLA_U32, }, ++ [NFCTH_STATUS] = { .type = NLA_U32, }, + }; + + static const struct nfnl_callback nfnl_cthelper_cb[NFNL_MSG_CTHELPER_MAX] = { +diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c +index e110b0ebbf58..19446a89a2a8 100644 +--- a/net/netfilter/nft_payload.c ++++ b/net/netfilter/nft_payload.c +@@ -121,6 +121,7 @@ static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = { + [NFTA_PAYLOAD_LEN] = { .type = NLA_U32 }, + [NFTA_PAYLOAD_CSUM_TYPE] = { .type = NLA_U32 }, + [NFTA_PAYLOAD_CSUM_OFFSET] = { .type = NLA_U32 }, ++ [NFTA_PAYLOAD_CSUM_FLAGS] = { .type = NLA_U32 }, + }; + + static int nft_payload_init(const struct nft_ctx *ctx, +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 07924559cb10..3e4e07559272 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -2389,7 +2389,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, + in_skb->len)) + WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, + (u8 *)extack->bad_attr - +- in_skb->data)); ++ (u8 *)nlh)); + } else { + if (extack->cookie_len) + WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE, +diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c +index 6bf14f4f4b42..ae315dbd3732 100644 +--- a/net/nfc/hci/core.c ++++ b/net/nfc/hci/core.c +@@ -193,13 +193,20 @@ exit: + void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, + struct sk_buff *skb) + { +- u8 gate = hdev->pipes[pipe].gate; + u8 status = NFC_HCI_ANY_OK; + struct hci_create_pipe_resp *create_info; + struct hci_delete_pipe_noti *delete_info; + struct hci_all_pipe_cleared_noti *cleared_info; ++ u8 gate; + +- pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd); ++ pr_debug("from pipe %x cmd %x\n", pipe, cmd); ++ ++ if (pipe >= NFC_HCI_MAX_PIPES) { ++ status = NFC_HCI_ANY_E_NOK; ++ goto exit; ++ } ++ ++ gate = hdev->pipes[pipe].gate; + + switch (cmd) { + case NFC_HCI_ADM_NOTIFY_PIPE_CREATED: +@@ -387,8 +394,14 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, + struct sk_buff *skb) + { + int r = 0; +- u8 gate = hdev->pipes[pipe].gate; ++ u8 gate; ++ ++ if (pipe >= NFC_HCI_MAX_PIPES) { ++ pr_err("Discarded event %x to invalid pipe %x\n", event, pipe); ++ goto exit; ++ } + ++ gate = hdev->pipes[pipe].gate; + if (gate == NFC_HCI_INVALID_GATE) { + pr_err("Discarded event %x to unopened pipe %x\n", event, pipe); + goto exit; +diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c +index 7b8d4d235a3a..6199f4334fbd 100644 +--- a/net/nfc/netlink.c ++++ b/net/nfc/netlink.c +@@ -55,7 +55,10 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { + [NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED }, + [NFC_ATTR_FIRMWARE_NAME] = { .type = NLA_STRING, + .len = NFC_FIRMWARE_NAME_MAXSIZE }, ++ [NFC_ATTR_SE_INDEX] = { .type = NLA_U32 }, + [NFC_ATTR_SE_APDU] = { .type = NLA_BINARY }, ++ [NFC_ATTR_VENDOR_ID] = { .type = NLA_U32 }, ++ [NFC_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 }, + [NFC_ATTR_VENDOR_DATA] = { .type = NLA_BINARY }, + + }; +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 46b7fac82775..387589a4a340 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2299,6 +2299,13 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, + TP_STATUS_KERNEL, (macoff+snaplen)); + if (!h.raw) + goto drop_n_account; ++ ++ if (do_vnet && ++ virtio_net_hdr_from_skb(skb, h.raw + macoff - ++ sizeof(struct virtio_net_hdr), ++ vio_le(), true, 0)) ++ goto drop_n_account; ++ + if (po->tp_version <= TPACKET_V2) { + packet_increment_rx_head(po, &po->rx_ring); + /* +@@ -2311,12 +2318,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, + status |= TP_STATUS_LOSING; + } + +- if (do_vnet && +- virtio_net_hdr_from_skb(skb, h.raw + macoff - +- sizeof(struct virtio_net_hdr), +- vio_le(), true, 0)) +- goto drop_n_account; +- + po->stats.stats1.tp_packets++; + if (copy_skb) { + status |= TP_STATUS_COPY; +diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c +index 7a944f508cae..66f1d40b910a 100644 +--- a/net/sched/sch_fq.c ++++ b/net/sched/sch_fq.c +@@ -695,6 +695,7 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = { + [TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 }, + [TCA_FQ_BUCKETS_LOG] = { .type = NLA_U32 }, + [TCA_FQ_FLOW_REFILL_DELAY] = { .type = NLA_U32 }, ++ [TCA_FQ_ORPHAN_MASK] = { .type = NLA_U32 }, + [TCA_FQ_LOW_RATE_THRESHOLD] = { .type = NLA_U32 }, + }; + +diff --git a/net/sctp/sctp_diag.c b/net/sctp/sctp_diag.c +index 75274a60b77a..6a5a3dfa6c8d 100644 +--- a/net/sctp/sctp_diag.c ++++ b/net/sctp/sctp_diag.c +@@ -221,15 +221,11 @@ static size_t inet_assoc_attr_size(struct sctp_association *asoc) + addrcnt++; + + return nla_total_size(sizeof(struct sctp_info)) +- + nla_total_size(1) /* INET_DIAG_SHUTDOWN */ +- + nla_total_size(1) /* INET_DIAG_TOS */ +- + nla_total_size(1) /* INET_DIAG_TCLASS */ +- + nla_total_size(4) /* INET_DIAG_MARK */ +- + nla_total_size(4) /* INET_DIAG_CLASS_ID */ + + nla_total_size(addrlen * asoc->peer.transport_count) + + nla_total_size(addrlen * addrcnt) +- + nla_total_size(sizeof(struct inet_diag_meminfo)) + + nla_total_size(sizeof(struct inet_diag_msg)) ++ + inet_diag_msg_attrs_size() ++ + nla_total_size(sizeof(struct inet_diag_meminfo)) + + 64; + } + +diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c +index 4410d0071515..7d89b0584944 100644 +--- a/net/smc/smc_ib.c ++++ b/net/smc/smc_ib.c +@@ -513,6 +513,8 @@ static void smc_ib_remove_dev(struct ib_device *ibdev, void *client_data) + struct smc_ib_device *smcibdev; + + smcibdev = ib_get_client_data(ibdev, &smc_ib_client); ++ if (!smcibdev || smcibdev->ibdev != ibdev) ++ return; + ib_set_client_data(ibdev, &smc_ib_client, NULL); + spin_lock(&smc_ib_devices.lock); + list_del_init(&smcibdev->list); /* remove from smc_ib_devices */ +diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c +index b248578aeb7b..d0b75781e6f7 100644 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -347,6 +347,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, + [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, + [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, ++ [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 }, ++ [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG }, + [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, + [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, + [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, +@@ -395,6 +397,8 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [NL80211_ATTR_MDID] = { .type = NLA_U16 }, + [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY, + .len = IEEE80211_MAX_DATA_LEN }, ++ [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 }, ++ [NL80211_ATTR_MAX_CRIT_PROT_DURATION] = { .type = NLA_U16 }, + [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 }, + [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 }, + [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG }, +@@ -420,6 +424,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { + [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 }, + [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, + [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, ++ [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 }, + [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN }, + [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG }, + [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 }, +diff --git a/net/wireless/reg.c b/net/wireless/reg.c +index a520f433d476..b95d1c2bdef7 100644 +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -1733,7 +1733,7 @@ static void handle_channel_custom(struct wiphy *wiphy, + break; + } + +- if (IS_ERR(reg_rule)) { ++ if (IS_ERR_OR_NULL(reg_rule)) { + pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n", + chan->center_freq); + if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) { +diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl +index 0c8b61f8398e..3bdd6a463819 100755 +--- a/tools/testing/ktest/ktest.pl ++++ b/tools/testing/ktest/ktest.pl +@@ -1345,7 +1345,7 @@ sub reboot { + + } else { + # Make sure everything has been written to disk +- run_ssh("sync"); ++ run_ssh("sync", 10); + + if (defined($time)) { + start_monitor;
