commit:     dd458323bfd7b0f33dbdfbfb163a3da902f97fd1
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 12 14:53:37 2020 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Jan 12 14:53:37 2020 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=dd458323

Linux patch 4.14.164

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README               |    4 +
 1163_linux-4.14.164.patch | 2533 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2537 insertions(+)

diff --git a/0000_README b/0000_README
index b1304d8..9cdb60b 100644
--- a/0000_README
+++ b/0000_README
@@ -695,6 +695,10 @@ Patch:  1162_linux-4.14.163.patch
 From:   https://www.kernel.org
 Desc:   Linux 4.14.163
 
+Patch:  1163_linux-4.14.164.patch
+From:   https://www.kernel.org
+Desc:   Linux 4.14.164
+
 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/1163_linux-4.14.164.patch b/1163_linux-4.14.164.patch
new file mode 100644
index 0000000..8b56337
--- /dev/null
+++ b/1163_linux-4.14.164.patch
@@ -0,0 +1,2533 @@
+diff --git a/Makefile b/Makefile
+index 35a71a78d1d2..f2aa55cea457 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 14
+-SUBLEVEL = 163
++SUBLEVEL = 164
+ EXTRAVERSION =
+ NAME = Petit Gorille
+ 
+diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts 
b/arch/arm/boot/dts/am437x-gp-evm.dts
+index afb8eb0a0a16..051823b7e5a1 100644
+--- a/arch/arm/boot/dts/am437x-gp-evm.dts
++++ b/arch/arm/boot/dts/am437x-gp-evm.dts
+@@ -83,7 +83,7 @@
+               };
+ 
+       lcd0: display {
+-              compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
++              compatible = "osddisplays,osd070t1718-19ts", "panel-dpi";
+               label = "lcd";
+ 
+               panel-timing {
+diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts 
b/arch/arm/boot/dts/am43x-epos-evm.dts
+index 081fa68b6f98..c4279b0b9f12 100644
+--- a/arch/arm/boot/dts/am43x-epos-evm.dts
++++ b/arch/arm/boot/dts/am43x-epos-evm.dts
+@@ -45,7 +45,7 @@
+       };
+ 
+       lcd0: display {
+-              compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
++              compatible = "osddisplays,osd070t1718-19ts", "panel-dpi";
+               label = "lcd";
+ 
+               panel-timing {
+diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi 
b/arch/arm/boot/dts/bcm-cygnus.dtsi
+index 8b2c65cd61a2..b822952c29f8 100644
+--- a/arch/arm/boot/dts/bcm-cygnus.dtsi
++++ b/arch/arm/boot/dts/bcm-cygnus.dtsi
+@@ -165,8 +165,8 @@
+               mdio: mdio@18002000 {
+                       compatible = "brcm,iproc-mdio";
+                       reg = <0x18002000 0x8>;
+-                      #size-cells = <1>;
+-                      #address-cells = <0>;
++                      #size-cells = <0>;
++                      #address-cells = <1>;
+                       status = "disabled";
+ 
+                       gphy0: ethernet-phy@0 {
+diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
+index 4745e3c7806b..fdb018e1278f 100644
+--- a/arch/arm/boot/dts/bcm283x.dtsi
++++ b/arch/arm/boot/dts/bcm283x.dtsi
+@@ -38,7 +38,7 @@
+ 
+                       trips {
+                               cpu-crit {
+-                                      temperature     = <80000>;
++                                      temperature     = <90000>;
+                                       hysteresis      = <0>;
+                                       type            = "critical";
+                               };
+diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c
+index fe488523694c..635b0d549487 100644
+--- a/arch/arm/mach-vexpress/spc.c
++++ b/arch/arm/mach-vexpress/spc.c
+@@ -555,8 +555,9 @@ static struct clk *ve_spc_clk_register(struct device 
*cpu_dev)
+ 
+ static int __init ve_spc_clk_init(void)
+ {
+-      int cpu;
++      int cpu, cluster;
+       struct clk *clk;
++      bool init_opp_table[MAX_CLUSTERS] = { false };
+ 
+       if (!info)
+               return 0; /* Continue only if SPC is initialised */
+@@ -582,8 +583,17 @@ static int __init ve_spc_clk_init(void)
+                       continue;
+               }
+ 
++              cluster = topology_physical_package_id(cpu_dev->id);
++              if (init_opp_table[cluster])
++                      continue;
++
+               if (ve_init_opp_table(cpu_dev))
+                       pr_warn("failed to initialise cpu%d opp table\n", cpu);
++              else if (dev_pm_opp_set_sharing_cpus(cpu_dev,
++                       topology_core_cpumask(cpu_dev->id)))
++                      pr_warn("failed to mark OPPs shared for cpu%d\n", cpu);
++              else
++                      init_opp_table[cluster] = true;
+       }
+ 
+       platform_device_register_simple("vexpress-spc-cpufreq", -1, NULL, 0);
+diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c
+index 42faa95ce664..57a7a9d68475 100644
+--- a/arch/mips/net/ebpf_jit.c
++++ b/arch/mips/net/ebpf_jit.c
+@@ -612,6 +612,7 @@ static void emit_const_to_reg(struct jit_ctx *ctx, int 
dst, u64 value)
+ static int emit_bpf_tail_call(struct jit_ctx *ctx, int this_idx)
+ {
+       int off, b_off;
++      int tcc_reg;
+ 
+       ctx->flags |= EBPF_SEEN_TC;
+       /*
+@@ -624,14 +625,14 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx, int 
this_idx)
+       b_off = b_imm(this_idx + 1, ctx);
+       emit_instr(ctx, bne, MIPS_R_AT, MIPS_R_ZERO, b_off);
+       /*
+-       * if (--TCC < 0)
++       * if (TCC-- < 0)
+        *     goto out;
+        */
+       /* Delay slot */
+-      emit_instr(ctx, daddiu, MIPS_R_T5,
+-                 (ctx->flags & EBPF_TCC_IN_V1) ? MIPS_R_V1 : MIPS_R_S4, -1);
++      tcc_reg = (ctx->flags & EBPF_TCC_IN_V1) ? MIPS_R_V1 : MIPS_R_S4;
++      emit_instr(ctx, daddiu, MIPS_R_T5, tcc_reg, -1);
+       b_off = b_imm(this_idx + 1, ctx);
+-      emit_instr(ctx, bltz, MIPS_R_T5, b_off);
++      emit_instr(ctx, bltz, tcc_reg, b_off);
+       /*
+        * prog = array->ptrs[index];
+        * if (prog == NULL)
+diff --git a/arch/parisc/include/asm/cmpxchg.h 
b/arch/parisc/include/asm/cmpxchg.h
+index f627c37dad9c..ab5c215cf46c 100644
+--- a/arch/parisc/include/asm/cmpxchg.h
++++ b/arch/parisc/include/asm/cmpxchg.h
+@@ -44,8 +44,14 @@ __xchg(unsigned long x, __volatile__ void *ptr, int size)
+ **            if (((unsigned long)p & 0xf) == 0)
+ **                    return __ldcw(p);
+ */
+-#define xchg(ptr, x) \
+-      ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
++#define xchg(ptr, x)                                                  \
++({                                                                    \
++      __typeof__(*(ptr)) __ret;                                       \
++      __typeof__(*(ptr)) _x_ = (x);                                   \
++      __ret = (__typeof__(*(ptr)))                                    \
++              __xchg((unsigned long)_x_, (ptr), sizeof(*(ptr)));      \
++      __ret;                                                          \
++})
+ 
+ /* bug catcher for when unsupported size is used - won't link */
+ extern void __cmpxchg_called_with_bad_pointer(void);
+diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
+index 30bf13b72e5e..3c5abfbbe60e 100644
+--- a/arch/powerpc/mm/mem.c
++++ b/arch/powerpc/mm/mem.c
+@@ -353,6 +353,14 @@ void __init mem_init(void)
+       BUILD_BUG_ON(MMU_PAGE_COUNT > 16);
+ 
+ #ifdef CONFIG_SWIOTLB
++      /*
++       * Some platforms (e.g. 85xx) limit DMA-able memory way below
++       * 4G. We force memblock to bottom-up mode to ensure that the
++       * memory allocated in swiotlb_init() is DMA-able.
++       * As it's the last memblock allocation, no need to reset it
++       * back to to-down.
++       */
++      memblock_set_bottom_up(true);
+       swiotlb_init(0);
+ #endif
+ 
+diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
+index 6ed99de2ddf5..c1f7b3cb84a9 100644
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -375,7 +375,7 @@ int x86_add_exclusive(unsigned int what)
+        * LBR and BTS are still mutually exclusive.
+        */
+       if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt)
+-              return 0;
++              goto out;
+ 
+       if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
+               mutex_lock(&pmc_reserve_mutex);
+@@ -387,6 +387,7 @@ int x86_add_exclusive(unsigned int what)
+               mutex_unlock(&pmc_reserve_mutex);
+       }
+ 
++out:
+       atomic_inc(&active_events);
+       return 0;
+ 
+@@ -397,11 +398,15 @@ fail_unlock:
+ 
+ void x86_del_exclusive(unsigned int what)
+ {
++      atomic_dec(&active_events);
++
++      /*
++       * See the comment in x86_add_exclusive().
++       */
+       if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt)
+               return;
+ 
+       atomic_dec(&x86_pmu.lbr_exclusive[what]);
+-      atomic_dec(&active_events);
+ }
+ 
+ int x86_setup_perfctr(struct perf_event *event)
+diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
+index 5b513ccffde4..cadd7fd290fa 100644
+--- a/arch/x86/platform/efi/quirks.c
++++ b/arch/x86/platform/efi/quirks.c
+@@ -257,10 +257,6 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 
size)
+               return;
+       }
+ 
+-      /* No need to reserve regions that will never be freed. */
+-      if (md.attribute & EFI_MEMORY_RUNTIME)
+-              return;
+-
+       size += addr % EFI_PAGE_SIZE;
+       size = round_up(size, EFI_PAGE_SIZE);
+       addr = round_down(addr, EFI_PAGE_SIZE);
+@@ -290,6 +286,8 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 
size)
+       early_memunmap(new, new_size);
+ 
+       efi_memmap_install(new_phys, num_entries);
++      e820__range_update(addr, size, E820_TYPE_RAM, E820_TYPE_RESERVED);
++      e820__update_table(e820_table);
+ }
+ 
+ /*
+diff --git a/block/blk-map.c b/block/blk-map.c
+index e31be14da8ea..f72a3af689b6 100644
+--- a/block/blk-map.c
++++ b/block/blk-map.c
+@@ -152,7 +152,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct 
request *rq,
+       return 0;
+ 
+ unmap_rq:
+-      __blk_rq_unmap_user(bio);
++      blk_rq_unmap_user(bio);
+ fail:
+       rq->bio = NULL;
+       return ret;
+diff --git a/drivers/firmware/efi/libstub/gop.c 
b/drivers/firmware/efi/libstub/gop.c
+index 24c461dea7af..fd8053f9556e 100644
+--- a/drivers/firmware/efi/libstub/gop.c
++++ b/drivers/firmware/efi/libstub/gop.c
+@@ -85,30 +85,6 @@ setup_pixel_info(struct screen_info *si, u32 
pixels_per_scan_line,
+       }
+ }
+ 
+-static efi_status_t
+-__gop_query32(efi_system_table_t *sys_table_arg,
+-            struct efi_graphics_output_protocol_32 *gop32,
+-            struct efi_graphics_output_mode_info **info,
+-            unsigned long *size, u64 *fb_base)
+-{
+-      struct efi_graphics_output_protocol_mode_32 *mode;
+-      efi_graphics_output_protocol_query_mode query_mode;
+-      efi_status_t status;
+-      unsigned long m;
+-
+-      m = gop32->mode;
+-      mode = (struct efi_graphics_output_protocol_mode_32 *)m;
+-      query_mode = (void *)(unsigned long)gop32->query_mode;
+-
+-      status = __efi_call_early(query_mode, (void *)gop32, mode->mode, size,
+-                                info);
+-      if (status != EFI_SUCCESS)
+-              return status;
+-
+-      *fb_base = mode->frame_buffer_base;
+-      return status;
+-}
+-
+ static efi_status_t
+ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si,
+             efi_guid_t *proto, unsigned long size, void **gop_handle)
+@@ -121,7 +97,7 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+       u64 fb_base;
+       struct efi_pixel_bitmask pixel_info;
+       int pixel_format;
+-      efi_status_t status = EFI_NOT_FOUND;
++      efi_status_t status;
+       u32 *handles = (u32 *)(unsigned long)gop_handle;
+       int i;
+ 
+@@ -130,6 +106,7 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+ 
+       nr_gops = size / sizeof(u32);
+       for (i = 0; i < nr_gops; i++) {
++              struct efi_graphics_output_protocol_mode_32 *mode;
+               struct efi_graphics_output_mode_info *info = NULL;
+               efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
+               bool conout_found = false;
+@@ -147,9 +124,11 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+               if (status == EFI_SUCCESS)
+                       conout_found = true;
+ 
+-              status = __gop_query32(sys_table_arg, gop32, &info, &size,
+-                                     &current_fb_base);
+-              if (status == EFI_SUCCESS && (!first_gop || conout_found) &&
++              mode = (void *)(unsigned long)gop32->mode;
++              info = (void *)(unsigned long)mode->info;
++              current_fb_base = mode->frame_buffer_base;
++
++              if ((!first_gop || conout_found) &&
+                   info->pixel_format != PIXEL_BLT_ONLY) {
+                       /*
+                        * Systems that use the UEFI Console Splitter may
+@@ -177,7 +156,7 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+ 
+       /* Did we find any GOPs? */
+       if (!first_gop)
+-              goto out;
++              return EFI_NOT_FOUND;
+ 
+       /* EFI framebuffer */
+       si->orig_video_isVGA = VIDEO_TYPE_EFI;
+@@ -199,32 +178,8 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+       si->lfb_size = si->lfb_linelength * si->lfb_height;
+ 
+       si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
+-out:
+-      return status;
+-}
+-
+-static efi_status_t
+-__gop_query64(efi_system_table_t *sys_table_arg,
+-            struct efi_graphics_output_protocol_64 *gop64,
+-            struct efi_graphics_output_mode_info **info,
+-            unsigned long *size, u64 *fb_base)
+-{
+-      struct efi_graphics_output_protocol_mode_64 *mode;
+-      efi_graphics_output_protocol_query_mode query_mode;
+-      efi_status_t status;
+-      unsigned long m;
+-
+-      m = gop64->mode;
+-      mode = (struct efi_graphics_output_protocol_mode_64 *)m;
+-      query_mode = (void *)(unsigned long)gop64->query_mode;
+-
+-      status = __efi_call_early(query_mode, (void *)gop64, mode->mode, size,
+-                                info);
+-      if (status != EFI_SUCCESS)
+-              return status;
+ 
+-      *fb_base = mode->frame_buffer_base;
+-      return status;
++      return EFI_SUCCESS;
+ }
+ 
+ static efi_status_t
+@@ -239,7 +194,7 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+       u64 fb_base;
+       struct efi_pixel_bitmask pixel_info;
+       int pixel_format;
+-      efi_status_t status = EFI_NOT_FOUND;
++      efi_status_t status;
+       u64 *handles = (u64 *)(unsigned long)gop_handle;
+       int i;
+ 
+@@ -248,6 +203,7 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+ 
+       nr_gops = size / sizeof(u64);
+       for (i = 0; i < nr_gops; i++) {
++              struct efi_graphics_output_protocol_mode_64 *mode;
+               struct efi_graphics_output_mode_info *info = NULL;
+               efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
+               bool conout_found = false;
+@@ -265,9 +221,11 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+               if (status == EFI_SUCCESS)
+                       conout_found = true;
+ 
+-              status = __gop_query64(sys_table_arg, gop64, &info, &size,
+-                                     &current_fb_base);
+-              if (status == EFI_SUCCESS && (!first_gop || conout_found) &&
++              mode = (void *)(unsigned long)gop64->mode;
++              info = (void *)(unsigned long)mode->info;
++              current_fb_base = mode->frame_buffer_base;
++
++              if ((!first_gop || conout_found) &&
+                   info->pixel_format != PIXEL_BLT_ONLY) {
+                       /*
+                        * Systems that use the UEFI Console Splitter may
+@@ -295,7 +253,7 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+ 
+       /* Did we find any GOPs? */
+       if (!first_gop)
+-              goto out;
++              return EFI_NOT_FOUND;
+ 
+       /* EFI framebuffer */
+       si->orig_video_isVGA = VIDEO_TYPE_EFI;
+@@ -317,8 +275,8 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct 
screen_info *si,
+       si->lfb_size = si->lfb_linelength * si->lfb_height;
+ 
+       si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
+-out:
+-      return status;
++
++      return EFI_SUCCESS;
+ }
+ 
+ /*
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index ce6dd49fbb98..916b88ee2de4 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -28,6 +28,7 @@
+ #include <linux/hdreg.h>
+ #include <linux/kdev_t.h>
+ #include <linux/blkdev.h>
++#include <linux/cdev.h>
+ #include <linux/mutex.h>
+ #include <linux/scatterlist.h>
+ #include <linux/string_helpers.h>
+@@ -87,6 +88,7 @@ static int max_devices;
+ #define MAX_DEVICES 256
+ 
+ static DEFINE_IDA(mmc_blk_ida);
++static DEFINE_IDA(mmc_rpmb_ida);
+ 
+ /*
+  * There is one mmc_blk_data per slot.
+@@ -97,6 +99,7 @@ struct mmc_blk_data {
+       struct gendisk  *disk;
+       struct mmc_queue queue;
+       struct list_head part;
++      struct list_head rpmbs;
+ 
+       unsigned int    flags;
+ #define MMC_BLK_CMD23 (1 << 0)        /* Can do SET_BLOCK_COUNT for 
multiblock */
+@@ -126,6 +129,32 @@ struct mmc_blk_data {
+       struct dentry *ext_csd_dentry;
+ };
+ 
++/* Device type for RPMB character devices */
++static dev_t mmc_rpmb_devt;
++
++/* Bus type for RPMB character devices */
++static struct bus_type mmc_rpmb_bus_type = {
++      .name = "mmc_rpmb",
++};
++
++/**
++ * struct mmc_rpmb_data - special RPMB device type for these areas
++ * @dev: the device for the RPMB area
++ * @chrdev: character device for the RPMB area
++ * @id: unique device ID number
++ * @part_index: partition index (0 on first)
++ * @md: parent MMC block device
++ * @node: list item, so we can put this device on a list
++ */
++struct mmc_rpmb_data {
++      struct device dev;
++      struct cdev chrdev;
++      int id;
++      unsigned int part_index;
++      struct mmc_blk_data *md;
++      struct list_head node;
++};
++
+ static DEFINE_MUTEX(open_lock);
+ 
+ module_param(perdev_minors, int, 0444);
+@@ -309,6 +338,7 @@ struct mmc_blk_ioc_data {
+       struct mmc_ioc_cmd ic;
+       unsigned char *buf;
+       u64 buf_bytes;
++      struct mmc_rpmb_data *rpmb;
+ };
+ 
+ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
+@@ -447,14 +477,25 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, 
struct mmc_blk_data *md,
+       struct mmc_request mrq = {};
+       struct scatterlist sg;
+       int err;
+-      bool is_rpmb = false;
++      unsigned int target_part;
+       u32 status = 0;
+ 
+       if (!card || !md || !idata)
+               return -EINVAL;
+ 
+-      if (md->area_type & MMC_BLK_DATA_AREA_RPMB)
+-              is_rpmb = true;
++      /*
++       * The RPMB accesses comes in from the character device, so we
++       * need to target these explicitly. Else we just target the
++       * partition type for the block device the ioctl() was issued
++       * on.
++       */
++      if (idata->rpmb) {
++              /* Support multiple RPMB partitions */
++              target_part = idata->rpmb->part_index;
++              target_part |= EXT_CSD_PART_CONFIG_ACC_RPMB;
++      } else {
++              target_part = md->part_type;
++      }
+ 
+       cmd.opcode = idata->ic.opcode;
+       cmd.arg = idata->ic.arg;
+@@ -498,7 +539,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, 
struct mmc_blk_data *md,
+ 
+       mrq.cmd = &cmd;
+ 
+-      err = mmc_blk_part_switch(card, md->part_type);
++      err = mmc_blk_part_switch(card, target_part);
+       if (err)
+               return err;
+ 
+@@ -508,7 +549,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, 
struct mmc_blk_data *md,
+                       return err;
+       }
+ 
+-      if (is_rpmb) {
++      if (idata->rpmb) {
+               err = mmc_set_blockcount(card, data.blocks,
+                       idata->ic.write_flag & (1 << 31));
+               if (err)
+@@ -566,7 +607,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, 
struct mmc_blk_data *md,
+ 
+       memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp));
+ 
+-      if (is_rpmb) {
++      if (idata->rpmb) {
+               /*
+                * Ensure RPMB command has completed by polling CMD13
+                * "Send Status".
+@@ -582,7 +623,8 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, 
struct mmc_blk_data *md,
+ }
+ 
+ static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md,
+-                           struct mmc_ioc_cmd __user *ic_ptr)
++                           struct mmc_ioc_cmd __user *ic_ptr,
++                           struct mmc_rpmb_data *rpmb)
+ {
+       struct mmc_blk_ioc_data *idata;
+       struct mmc_blk_ioc_data *idatas[1];
+@@ -594,6 +636,8 @@ static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md,
+       idata = mmc_blk_ioctl_copy_from_user(ic_ptr);
+       if (IS_ERR(idata))
+               return PTR_ERR(idata);
++      /* This will be NULL on non-RPMB ioctl():s */
++      idata->rpmb = rpmb;
+ 
+       card = md->queue.card;
+       if (IS_ERR(card)) {
+@@ -613,7 +657,8 @@ static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md,
+               goto cmd_done;
+       }
+       idatas[0] = idata;
+-      req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_IOCTL;
++      req_to_mmc_queue_req(req)->drv_op =
++              rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;
+       req_to_mmc_queue_req(req)->drv_op_data = idatas;
+       req_to_mmc_queue_req(req)->ioc_count = 1;
+       blk_execute_rq(mq->queue, NULL, req, 0);
+@@ -628,7 +673,8 @@ cmd_done:
+ }
+ 
+ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md,
+-                                 struct mmc_ioc_multi_cmd __user *user)
++                                 struct mmc_ioc_multi_cmd __user *user,
++                                 struct mmc_rpmb_data *rpmb)
+ {
+       struct mmc_blk_ioc_data **idata = NULL;
+       struct mmc_ioc_cmd __user *cmds = user->cmds;
+@@ -659,6 +705,8 @@ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md,
+                       num_of_cmds = i;
+                       goto cmd_err;
+               }
++              /* This will be NULL on non-RPMB ioctl():s */
++              idata[i]->rpmb = rpmb;
+       }
+ 
+       card = md->queue.card;
+@@ -679,7 +727,8 @@ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md,
+               err = PTR_ERR(req);
+               goto cmd_err;
+       }
+-      req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_IOCTL;
++      req_to_mmc_queue_req(req)->drv_op =
++              rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;
+       req_to_mmc_queue_req(req)->drv_op_data = idata;
+       req_to_mmc_queue_req(req)->ioc_count = num_of_cmds;
+       blk_execute_rq(mq->queue, NULL, req, 0);
+@@ -727,7 +776,8 @@ static int mmc_blk_ioctl(struct block_device *bdev, 
fmode_t mode,
+               if (!md)
+                       return -EINVAL;
+               ret = mmc_blk_ioctl_cmd(md,
+-                                      (struct mmc_ioc_cmd __user *)arg);
++                                      (struct mmc_ioc_cmd __user *)arg,
++                                      NULL);
+               mmc_blk_put(md);
+               return ret;
+       case MMC_IOC_MULTI_CMD:
+@@ -738,7 +788,8 @@ static int mmc_blk_ioctl(struct block_device *bdev, 
fmode_t mode,
+               if (!md)
+                       return -EINVAL;
+               ret = mmc_blk_ioctl_multi_cmd(md,
+-                                      (struct mmc_ioc_multi_cmd __user *)arg);
++                                      (struct mmc_ioc_multi_cmd __user *)arg,
++                                      NULL);
+               mmc_blk_put(md);
+               return ret;
+       default:
+@@ -1188,18 +1239,6 @@ static inline void mmc_blk_reset_success(struct 
mmc_blk_data *md, int type)
+       md->reset_done &= ~type;
+ }
+ 
+-int mmc_access_rpmb(struct mmc_queue *mq)
+-{
+-      struct mmc_blk_data *md = mq->blkdata;
+-      /*
+-       * If this is a RPMB partition access, return ture
+-       */
+-      if (md && md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB)
+-              return true;
+-
+-      return false;
+-}
+-
+ /*
+  * The non-block commands come back from the block layer after it queued it 
and
+  * processed it with all other requests and then they get issued in this
+@@ -1210,17 +1249,19 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, 
struct request *req)
+       struct mmc_queue_req *mq_rq;
+       struct mmc_card *card = mq->card;
+       struct mmc_blk_data *md = mq->blkdata;
+-      struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev);
+       struct mmc_blk_ioc_data **idata;
++      bool rpmb_ioctl;
+       u8 **ext_csd;
+       u32 status;
+       int ret;
+       int i;
+ 
+       mq_rq = req_to_mmc_queue_req(req);
++      rpmb_ioctl = (mq_rq->drv_op == MMC_DRV_OP_IOCTL_RPMB);
+ 
+       switch (mq_rq->drv_op) {
+       case MMC_DRV_OP_IOCTL:
++      case MMC_DRV_OP_IOCTL_RPMB:
+               idata = mq_rq->drv_op_data;
+               for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) {
+                       ret = __mmc_blk_ioctl_cmd(card, md, idata[i]);
+@@ -1228,8 +1269,8 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, 
struct request *req)
+                               break;
+               }
+               /* Always switch back to main area after RPMB access */
+-              if (md->area_type & MMC_BLK_DATA_AREA_RPMB)
+-                      mmc_blk_part_switch(card, main_md->part_type);
++              if (rpmb_ioctl)
++                      mmc_blk_part_switch(card, 0);
+               break;
+       case MMC_DRV_OP_BOOT_WP:
+               ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP,
+@@ -2114,6 +2155,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct 
mmc_card *card,
+ 
+       spin_lock_init(&md->lock);
+       INIT_LIST_HEAD(&md->part);
++      INIT_LIST_HEAD(&md->rpmbs);
+       md->usage = 1;
+ 
+       ret = mmc_init_queue(&md->queue, card, &md->lock, subname);
+@@ -2232,6 +2274,158 @@ static int mmc_blk_alloc_part(struct mmc_card *card,
+       return 0;
+ }
+ 
++/**
++ * mmc_rpmb_ioctl() - ioctl handler for the RPMB chardev
++ * @filp: the character device file
++ * @cmd: the ioctl() command
++ * @arg: the argument from userspace
++ *
++ * This will essentially just redirect the ioctl()s coming in over to
++ * the main block device spawning the RPMB character device.
++ */
++static long mmc_rpmb_ioctl(struct file *filp, unsigned int cmd,
++                         unsigned long arg)
++{
++      struct mmc_rpmb_data *rpmb = filp->private_data;
++      int ret;
++
++      switch (cmd) {
++      case MMC_IOC_CMD:
++              ret = mmc_blk_ioctl_cmd(rpmb->md,
++                                      (struct mmc_ioc_cmd __user *)arg,
++                                      rpmb);
++              break;
++      case MMC_IOC_MULTI_CMD:
++              ret = mmc_blk_ioctl_multi_cmd(rpmb->md,
++                                      (struct mmc_ioc_multi_cmd __user *)arg,
++                                      rpmb);
++              break;
++      default:
++              ret = -EINVAL;
++              break;
++      }
++
++      return ret;
++}
++
++#ifdef CONFIG_COMPAT
++static long mmc_rpmb_ioctl_compat(struct file *filp, unsigned int cmd,
++                            unsigned long arg)
++{
++      return mmc_rpmb_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
++}
++#endif
++
++static int mmc_rpmb_chrdev_open(struct inode *inode, struct file *filp)
++{
++      struct mmc_rpmb_data *rpmb = container_of(inode->i_cdev,
++                                                struct mmc_rpmb_data, chrdev);
++
++      get_device(&rpmb->dev);
++      filp->private_data = rpmb;
++      mmc_blk_get(rpmb->md->disk);
++
++      return nonseekable_open(inode, filp);
++}
++
++static int mmc_rpmb_chrdev_release(struct inode *inode, struct file *filp)
++{
++      struct mmc_rpmb_data *rpmb = container_of(inode->i_cdev,
++                                                struct mmc_rpmb_data, chrdev);
++
++      put_device(&rpmb->dev);
++      mmc_blk_put(rpmb->md);
++
++      return 0;
++}
++
++static const struct file_operations mmc_rpmb_fileops = {
++      .release = mmc_rpmb_chrdev_release,
++      .open = mmc_rpmb_chrdev_open,
++      .owner = THIS_MODULE,
++      .llseek = no_llseek,
++      .unlocked_ioctl = mmc_rpmb_ioctl,
++#ifdef CONFIG_COMPAT
++      .compat_ioctl = mmc_rpmb_ioctl_compat,
++#endif
++};
++
++static void mmc_blk_rpmb_device_release(struct device *dev)
++{
++      struct mmc_rpmb_data *rpmb = dev_get_drvdata(dev);
++
++      ida_simple_remove(&mmc_rpmb_ida, rpmb->id);
++      kfree(rpmb);
++}
++
++static int mmc_blk_alloc_rpmb_part(struct mmc_card *card,
++                                 struct mmc_blk_data *md,
++                                 unsigned int part_index,
++                                 sector_t size,
++                                 const char *subname)
++{
++      int devidx, ret;
++      char rpmb_name[DISK_NAME_LEN];
++      char cap_str[10];
++      struct mmc_rpmb_data *rpmb;
++
++      /* This creates the minor number for the RPMB char device */
++      devidx = ida_simple_get(&mmc_rpmb_ida, 0, max_devices, GFP_KERNEL);
++      if (devidx < 0)
++              return devidx;
++
++      rpmb = kzalloc(sizeof(*rpmb), GFP_KERNEL);
++      if (!rpmb) {
++              ida_simple_remove(&mmc_rpmb_ida, devidx);
++              return -ENOMEM;
++      }
++
++      snprintf(rpmb_name, sizeof(rpmb_name),
++               "mmcblk%u%s", card->host->index, subname ? subname : "");
++
++      rpmb->id = devidx;
++      rpmb->part_index = part_index;
++      rpmb->dev.init_name = rpmb_name;
++      rpmb->dev.bus = &mmc_rpmb_bus_type;
++      rpmb->dev.devt = MKDEV(MAJOR(mmc_rpmb_devt), rpmb->id);
++      rpmb->dev.parent = &card->dev;
++      rpmb->dev.release = mmc_blk_rpmb_device_release;
++      device_initialize(&rpmb->dev);
++      dev_set_drvdata(&rpmb->dev, rpmb);
++      rpmb->md = md;
++
++      cdev_init(&rpmb->chrdev, &mmc_rpmb_fileops);
++      rpmb->chrdev.owner = THIS_MODULE;
++      ret = cdev_device_add(&rpmb->chrdev, &rpmb->dev);
++      if (ret) {
++              pr_err("%s: could not add character device\n", rpmb_name);
++              goto out_put_device;
++      }
++
++      list_add(&rpmb->node, &md->rpmbs);
++
++      string_get_size((u64)size, 512, STRING_UNITS_2,
++                      cap_str, sizeof(cap_str));
++
++      pr_info("%s: %s %s partition %u %s, chardev (%d:%d)\n",
++              rpmb_name, mmc_card_id(card),
++              mmc_card_name(card), EXT_CSD_PART_CONFIG_ACC_RPMB, cap_str,
++              MAJOR(mmc_rpmb_devt), rpmb->id);
++
++      return 0;
++
++out_put_device:
++      put_device(&rpmb->dev);
++      return ret;
++}
++
++static void mmc_blk_remove_rpmb_part(struct mmc_rpmb_data *rpmb)
++
++{
++      cdev_device_del(&rpmb->chrdev, &rpmb->dev);
++      put_device(&rpmb->dev);
++}
++
+ /* MMC Physical partitions consist of two boot partitions and
+  * up to four general purpose partitions.
+  * For each partition enabled in EXT_CSD a block device will be allocatedi
+@@ -2240,13 +2434,26 @@ static int mmc_blk_alloc_part(struct mmc_card *card,
+ 
+ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
+ {
+-      int idx, ret = 0;
++      int idx, ret;
+ 
+       if (!mmc_card_mmc(card))
+               return 0;
+ 
+       for (idx = 0; idx < card->nr_parts; idx++) {
+-              if (card->part[idx].size) {
++              if (card->part[idx].area_type & MMC_BLK_DATA_AREA_RPMB) {
++                      /*
++                       * RPMB partitions does not provide block access, they
++                       * are only accessed using ioctl():s. Thus create
++                       * special RPMB block devices that do not have a
++                       * backing block queue for these.
++                       */
++                      ret = mmc_blk_alloc_rpmb_part(card, md,
++                              card->part[idx].part_cfg,
++                              card->part[idx].size >> 9,
++                              card->part[idx].name);
++                      if (ret)
++                              return ret;
++              } else if (card->part[idx].size) {
+                       ret = mmc_blk_alloc_part(card, md,
+                               card->part[idx].part_cfg,
+                               card->part[idx].size >> 9,
+@@ -2258,7 +2465,7 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, 
struct mmc_blk_data *md)
+               }
+       }
+ 
+-      return ret;
++      return 0;
+ }
+ 
+ static void mmc_blk_remove_req(struct mmc_blk_data *md)
+@@ -2295,7 +2502,15 @@ static void mmc_blk_remove_parts(struct mmc_card *card,
+ {
+       struct list_head *pos, *q;
+       struct mmc_blk_data *part_md;
++      struct mmc_rpmb_data *rpmb;
+ 
++      /* Remove RPMB partitions */
++      list_for_each_safe(pos, q, &md->rpmbs) {
++              rpmb = list_entry(pos, struct mmc_rpmb_data, node);
++              list_del(pos);
++              mmc_blk_remove_rpmb_part(rpmb);
++      }
++      /* Remove block partitions */
+       list_for_each_safe(pos, q, &md->part) {
+               part_md = list_entry(pos, struct mmc_blk_data, part);
+               list_del(pos);
+@@ -2649,6 +2864,17 @@ static int __init mmc_blk_init(void)
+ {
+       int res;
+ 
++      res  = bus_register(&mmc_rpmb_bus_type);
++      if (res < 0) {
++              pr_err("mmcblk: could not register RPMB bus type\n");
++              return res;
++      }
++      res = alloc_chrdev_region(&mmc_rpmb_devt, 0, MAX_DEVICES, "rpmb");
++      if (res < 0) {
++              pr_err("mmcblk: failed to allocate rpmb chrdev region\n");
++              goto out_bus_unreg;
++      }
++
+       if (perdev_minors != CONFIG_MMC_BLOCK_MINORS)
+               pr_info("mmcblk: using %d minors per device\n", perdev_minors);
+ 
+@@ -2656,16 +2882,20 @@ static int __init mmc_blk_init(void)
+ 
+       res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
+       if (res)
+-              goto out;
++              goto out_chrdev_unreg;
+ 
+       res = mmc_register_driver(&mmc_driver);
+       if (res)
+-              goto out2;
++              goto out_blkdev_unreg;
+ 
+       return 0;
+- out2:
++
++out_blkdev_unreg:
+       unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
+- out:
++out_chrdev_unreg:
++      unregister_chrdev_region(mmc_rpmb_devt, MAX_DEVICES);
++out_bus_unreg:
++      bus_unregister(&mmc_rpmb_bus_type);
+       return res;
+ }
+ 
+@@ -2673,6 +2903,8 @@ static void __exit mmc_blk_exit(void)
+ {
+       mmc_unregister_driver(&mmc_driver);
+       unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
++      unregister_chrdev_region(mmc_rpmb_devt, MAX_DEVICES);
++      bus_unregister(&mmc_rpmb_bus_type);
+ }
+ 
+ module_init(mmc_blk_init);
+diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
+index 0a4e77a5ba33..f74f9ef460cc 100644
+--- a/drivers/mmc/core/queue.c
++++ b/drivers/mmc/core/queue.c
+@@ -30,7 +30,7 @@ static int mmc_prep_request(struct request_queue *q, struct 
request *req)
+ {
+       struct mmc_queue *mq = q->queuedata;
+ 
+-      if (mq && (mmc_card_removed(mq->card) || mmc_access_rpmb(mq)))
++      if (mq && mmc_card_removed(mq->card))
+               return BLKPREP_KILL;
+ 
+       req->rq_flags |= RQF_DONTPREP;
+diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h
+index 6bfba32ffa66..547b457c4251 100644
+--- a/drivers/mmc/core/queue.h
++++ b/drivers/mmc/core/queue.h
+@@ -36,12 +36,14 @@ struct mmc_blk_request {
+ /**
+  * enum mmc_drv_op - enumerates the operations in the mmc_queue_req
+  * @MMC_DRV_OP_IOCTL: ioctl operation
++ * @MMC_DRV_OP_IOCTL_RPMB: RPMB-oriented ioctl operation
+  * @MMC_DRV_OP_BOOT_WP: write protect boot partitions
+  * @MMC_DRV_OP_GET_CARD_STATUS: get card status
+  * @MMC_DRV_OP_GET_EXT_CSD: get the EXT CSD from an eMMC card
+  */
+ enum mmc_drv_op {
+       MMC_DRV_OP_IOCTL,
++      MMC_DRV_OP_IOCTL_RPMB,
+       MMC_DRV_OP_BOOT_WP,
+       MMC_DRV_OP_GET_CARD_STATUS,
+       MMC_DRV_OP_GET_EXT_CSD,
+@@ -82,6 +84,4 @@ extern void mmc_queue_resume(struct mmc_queue *);
+ extern unsigned int mmc_queue_map_sg(struct mmc_queue *,
+                                    struct mmc_queue_req *);
+ 
+-extern int mmc_access_rpmb(struct mmc_queue *);
+-
+ #endif
+diff --git a/drivers/net/dsa/mv88e6xxx/global1.c 
b/drivers/net/dsa/mv88e6xxx/global1.c
+index d76d7c7ea819..544b6a9cc01a 100644
+--- a/drivers/net/dsa/mv88e6xxx/global1.c
++++ b/drivers/net/dsa/mv88e6xxx/global1.c
+@@ -313,6 +313,11 @@ int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip 
*chip, int port)
+ {
+       u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST;
+ 
++      /* Use the default high priority for management frames sent to
++       * the CPU.
++       */
++      port |= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI;
++
+       return mv88e6390_g1_monitor_write(chip, ptr, port);
+ }
+ 
+diff --git a/drivers/net/dsa/mv88e6xxx/global1.h 
b/drivers/net/dsa/mv88e6xxx/global1.h
+index 950b914f9251..d82e8956cbd5 100644
+--- a/drivers/net/dsa/mv88e6xxx/global1.h
++++ b/drivers/net/dsa/mv88e6xxx/global1.h
+@@ -189,6 +189,7 @@
+ #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST                0x2000
+ #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST         0x2100
+ #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST            0x3000
++#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI    0x00e0
+ #define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK                       0x00ff
+ 
+ /* Offset 0x1C: Global Control 2 */
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+index 4e091a11daaf..52bce009d096 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+@@ -1112,7 +1112,7 @@ static inline u8 bnx2x_get_path_func_num(struct bnx2x 
*bp)
+               for (i = 0; i < E1H_FUNC_MAX / 2; i++) {
+                       u32 func_config =
+                               MF_CFG_RD(bp,
+-                                        func_mf_config[BP_PORT(bp) + 2 * i].
++                                        func_mf_config[BP_PATH(bp) + 2 * i].
+                                         config);
+                       func_num +=
+                               ((func_config & FUNC_MF_CFG_FUNC_HIDE) ? 0 : 1);
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+index dbe8feec456c..b0ada7eac652 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+@@ -9995,10 +9995,18 @@ static void bnx2x_recovery_failed(struct bnx2x *bp)
+  */
+ static void bnx2x_parity_recover(struct bnx2x *bp)
+ {
+-      bool global = false;
+       u32 error_recovered, error_unrecovered;
+-      bool is_parity;
++      bool is_parity, global = false;
++#ifdef CONFIG_BNX2X_SRIOV
++      int vf_idx;
++
++      for (vf_idx = 0; vf_idx < bp->requested_nr_virtfn; vf_idx++) {
++              struct bnx2x_virtf *vf = BP_VF(bp, vf_idx);
+ 
++              if (vf)
++                      vf->state = VF_LOST;
++      }
++#endif
+       DP(NETIF_MSG_HW, "Handling parity\n");
+       while (1) {
+               switch (bp->recovery_state) {
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+index 53466f6cebab..a887bfa24c88 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+@@ -139,6 +139,7 @@ struct bnx2x_virtf {
+ #define VF_ACQUIRED   1       /* VF acquired, but not initialized */
+ #define VF_ENABLED    2       /* VF Enabled */
+ #define VF_RESET      3       /* VF FLR'd, pending cleanup */
++#define VF_LOST               4       /* Recovery while VFs are loaded */
+ 
+       bool flr_clnup_stage;   /* true during flr cleanup */
+       bool malicious;         /* true if FW indicated so, until FLR */
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c 
b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+index 76a4668c50fe..6d5b81a971e3 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+@@ -2112,6 +2112,18 @@ static void bnx2x_vf_mbx_request(struct bnx2x *bp, 
struct bnx2x_virtf *vf,
+ {
+       int i;
+ 
++      if (vf->state == VF_LOST) {
++              /* Just ack the FW and return if VFs are lost
++               * in case of parity error. VFs are supposed to be timedout
++               * on waiting for PF response.
++               */
++              DP(BNX2X_MSG_IOV,
++                 "VF 0x%x lost, not handling the request\n", vf->abs_vfid);
++
++              storm_memset_vf_mbx_ack(bp, vf->abs_vfid);
++              return;
++      }
++
+       /* check if tlv type is known */
+       if (bnx2x_tlv_supported(mbx->first_tlv.tl.type)) {
+               /* Lock the per vf op mutex and note the locker's identity.
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+index a62128a444a6..149fd0d5e069 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+@@ -724,6 +724,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
+               /* default */
+               break;
+       case PHY_INTERFACE_MODE_RGMII:
++      case PHY_INTERFACE_MODE_RGMII_ID:
++      case PHY_INTERFACE_MODE_RGMII_RXID:
++      case PHY_INTERFACE_MODE_RGMII_TXID:
+               reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII;
+               break;
+       case PHY_INTERFACE_MODE_RMII:
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+index 62ccbd47c1db..fc1fa0f9f338 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+@@ -53,7 +53,7 @@ static int sun7i_gmac_init(struct platform_device *pdev, 
void *priv)
+        * rate, which then uses the auto-reparenting feature of the
+        * clock driver, and enabling/disabling the clock.
+        */
+-      if (gmac->interface == PHY_INTERFACE_MODE_RGMII) {
++      if (phy_interface_mode_is_rgmii(gmac->interface)) {
+               clk_set_rate(gmac->tx_clk, SUN7I_GMAC_GMII_RGMII_RATE);
+               clk_prepare_enable(gmac->tx_clk);
+               gmac->clk_enabled = 1;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index e6d16c48ffef..e89466bd432d 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -51,7 +51,7 @@
+ #include <linux/of_mdio.h>
+ #include "dwmac1000.h"
+ 
+-#define       STMMAC_ALIGN(x)         __ALIGN_KERNEL(x, SMP_CACHE_BYTES)
++#define       STMMAC_ALIGN(x)         ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16)
+ #define       TSO_MAX_BUFF_SIZE       (SZ_16K - 1)
+ 
+ /* Module parameters */
+@@ -3597,12 +3597,24 @@ static void stmmac_set_rx_mode(struct net_device *dev)
+ static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
+ {
+       struct stmmac_priv *priv = netdev_priv(dev);
++      int txfifosz = priv->plat->tx_fifo_size;
++
++      if (txfifosz == 0)
++              txfifosz = priv->dma_cap.tx_fifo_size;
++
++      txfifosz /= priv->plat->tx_queues_to_use;
+ 
+       if (netif_running(dev)) {
+               netdev_err(priv->dev, "must be stopped to change its MTU\n");
+               return -EBUSY;
+       }
+ 
++      new_mtu = STMMAC_ALIGN(new_mtu);
++
++      /* If condition true, FIFO is too small or MTU too large */
++      if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB))
++              return -EINVAL;
++
+       dev->mtu = new_mtu;
+ 
+       netdev_update_features(dev);
+diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
+index 35905e9ee9ec..25be27826a22 100644
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -816,7 +816,7 @@ static struct sock *gtp_encap_enable_socket(int fd, int 
type,
+       lock_sock(sock->sk);
+       if (sock->sk->sk_user_data) {
+               sk = ERR_PTR(-EBUSY);
+-              goto out_sock;
++              goto out_rel_sock;
+       }
+ 
+       sk = sock->sk;
+@@ -829,8 +829,9 @@ static struct sock *gtp_encap_enable_socket(int fd, int 
type,
+ 
+       setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg);
+ 
+-out_sock:
++out_rel_sock:
+       release_sock(sock->sk);
++out_sock:
+       sockfd_put(sock);
+       return sk;
+ }
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+index 0f07b5978fa1..fc794e69e6a1 100644
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -179,7 +179,6 @@ struct rndis_device {
+ 
+       u8 hw_mac_adr[ETH_ALEN];
+       u8 rss_key[NETVSC_HASH_KEYLEN];
+-      u16 rx_table[ITAB_NUM];
+ };
+ 
+ 
+@@ -741,6 +740,8 @@ struct net_device_context {
+ 
+       u32 tx_table[VRSS_SEND_TAB_SIZE];
+ 
++      u16 rx_table[ITAB_NUM];
++
+       /* Ethtool settings */
+       bool udp4_l4_hash;
+       bool udp6_l4_hash;
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+index 5a44b9795266..a89de5752a8c 100644
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -1528,7 +1528,7 @@ static int netvsc_get_rxfh(struct net_device *dev, u32 
*indir, u8 *key,
+       rndis_dev = ndev->extension;
+       if (indir) {
+               for (i = 0; i < ITAB_NUM; i++)
+-                      indir[i] = rndis_dev->rx_table[i];
++                      indir[i] = ndc->rx_table[i];
+       }
+ 
+       if (key)
+@@ -1558,7 +1558,7 @@ static int netvsc_set_rxfh(struct net_device *dev, const 
u32 *indir,
+                               return -EINVAL;
+ 
+               for (i = 0; i < ITAB_NUM; i++)
+-                      rndis_dev->rx_table[i] = indir[i];
++                      ndc->rx_table[i] = indir[i];
+       }
+ 
+       if (!key) {
+diff --git a/drivers/net/hyperv/rndis_filter.c 
b/drivers/net/hyperv/rndis_filter.c
+index fc1d5e14d83e..b19557c035f2 100644
+--- a/drivers/net/hyperv/rndis_filter.c
++++ b/drivers/net/hyperv/rndis_filter.c
+@@ -715,6 +715,7 @@ static int rndis_set_rss_param_msg(struct rndis_device 
*rdev,
+                                  const u8 *rss_key, u16 flag)
+ {
+       struct net_device *ndev = rdev->ndev;
++      struct net_device_context *ndc = netdev_priv(ndev);
+       struct rndis_request *request;
+       struct rndis_set_request *set;
+       struct rndis_set_complete *set_complete;
+@@ -754,7 +755,7 @@ static int rndis_set_rss_param_msg(struct rndis_device 
*rdev,
+       /* Set indirection table entries */
+       itab = (u32 *)(rssp + 1);
+       for (i = 0; i < ITAB_NUM; i++)
+-              itab[i] = rdev->rx_table[i];
++              itab[i] = ndc->rx_table[i];
+ 
+       /* Set hask key values */
+       keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
+@@ -1204,6 +1205,7 @@ struct netvsc_device *rndis_filter_device_add(struct 
hv_device *dev,
+                                     struct netvsc_device_info *device_info)
+ {
+       struct net_device *net = hv_get_drvdata(dev);
++      struct net_device_context *ndc = netdev_priv(net);
+       struct netvsc_device *net_device;
+       struct rndis_device *rndis_device;
+       struct ndis_recv_scale_cap rsscap;
+@@ -1286,9 +1288,11 @@ struct netvsc_device *rndis_filter_device_add(struct 
hv_device *dev,
+       /* We will use the given number of channels if available. */
+       net_device->num_chn = min(net_device->max_chn, device_info->num_chn);
+ 
+-      for (i = 0; i < ITAB_NUM; i++)
+-              rndis_device->rx_table[i] = ethtool_rxfh_indir_default(
++      if (!netif_is_rxfh_configured(net)) {
++              for (i = 0; i < ITAB_NUM; i++)
++                      ndc->rx_table[i] = ethtool_rxfh_indir_default(
+                                               i, net_device->num_chn);
++      }
+ 
+       atomic_set(&net_device->open_chn, 1);
+       vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index 8d5f88a538fc..2b977655834c 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -263,7 +263,7 @@ static void macvlan_broadcast(struct sk_buff *skb,
+                             struct net_device *src,
+                             enum macvlan_mode mode)
+ {
+-      const struct ethhdr *eth = eth_hdr(skb);
++      const struct ethhdr *eth = skb_eth_hdr(skb);
+       const struct macvlan_dev *vlan;
+       struct sk_buff *nskb;
+       unsigned int i;
+diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
+index 7d1d5b30ecc3..c23f35dba718 100644
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -497,7 +497,7 @@ static int lan78xx_read_stats(struct lan78xx_net *dev,
+               }
+       } else {
+               netdev_warn(dev->net,
+-                          "Failed to read stat ret = 0x%x", ret);
++                          "Failed to read stat ret = %d", ret);
+       }
+ 
+       kfree(stats);
+@@ -2604,11 +2604,6 @@ static int lan78xx_stop(struct net_device *net)
+       return 0;
+ }
+ 
+-static int lan78xx_linearize(struct sk_buff *skb)
+-{
+-      return skb_linearize(skb);
+-}
+-
+ static struct sk_buff *lan78xx_tx_prep(struct lan78xx_net *dev,
+                                      struct sk_buff *skb, gfp_t flags)
+ {
+@@ -2619,8 +2614,10 @@ static struct sk_buff *lan78xx_tx_prep(struct 
lan78xx_net *dev,
+               return NULL;
+       }
+ 
+-      if (lan78xx_linearize(skb) < 0)
++      if (skb_linearize(skb)) {
++              dev_kfree_skb_any(skb);
+               return NULL;
++      }
+ 
+       tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN_MASK_) | TX_CMD_A_FCS_;
+ 
+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
+index 153a81ece9fe..5aa7d5091f4d 100644
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -2216,7 +2216,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct 
net_device *dev,
+                       skb_dst_update_pmtu(skb, mtu);
+               }
+ 
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(RT_TOS(tos), old_iph, skb);
+               ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
+                                     vni, md, flags, udp_sum);
+@@ -2257,7 +2257,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct 
net_device *dev,
+                       skb_dst_update_pmtu(skb, mtu);
+               }
+ 
+-              tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
++              tos = ip_tunnel_ecn_encap(RT_TOS(tos), old_iph, skb);
+               ttl = ttl ? : ip6_dst_hoplimit(ndst);
+               skb_scrub_packet(skb, xnet);
+               err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
+diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c 
b/drivers/net/wireless/marvell/mwifiex/tdls.c
+index e76af2866a19..b5340af9fa5e 100644
+--- a/drivers/net/wireless/marvell/mwifiex/tdls.c
++++ b/drivers/net/wireless/marvell/mwifiex/tdls.c
+@@ -956,59 +956,117 @@ void mwifiex_process_tdls_action_frame(struct 
mwifiex_private *priv,
+ 
+               switch (*pos) {
+               case WLAN_EID_SUPP_RATES:
++                      if (pos[1] > 32)
++                              return;
+                       sta_ptr->tdls_cap.rates_len = pos[1];
+                       for (i = 0; i < pos[1]; i++)
+                               sta_ptr->tdls_cap.rates[i] = pos[i + 2];
+                       break;
+ 
+               case WLAN_EID_EXT_SUPP_RATES:
++                      if (pos[1] > 32)
++                              return;
+                       basic = sta_ptr->tdls_cap.rates_len;
++                      if (pos[1] > 32 - basic)
++                              return;
+                       for (i = 0; i < pos[1]; i++)
+                               sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2];
+                       sta_ptr->tdls_cap.rates_len += pos[1];
+                       break;
+               case WLAN_EID_HT_CAPABILITY:
+-                      memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos,
++                      if (pos > end - sizeof(struct ieee80211_ht_cap) - 2)
++                              return;
++                      if (pos[1] != sizeof(struct ieee80211_ht_cap))
++                              return;
++                      /* copy the ie's value into ht_capb*/
++                      memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2,
+                              sizeof(struct ieee80211_ht_cap));
+                       sta_ptr->is_11n_enabled = 1;
+                       break;
+               case WLAN_EID_HT_OPERATION:
+-                      memcpy(&sta_ptr->tdls_cap.ht_oper, pos,
++                      if (pos > end -
++                          sizeof(struct ieee80211_ht_operation) - 2)
++                              return;
++                      if (pos[1] != sizeof(struct ieee80211_ht_operation))
++                              return;
++                      /* copy the ie's value into ht_oper*/
++                      memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2,
+                              sizeof(struct ieee80211_ht_operation));
+                       break;
+               case WLAN_EID_BSS_COEX_2040:
++                      if (pos > end - 3)
++                              return;
++                      if (pos[1] != 1)
++                              return;
+                       sta_ptr->tdls_cap.coex_2040 = pos[2];
+                       break;
+               case WLAN_EID_EXT_CAPABILITY:
++                      if (pos > end - sizeof(struct ieee_types_header))
++                              return;
++                      if (pos[1] < sizeof(struct ieee_types_header))
++                              return;
++                      if (pos[1] > 8)
++                              return;
+                       memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos,
+                              sizeof(struct ieee_types_header) +
+                              min_t(u8, pos[1], 8));
+                       break;
+               case WLAN_EID_RSN:
++                      if (pos > end - sizeof(struct ieee_types_header))
++                              return;
++                      if (pos[1] < sizeof(struct ieee_types_header))
++                              return;
++                      if (pos[1] > IEEE_MAX_IE_SIZE -
++                          sizeof(struct ieee_types_header))
++                              return;
+                       memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
+                              sizeof(struct ieee_types_header) +
+                              min_t(u8, pos[1], IEEE_MAX_IE_SIZE -
+                                    sizeof(struct ieee_types_header)));
+                       break;
+               case WLAN_EID_QOS_CAPA:
++                      if (pos > end - 3)
++                              return;
++                      if (pos[1] != 1)
++                              return;
+                       sta_ptr->tdls_cap.qos_info = pos[2];
+                       break;
+               case WLAN_EID_VHT_OPERATION:
+-                      if (priv->adapter->is_hw_11ac_capable)
+-                              memcpy(&sta_ptr->tdls_cap.vhtoper, pos,
++                      if (priv->adapter->is_hw_11ac_capable) {
++                              if (pos > end -
++                                  sizeof(struct ieee80211_vht_operation) - 2)
++                                      return;
++                              if (pos[1] !=
++                                  sizeof(struct ieee80211_vht_operation))
++                                      return;
++                              /* copy the ie's value into vhtoper*/
++                              memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2,
+                                      sizeof(struct ieee80211_vht_operation));
++                      }
+                       break;
+               case WLAN_EID_VHT_CAPABILITY:
+                       if (priv->adapter->is_hw_11ac_capable) {
+-                              memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos,
++                              if (pos > end -
++                                  sizeof(struct ieee80211_vht_cap) - 2)
++                                      return;
++                              if (pos[1] != sizeof(struct ieee80211_vht_cap))
++                                      return;
++                              /* copy the ie's value into vhtcap*/
++                              memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2,
+                                      sizeof(struct ieee80211_vht_cap));
+                               sta_ptr->is_11ac_enabled = 1;
+                       }
+                       break;
+               case WLAN_EID_AID:
+-                      if (priv->adapter->is_hw_11ac_capable)
++                      if (priv->adapter->is_hw_11ac_capable) {
++                              if (pos > end - 4)
++                                      return;
++                              if (pos[1] != 2)
++                                      return;
+                               sta_ptr->tdls_cap.aid =
+                                       get_unaligned_le16((pos + 2));
++                      }
++                      break;
+               default:
+                       break;
+               }
+diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
+index e3aefdafae89..0941555b84a5 100644
+--- a/drivers/pci/switch/switchtec.c
++++ b/drivers/pci/switch/switchtec.c
+@@ -23,7 +23,7 @@
+ #include <linux/pci.h>
+ #include <linux/cdev.h>
+ #include <linux/wait.h>
+-
++#include <linux/io-64-nonatomic-lo-hi.h>
+ #include <linux/nospec.h>
+ 
+ MODULE_DESCRIPTION("Microsemi Switchtec(tm) PCIe Management Driver");
+@@ -898,7 +898,7 @@ static int ioctl_event_summary(struct switchtec_dev *stdev,
+       u32 reg;
+ 
+       s.global = ioread32(&stdev->mmio_sw_event->global_summary);
+-      s.part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap);
++      s.part_bitmap = readq(&stdev->mmio_sw_event->part_event_bitmap);
+       s.local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary);
+ 
+       for (i = 0; i < stdev->partition_count; i++) {
+diff --git a/drivers/regulator/rn5t618-regulator.c 
b/drivers/regulator/rn5t618-regulator.c
+index 790a4a73ea2c..40b74648bd31 100644
+--- a/drivers/regulator/rn5t618-regulator.c
++++ b/drivers/regulator/rn5t618-regulator.c
+@@ -154,6 +154,7 @@ static struct platform_driver rn5t618_regulator_driver = {
+ 
+ module_platform_driver(rn5t618_regulator_driver);
+ 
++MODULE_ALIAS("platform:rn5t618-regulator");
+ MODULE_AUTHOR("Beniamino Galvani <b.galv...@gmail.com>");
+ MODULE_DESCRIPTION("RN5T618 regulator driver");
+ MODULE_LICENSE("GPL v2");
+diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
+index 0d5e2d92e05b..aa651403546f 100644
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -1133,7 +1133,8 @@ static u32 get_fcx_max_data(struct dasd_device *device)
+ {
+       struct dasd_eckd_private *private = device->private;
+       int fcx_in_css, fcx_in_gneq, fcx_in_features;
+-      int tpm, mdc;
++      unsigned int mdc;
++      int tpm;
+ 
+       if (dasd_nofcx)
+               return 0;
+@@ -1147,7 +1148,7 @@ static u32 get_fcx_max_data(struct dasd_device *device)
+               return 0;
+ 
+       mdc = ccw_device_get_mdc(device->cdev, 0);
+-      if (mdc < 0) {
++      if (mdc == 0) {
+               dev_warn(&device->cdev->dev, "Detecting the maximum supported 
data size for zHPF requests failed\n");
+               return 0;
+       } else {
+@@ -1158,12 +1159,12 @@ static u32 get_fcx_max_data(struct dasd_device *device)
+ static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm)
+ {
+       struct dasd_eckd_private *private = device->private;
+-      int mdc;
++      unsigned int mdc;
+       u32 fcx_max_data;
+ 
+       if (private->fcx_max_data) {
+               mdc = ccw_device_get_mdc(device->cdev, lpm);
+-              if ((mdc < 0)) {
++              if (mdc == 0) {
+                       dev_warn(&device->cdev->dev,
+                                "Detecting the maximum data size for zHPF "
+                                "requests failed (rc=%d) for a new path %x\n",
+@@ -1767,7 +1768,7 @@ out_err2:
+       dasd_free_block(device->block);
+       device->block = NULL;
+ out_err1:
+-      kfree(private->conf_data);
++      dasd_eckd_clear_conf_data(device);
+       kfree(device->private);
+       device->private = NULL;
+       return rc;
+@@ -1776,7 +1777,6 @@ out_err1:
+ static void dasd_eckd_uncheck_device(struct dasd_device *device)
+ {
+       struct dasd_eckd_private *private = device->private;
+-      int i;
+ 
+       if (!private)
+               return;
+@@ -1786,21 +1786,7 @@ static void dasd_eckd_uncheck_device(struct dasd_device 
*device)
+       private->sneq = NULL;
+       private->vdsneq = NULL;
+       private->gneq = NULL;
+-      private->conf_len = 0;
+-      for (i = 0; i < 8; i++) {
+-              kfree(device->path[i].conf_data);
+-              if ((__u8 *)device->path[i].conf_data ==
+-                  private->conf_data) {
+-                      private->conf_data = NULL;
+-                      private->conf_len = 0;
+-              }
+-              device->path[i].conf_data = NULL;
+-              device->path[i].cssid = 0;
+-              device->path[i].ssid = 0;
+-              device->path[i].chpid = 0;
+-      }
+-      kfree(private->conf_data);
+-      private->conf_data = NULL;
++      dasd_eckd_clear_conf_data(device);
+ }
+ 
+ static struct dasd_ccw_req *
+diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
+index b22922ec32d1..474afec9ab87 100644
+--- a/drivers/s390/cio/device_ops.c
++++ b/drivers/s390/cio/device_ops.c
+@@ -595,7 +595,7 @@ EXPORT_SYMBOL(ccw_device_tm_start_timeout);
+  * @mask: mask of paths to use
+  *
+  * Return the number of 64K-bytes blocks all paths at least support
+- * for a transport command. Return values <= 0 indicate failures.
++ * for a transport command. Return value 0 indicates failure.
+  */
+ int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask)
+ {
+diff --git a/drivers/spi/spi-cavium-thunderx.c 
b/drivers/spi/spi-cavium-thunderx.c
+index 877937706240..828fbbebc3c4 100644
+--- a/drivers/spi/spi-cavium-thunderx.c
++++ b/drivers/spi/spi-cavium-thunderx.c
+@@ -81,6 +81,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
+ 
+ error:
+       clk_disable_unprepare(p->clk);
++      pci_release_regions(pdev);
+       spi_master_put(master);
+       return ret;
+ }
+@@ -95,6 +96,7 @@ static void thunderx_spi_remove(struct pci_dev *pdev)
+               return;
+ 
+       clk_disable_unprepare(p->clk);
++      pci_release_regions(pdev);
+       /* Put everything in a known state. */
+       writeq(0, p->register_base + OCTEON_SPI_CFG(p));
+ }
+diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
+index cfb8f1126cf8..1f525d5f6d2d 100644
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -203,9 +203,58 @@ static const unsigned short 
super_speed_maxpacket_maxes[4] = {
+       [USB_ENDPOINT_XFER_INT] = 1024,
+ };
+ 
+-static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
+-    int asnum, struct usb_host_interface *ifp, int num_ep,
+-    unsigned char *buffer, int size)
++static bool endpoint_is_duplicate(struct usb_endpoint_descriptor *e1,
++              struct usb_endpoint_descriptor *e2)
++{
++      if (e1->bEndpointAddress == e2->bEndpointAddress)
++              return true;
++
++      if (usb_endpoint_xfer_control(e1) || usb_endpoint_xfer_control(e2)) {
++              if (usb_endpoint_num(e1) == usb_endpoint_num(e2))
++                      return true;
++      }
++
++      return false;
++}
++
++/*
++ * Check for duplicate endpoint addresses in other interfaces and in the
++ * altsetting currently being parsed.
++ */
++static bool config_endpoint_is_duplicate(struct usb_host_config *config,
++              int inum, int asnum, struct usb_endpoint_descriptor *d)
++{
++      struct usb_endpoint_descriptor *epd;
++      struct usb_interface_cache *intfc;
++      struct usb_host_interface *alt;
++      int i, j, k;
++
++      for (i = 0; i < config->desc.bNumInterfaces; ++i) {
++              intfc = config->intf_cache[i];
++
++              for (j = 0; j < intfc->num_altsetting; ++j) {
++                      alt = &intfc->altsetting[j];
++
++                      if (alt->desc.bInterfaceNumber == inum &&
++                                      alt->desc.bAlternateSetting != asnum)
++                              continue;
++
++                      for (k = 0; k < alt->desc.bNumEndpoints; ++k) {
++                              epd = &alt->endpoint[k].desc;
++
++                              if (endpoint_is_duplicate(epd, d))
++                                      return true;
++                      }
++              }
++      }
++
++      return false;
++}
++
++static int usb_parse_endpoint(struct device *ddev, int cfgno,
++              struct usb_host_config *config, int inum, int asnum,
++              struct usb_host_interface *ifp, int num_ep,
++              unsigned char *buffer, int size)
+ {
+       unsigned char *buffer0 = buffer;
+       struct usb_endpoint_descriptor *d;
+@@ -242,13 +291,10 @@ static int usb_parse_endpoint(struct device *ddev, int 
cfgno, int inum,
+               goto skip_to_next_endpoint_or_interface_descriptor;
+ 
+       /* Check for duplicate endpoint addresses */
+-      for (i = 0; i < ifp->desc.bNumEndpoints; ++i) {
+-              if (ifp->endpoint[i].desc.bEndpointAddress ==
+-                  d->bEndpointAddress) {
+-                      dev_warn(ddev, "config %d interface %d altsetting %d 
has a duplicate endpoint with address 0x%X, skipping\n",
+-                          cfgno, inum, asnum, d->bEndpointAddress);
+-                      goto skip_to_next_endpoint_or_interface_descriptor;
+-              }
++      if (config_endpoint_is_duplicate(config, inum, asnum, d)) {
++              dev_warn(ddev, "config %d interface %d altsetting %d has a 
duplicate endpoint with address 0x%X, skipping\n",
++                              cfgno, inum, asnum, d->bEndpointAddress);
++              goto skip_to_next_endpoint_or_interface_descriptor;
+       }
+ 
+       endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
+@@ -522,8 +568,8 @@ static int usb_parse_interface(struct device *ddev, int 
cfgno,
+               if (((struct usb_descriptor_header *) buffer)->bDescriptorType
+                    == USB_DT_INTERFACE)
+                       break;
+-              retval = usb_parse_endpoint(ddev, cfgno, inum, asnum, alt,
+-                  num_ep, buffer, size);
++              retval = usb_parse_endpoint(ddev, cfgno, config, inum, asnum,
++                              alt, num_ep, buffer, size);
+               if (retval < 0)
+                       return retval;
+               ++n;
+diff --git a/drivers/usb/gadget/udc/dummy_hcd.c 
b/drivers/usb/gadget/udc/dummy_hcd.c
+index 7e90f786d923..a0c1d77a7e38 100644
+--- a/drivers/usb/gadget/udc/dummy_hcd.c
++++ b/drivers/usb/gadget/udc/dummy_hcd.c
+@@ -1325,7 +1325,7 @@ static int dummy_perform_transfer(struct urb *urb, 
struct dummy_request *req,
+       u32 this_sg;
+       bool next_sg;
+ 
+-      to_host = usb_pipein(urb->pipe);
++      to_host = usb_urb_dir_in(urb);
+       rbuf = req->req.buf + req->req.actual;
+ 
+       if (!urb->num_sgs) {
+@@ -1413,7 +1413,7 @@ top:
+ 
+               /* FIXME update emulated data toggle too */
+ 
+-              to_host = usb_pipein(urb->pipe);
++              to_host = usb_urb_dir_in(urb);
+               if (unlikely(len == 0))
+                       is_short = 1;
+               else {
+@@ -1837,7 +1837,7 @@ restart:
+ 
+               /* find the gadget's ep for this request (if configured) */
+               address = usb_pipeendpoint (urb->pipe);
+-              if (usb_pipein(urb->pipe))
++              if (usb_urb_dir_in(urb))
+                       address |= USB_DIR_IN;
+               ep = find_endpoint(dum, address);
+               if (!ep) {
+@@ -2390,7 +2390,7 @@ static inline ssize_t show_urb(char *buf, size_t size, 
struct urb *urb)
+                       s = "?";
+                       break;
+                } s; }),
+-              ep, ep ? (usb_pipein(urb->pipe) ? "in" : "out") : "",
++              ep, ep ? (usb_urb_dir_in(urb) ? "in" : "out") : "",
+               ({ char *s; \
+               switch (usb_pipetype(urb->pipe)) { \
+               case PIPE_CONTROL: \
+@@ -2734,7 +2734,7 @@ static struct platform_driver dummy_hcd_driver = {
+ };
+ 
+ /*-------------------------------------------------------------------------*/
+-#define MAX_NUM_UDC   2
++#define MAX_NUM_UDC   32
+ static struct platform_device *the_udc_pdev[MAX_NUM_UDC];
+ static struct platform_device *the_hcd_pdev[MAX_NUM_UDC];
+ 
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 8d349f2e5656..dc9a1139e7e1 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1175,6 +1175,8 @@ static const struct usb_device_id option_ids[] = {
+         .driver_info = NCTRL(0) | RSVD(3) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1102, 0xff),    /* 
Telit ME910 (ECM) */
+         .driver_info = NCTRL(0) },
++      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110a, 0xff),    /* 
Telit ME910G1 */
++        .driver_info = NCTRL(0) | RSVD(3) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
+         .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
+diff --git a/fs/drop_caches.c b/fs/drop_caches.c
+index d31b6c72b476..dc1a1d5d825b 100644
+--- a/fs/drop_caches.c
++++ b/fs/drop_caches.c
+@@ -35,11 +35,11 @@ static void drop_pagecache_sb(struct super_block *sb, void 
*unused)
+               spin_unlock(&inode->i_lock);
+               spin_unlock(&sb->s_inode_list_lock);
+ 
+-              cond_resched();
+               invalidate_mapping_pages(inode->i_mapping, 0, -1);
+               iput(toput_inode);
+               toput_inode = inode;
+ 
++              cond_resched();
+               spin_lock(&sb->s_inode_list_lock);
+       }
+       spin_unlock(&sb->s_inode_list_lock);
+diff --git a/fs/inode.c b/fs/inode.c
+index 76f7535fe754..d2a700c5efce 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -656,6 +656,7 @@ int invalidate_inodes(struct super_block *sb, bool 
kill_dirty)
+       struct inode *inode, *next;
+       LIST_HEAD(dispose);
+ 
++again:
+       spin_lock(&sb->s_inode_list_lock);
+       list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
+               spin_lock(&inode->i_lock);
+@@ -678,6 +679,12 @@ int invalidate_inodes(struct super_block *sb, bool 
kill_dirty)
+               inode_lru_list_del(inode);
+               spin_unlock(&inode->i_lock);
+               list_add(&inode->i_lru, &dispose);
++              if (need_resched()) {
++                      spin_unlock(&sb->s_inode_list_lock);
++                      cond_resched();
++                      dispose_list(&dispose);
++                      goto again;
++              }
+       }
+       spin_unlock(&sb->s_inode_list_lock);
+ 
+diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
+index 506da82ff3f1..a308f7a7e577 100644
+--- a/fs/notify/fsnotify.c
++++ b/fs/notify/fsnotify.c
+@@ -90,6 +90,7 @@ void fsnotify_unmount_inodes(struct super_block *sb)
+ 
+               iput_inode = inode;
+ 
++              cond_resched();
+               spin_lock(&sb->s_inode_list_lock);
+       }
+       spin_unlock(&sb->s_inode_list_lock);
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 3fdbdd29702b..30f5da8f4aff 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -976,6 +976,7 @@ static int add_dquot_ref(struct super_block *sb, int type)
+                * later.
+                */
+               old_inode = inode;
++              cond_resched();
+               spin_lock(&sb->s_inode_list_lock);
+       }
+       spin_unlock(&sb->s_inode_list_lock);
+diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
+index 548fd535fd02..d433f5e292c9 100644
+--- a/include/linux/if_ether.h
++++ b/include/linux/if_ether.h
+@@ -28,6 +28,14 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff 
*skb)
+       return (struct ethhdr *)skb_mac_header(skb);
+ }
+ 
++/* Prefer this version in TX path, instead of
++ * skb_reset_mac_header() + eth_hdr()
++ */
++static inline struct ethhdr *skb_eth_hdr(const struct sk_buff *skb)
++{
++      return (struct ethhdr *)skb->data;
++}
++
+ static inline struct ethhdr *inner_eth_hdr(const struct sk_buff *skb)
+ {
+       return (struct ethhdr *)skb_inner_mac_header(skb);
+diff --git a/include/uapi/linux/netfilter/xt_sctp.h 
b/include/uapi/linux/netfilter/xt_sctp.h
+index 4bc6d1a08781..b4d804a9fccb 100644
+--- a/include/uapi/linux/netfilter/xt_sctp.h
++++ b/include/uapi/linux/netfilter/xt_sctp.h
+@@ -41,19 +41,19 @@ struct xt_sctp_info {
+ #define SCTP_CHUNKMAP_SET(chunkmap, type)             \
+       do {                                            \
+               (chunkmap)[type / bytes(__u32)] |=      \
+-                      1 << (type % bytes(__u32));     \
++                      1u << (type % bytes(__u32));    \
+       } while (0)
+ 
+ #define SCTP_CHUNKMAP_CLEAR(chunkmap, type)                   \
+       do {                                                    \
+               (chunkmap)[type / bytes(__u32)] &=              \
+-                      ~(1 << (type % bytes(__u32)));  \
++                      ~(1u << (type % bytes(__u32))); \
+       } while (0)
+ 
+ #define SCTP_CHUNKMAP_IS_SET(chunkmap, type)                  \
+ ({                                                            \
+       ((chunkmap)[type / bytes (__u32)] &             \
+-              (1 << (type % bytes (__u32)))) ? 1: 0;  \
++              (1u << (type % bytes (__u32)))) ? 1: 0; \
+ })
+ 
+ #define SCTP_CHUNKMAP_RESET(chunkmap) \
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index a4875ff0bab1..615a2e44d2a0 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1251,6 +1251,30 @@ static int check_ptr_alignment(struct bpf_verifier_env 
*env,
+       return check_generic_ptr_alignment(reg, pointer_desc, off, size, 
strict);
+ }
+ 
++static int check_ctx_reg(struct bpf_verifier_env *env,
++                       const struct bpf_reg_state *reg, int regno)
++{
++      /* Access to ctx or passing it to a helper is only allowed in
++       * its original, unmodified form.
++       */
++
++      if (reg->off) {
++              verbose("dereference of modified ctx ptr R%d off=%d 
disallowed\n",
++                      regno, reg->off);
++              return -EACCES;
++      }
++
++      if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
++              char tn_buf[48];
++
++              tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
++              verbose("variable ctx access var_off=%s disallowed\n", tn_buf);
++              return -EACCES;
++      }
++
++      return 0;
++}
++
+ /* truncate register to smaller size (in bytes)
+  * must be called with size < BPF_REG_SIZE
+  */
+@@ -1320,22 +1344,10 @@ static int check_mem_access(struct bpf_verifier_env 
*env, int insn_idx, u32 regn
+                       verbose("R%d leaks addr into ctx\n", value_regno);
+                       return -EACCES;
+               }
+-              /* ctx accesses must be at a fixed offset, so that we can
+-               * determine what type of data were returned.
+-               */
+-              if (reg->off) {
+-                      verbose("dereference of modified ctx ptr R%d off=%d+%d, 
ctx+const is allowed, ctx+const+const is not\n",
+-                              regno, reg->off, off - reg->off);
+-                      return -EACCES;
+-              }
+-              if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
+-                      char tn_buf[48];
++              err = check_ctx_reg(env, reg, regno);
++              if (err < 0)
++                      return err;
+ 
+-                      tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
+-                      verbose("variable ctx access var_off=%s off=%d size=%d",
+-                              tn_buf, off, size);
+-                      return -EACCES;
+-              }
+               err = check_ctx_access(env, insn_idx, off, size, t, &reg_type);
+               if (!err && t == BPF_READ && value_regno >= 0) {
+                       /* ctx access returns either a scalar, or a
+@@ -1573,6 +1585,9 @@ static int check_func_arg(struct bpf_verifier_env *env, 
u32 regno,
+               expected_type = PTR_TO_CTX;
+               if (type != expected_type)
+                       goto err_type;
++              err = check_ctx_reg(env, reg, regno);
++              if (err < 0)
++                      return err;
+       } else if (arg_type == ARG_PTR_TO_MEM ||
+                  arg_type == ARG_PTR_TO_UNINIT_MEM) {
+               expected_type = PTR_TO_STACK;
+@@ -3442,6 +3457,7 @@ static bool may_access_skb(enum bpf_prog_type type)
+ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
+ {
+       struct bpf_reg_state *regs = cur_regs(env);
++      static const int ctx_reg = BPF_REG_6;
+       u8 mode = BPF_MODE(insn->code);
+       int i, err;
+ 
+@@ -3458,11 +3474,11 @@ static int check_ld_abs(struct bpf_verifier_env *env, 
struct bpf_insn *insn)
+       }
+ 
+       /* check whether implicit source operand (register R6) is readable */
+-      err = check_reg_arg(env, BPF_REG_6, SRC_OP);
++      err = check_reg_arg(env, ctx_reg, SRC_OP);
+       if (err)
+               return err;
+ 
+-      if (regs[BPF_REG_6].type != PTR_TO_CTX) {
++      if (regs[ctx_reg].type != PTR_TO_CTX) {
+               verbose("at the time of BPF_LD_ABS|IND R6 != pointer to skb\n");
+               return -EINVAL;
+       }
+@@ -3474,6 +3490,10 @@ static int check_ld_abs(struct bpf_verifier_env *env, 
struct bpf_insn *insn)
+                       return err;
+       }
+ 
++      err = check_ctx_reg(env, &regs[ctx_reg], ctx_reg);
++      if (err < 0)
++              return err;
++
+       /* reset caller saved regs to unreadable */
+       for (i = 0; i < CALLER_SAVED_REGS; i++) {
+               mark_reg_not_init(regs, caller_saved[i]);
+diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c
+index 9aa0fccd5d43..03595c29c566 100644
+--- a/kernel/locking/spinlock_debug.c
++++ b/kernel/locking/spinlock_debug.c
+@@ -51,19 +51,19 @@ EXPORT_SYMBOL(__rwlock_init);
+ 
+ static void spin_dump(raw_spinlock_t *lock, const char *msg)
+ {
+-      struct task_struct *owner = NULL;
++      struct task_struct *owner = READ_ONCE(lock->owner);
+ 
+-      if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)
+-              owner = lock->owner;
++      if (owner == SPINLOCK_OWNER_INIT)
++              owner = NULL;
+       printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n",
+               msg, raw_smp_processor_id(),
+               current->comm, task_pid_nr(current));
+       printk(KERN_EMERG " lock: %pS, .magic: %08x, .owner: %s/%d, "
+                       ".owner_cpu: %d\n",
+-              lock, lock->magic,
++              lock, READ_ONCE(lock->magic),
+               owner ? owner->comm : "<none>",
+               owner ? task_pid_nr(owner) : -1,
+-              lock->owner_cpu);
++              READ_ONCE(lock->owner_cpu));
+       dump_stack();
+ }
+ 
+@@ -80,16 +80,16 @@ static void spin_bug(raw_spinlock_t *lock, const char *msg)
+ static inline void
+ debug_spin_lock_before(raw_spinlock_t *lock)
+ {
+-      SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic");
+-      SPIN_BUG_ON(lock->owner == current, lock, "recursion");
+-      SPIN_BUG_ON(lock->owner_cpu == raw_smp_processor_id(),
++      SPIN_BUG_ON(READ_ONCE(lock->magic) != SPINLOCK_MAGIC, lock, "bad 
magic");
++      SPIN_BUG_ON(READ_ONCE(lock->owner) == current, lock, "recursion");
++      SPIN_BUG_ON(READ_ONCE(lock->owner_cpu) == raw_smp_processor_id(),
+                                                       lock, "cpu recursion");
+ }
+ 
+ static inline void debug_spin_lock_after(raw_spinlock_t *lock)
+ {
+-      lock->owner_cpu = raw_smp_processor_id();
+-      lock->owner = current;
++      WRITE_ONCE(lock->owner_cpu, raw_smp_processor_id());
++      WRITE_ONCE(lock->owner, current);
+ }
+ 
+ static inline void debug_spin_unlock(raw_spinlock_t *lock)
+@@ -99,8 +99,8 @@ static inline void debug_spin_unlock(raw_spinlock_t *lock)
+       SPIN_BUG_ON(lock->owner != current, lock, "wrong owner");
+       SPIN_BUG_ON(lock->owner_cpu != raw_smp_processor_id(),
+                                                       lock, "wrong CPU");
+-      lock->owner = SPINLOCK_OWNER_INIT;
+-      lock->owner_cpu = -1;
++      WRITE_ONCE(lock->owner, SPINLOCK_OWNER_INIT);
++      WRITE_ONCE(lock->owner_cpu, -1);
+ }
+ 
+ /*
+@@ -183,8 +183,8 @@ static inline void debug_write_lock_before(rwlock_t *lock)
+ 
+ static inline void debug_write_lock_after(rwlock_t *lock)
+ {
+-      lock->owner_cpu = raw_smp_processor_id();
+-      lock->owner = current;
++      WRITE_ONCE(lock->owner_cpu, raw_smp_processor_id());
++      WRITE_ONCE(lock->owner, current);
+ }
+ 
+ static inline void debug_write_unlock(rwlock_t *lock)
+@@ -193,8 +193,8 @@ static inline void debug_write_unlock(rwlock_t *lock)
+       RWLOCK_BUG_ON(lock->owner != current, lock, "wrong owner");
+       RWLOCK_BUG_ON(lock->owner_cpu != raw_smp_processor_id(),
+                                                       lock, "wrong CPU");
+-      lock->owner = SPINLOCK_OWNER_INIT;
+-      lock->owner_cpu = -1;
++      WRITE_ONCE(lock->owner, SPINLOCK_OWNER_INIT);
++      WRITE_ONCE(lock->owner_cpu, -1);
+ }
+ 
+ void do_raw_write_lock(rwlock_t *lock)
+diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
+index 0e7afdf86127..235bed825e3a 100644
+--- a/net/8021q/vlan.h
++++ b/net/8021q/vlan.h
+@@ -110,6 +110,7 @@ int vlan_check_real_dev(struct net_device *real_dev,
+ void vlan_setup(struct net_device *dev);
+ int register_vlan_dev(struct net_device *dev);
+ void unregister_vlan_dev(struct net_device *dev, struct list_head *head);
++void vlan_dev_uninit(struct net_device *dev);
+ bool vlan_dev_inherit_address(struct net_device *dev,
+                             struct net_device *real_dev);
+ 
+diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
+index ac4c93c999b0..ed3717dc2d20 100644
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -610,7 +610,8 @@ static int vlan_dev_init(struct net_device *dev)
+       return 0;
+ }
+ 
+-static void vlan_dev_uninit(struct net_device *dev)
++/* Note: this function might be called multiple times for the same device. */
++void vlan_dev_uninit(struct net_device *dev)
+ {
+       struct vlan_priority_tci_mapping *pm;
+       struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
+diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
+index 5e831de3103e..fdf39dd5e755 100644
+--- a/net/8021q/vlan_netlink.c
++++ b/net/8021q/vlan_netlink.c
+@@ -95,11 +95,13 @@ static int vlan_changelink(struct net_device *dev, struct 
nlattr *tb[],
+       struct ifla_vlan_flags *flags;
+       struct ifla_vlan_qos_mapping *m;
+       struct nlattr *attr;
+-      int rem;
++      int rem, err;
+ 
+       if (data[IFLA_VLAN_FLAGS]) {
+               flags = nla_data(data[IFLA_VLAN_FLAGS]);
+-              vlan_dev_change_flags(dev, flags->flags, flags->mask);
++              err = vlan_dev_change_flags(dev, flags->flags, flags->mask);
++              if (err)
++                      return err;
+       }
+       if (data[IFLA_VLAN_INGRESS_QOS]) {
+               nla_for_each_nested(attr, data[IFLA_VLAN_INGRESS_QOS], rem) {
+@@ -110,7 +112,9 @@ static int vlan_changelink(struct net_device *dev, struct 
nlattr *tb[],
+       if (data[IFLA_VLAN_EGRESS_QOS]) {
+               nla_for_each_nested(attr, data[IFLA_VLAN_EGRESS_QOS], rem) {
+                       m = nla_data(attr);
+-                      vlan_dev_set_egress_priority(dev, m->from, m->to);
++                      err = vlan_dev_set_egress_priority(dev, m->from, m->to);
++                      if (err)
++                              return err;
+               }
+       }
+       return 0;
+@@ -157,10 +161,11 @@ static int vlan_newlink(struct net *src_net, struct 
net_device *dev,
+               return -EINVAL;
+ 
+       err = vlan_changelink(dev, tb, data, extack);
+-      if (err < 0)
+-              return err;
+-
+-      return register_vlan_dev(dev);
++      if (!err)
++              err = register_vlan_dev(dev);
++      if (err)
++              vlan_dev_uninit(dev);
++      return err;
+ }
+ 
+ static inline size_t vlan_qos_map_size(unsigned int n)
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index 55253ba0681f..d2b1c39c4223 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -1750,8 +1750,11 @@ tcp_sacktag_write_queue(struct sock *sk, const struct 
sk_buff *ack_skb,
+               }
+ 
+               /* Ignore very old stuff early */
+-              if (!after(sp[used_sacks].end_seq, prior_snd_una))
++              if (!after(sp[used_sacks].end_seq, prior_snd_una)) {
++                      if (i == 0)
++                              first_sack_index = -1;
+                       continue;
++              }
+ 
+               used_sacks++;
+       }
+diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c
+index 204a8351efff..c29170e767a8 100644
+--- a/net/llc/llc_station.c
++++ b/net/llc/llc_station.c
+@@ -32,7 +32,7 @@ static int llc_stat_ev_rx_null_dsap_xid_c(struct sk_buff 
*skb)
+       return LLC_PDU_IS_CMD(pdu) &&                   /* command PDU */
+              LLC_PDU_TYPE_IS_U(pdu) &&                /* U type PDU */
+              LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID &&
+-             !pdu->dsap ? 0 : 1;                      /* NULL DSAP value */
++             !pdu->dsap;                              /* NULL DSAP value */
+ }
+ 
+ static int llc_stat_ev_rx_null_dsap_test_c(struct sk_buff *skb)
+@@ -42,7 +42,7 @@ static int llc_stat_ev_rx_null_dsap_test_c(struct sk_buff 
*skb)
+       return LLC_PDU_IS_CMD(pdu) &&                   /* command PDU */
+              LLC_PDU_TYPE_IS_U(pdu) &&                /* U type PDU */
+              LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST &&
+-             !pdu->dsap ? 0 : 1;                      /* NULL DSAP */
++             !pdu->dsap;                              /* NULL DSAP */
+ }
+ 
+ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
+diff --git a/net/netfilter/nf_conntrack_netlink.c 
b/net/netfilter/nf_conntrack_netlink.c
+index c781c9a1a697..39a32edaa92c 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -3422,6 +3422,9 @@ static void __net_exit ctnetlink_net_exit_batch(struct 
list_head *net_exit_list)
+ 
+       list_for_each_entry(net, net_exit_list, exit_list)
+               ctnetlink_net_exit(net);
++
++      /* wait for other cpus until they are done with ctnl_notifiers */
++      synchronize_rcu();
+ }
+ 
+ static struct pernet_operations ctnetlink_net_ops = {
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 7ef126489d4e..91490446ebb4 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -3917,14 +3917,20 @@ static int nft_add_set_elem(struct nft_ctx *ctx, 
struct nft_set *set,
+               if (nla[NFTA_SET_ELEM_DATA] == NULL &&
+                   !(flags & NFT_SET_ELEM_INTERVAL_END))
+                       return -EINVAL;
+-              if (nla[NFTA_SET_ELEM_DATA] != NULL &&
+-                  flags & NFT_SET_ELEM_INTERVAL_END)
+-                      return -EINVAL;
+       } else {
+               if (nla[NFTA_SET_ELEM_DATA] != NULL)
+                       return -EINVAL;
+       }
+ 
++      if ((flags & NFT_SET_ELEM_INTERVAL_END) &&
++           (nla[NFTA_SET_ELEM_DATA] ||
++            nla[NFTA_SET_ELEM_OBJREF] ||
++            nla[NFTA_SET_ELEM_TIMEOUT] ||
++            nla[NFTA_SET_ELEM_EXPIRATION] ||
++            nla[NFTA_SET_ELEM_USERDATA] ||
++            nla[NFTA_SET_ELEM_EXPR]))
++              return -EINVAL;
++
+       timeout = 0;
+       if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
+               if (!(set->flags & NFT_SET_TIMEOUT))
+diff --git a/net/rfkill/core.c b/net/rfkill/core.c
+index 99a2e55b01cf..e31b4288f32c 100644
+--- a/net/rfkill/core.c
++++ b/net/rfkill/core.c
+@@ -998,10 +998,13 @@ static void rfkill_sync_work(struct work_struct *work)
+ int __must_check rfkill_register(struct rfkill *rfkill)
+ {
+       static unsigned long rfkill_no;
+-      struct device *dev = &rfkill->dev;
++      struct device *dev;
+       int error;
+ 
+-      BUG_ON(!rfkill);
++      if (!rfkill)
++              return -EINVAL;
++
++      dev = &rfkill->dev;
+ 
+       mutex_lock(&rfkill_global_mutex);
+ 
+diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
+index f50eb87cfe79..7a944f508cae 100644
+--- a/net/sched/sch_fq.c
++++ b/net/sched/sch_fq.c
+@@ -734,7 +734,7 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt)
+       if (tb[TCA_FQ_QUANTUM]) {
+               u32 quantum = nla_get_u32(tb[TCA_FQ_QUANTUM]);
+ 
+-              if (quantum > 0)
++              if (quantum > 0 && quantum <= (1 << 20))
+                       q->quantum = quantum;
+               else
+                       err = -EINVAL;
+diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
+index c60777351de1..ff6bc7cf6cbd 100644
+--- a/net/sched/sch_prio.c
++++ b/net/sched/sch_prio.c
+@@ -244,8 +244,14 @@ static int prio_graft(struct Qdisc *sch, unsigned long 
arg, struct Qdisc *new,
+       struct prio_sched_data *q = qdisc_priv(sch);
+       unsigned long band = arg - 1;
+ 
+-      if (new == NULL)
+-              new = &noop_qdisc;
++      if (!new) {
++              new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
++                                      TC_H_MAKE(sch->handle, arg));
++              if (!new)
++                      new = &noop_qdisc;
++              else
++                      qdisc_hash_add(new, true);
++      }
+ 
+       *old = qdisc_replace(sch, new, &q->queues[band]);
+       return 0;
+diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
+index bf0c61adb09c..482bb0a5d4d3 100644
+--- a/net/sctp/sm_sideeffect.c
++++ b/net/sctp/sm_sideeffect.c
+@@ -1359,8 +1359,10 @@ static int sctp_cmd_interpreter(enum sctp_event 
event_type,
+                       /* Generate an INIT ACK chunk.  */
+                       new_obj = sctp_make_init_ack(asoc, chunk, GFP_ATOMIC,
+                                                    0);
+-                      if (!new_obj)
+-                              goto nomem;
++                      if (!new_obj) {
++                              error = -ENOMEM;
++                              break;
++                      }
+ 
+                       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+                                       SCTP_CHUNK(new_obj));
+@@ -1382,7 +1384,8 @@ static int sctp_cmd_interpreter(enum sctp_event 
event_type,
+                       if (!new_obj) {
+                               if (cmd->obj.chunk)
+                                       sctp_chunk_free(cmd->obj.chunk);
+-                              goto nomem;
++                              error = -ENOMEM;
++                              break;
+                       }
+                       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+                                       SCTP_CHUNK(new_obj));
+@@ -1429,8 +1432,10 @@ static int sctp_cmd_interpreter(enum sctp_event 
event_type,
+ 
+                       /* Generate a SHUTDOWN chunk.  */
+                       new_obj = sctp_make_shutdown(asoc, chunk);
+-                      if (!new_obj)
+-                              goto nomem;
++                      if (!new_obj) {
++                              error = -ENOMEM;
++                              break;
++                      }
+                       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+                                       SCTP_CHUNK(new_obj));
+                       break;
+@@ -1760,11 +1765,17 @@ static int sctp_cmd_interpreter(enum sctp_event 
event_type,
+                       break;
+               }
+ 
+-              if (error)
++              if (error) {
++                      cmd = sctp_next_cmd(commands);
++                      while (cmd) {
++                              if (cmd->verb == SCTP_CMD_REPLY)
++                                      sctp_chunk_free(cmd->obj.chunk);
++                              cmd = sctp_next_cmd(commands);
++                      }
+                       break;
++              }
+       }
+ 
+-out:
+       /* If this is in response to a received chunk, wait until
+        * we are done with the packet to open the queue so that we don't
+        * send multiple packets in response to a single request.
+@@ -1779,8 +1790,5 @@ out:
+               sp->data_ready_signalled = 0;
+ 
+       return error;
+-nomem:
+-      error = -ENOMEM;
+-      goto out;
+ }
+ 
+diff --git a/samples/bpf/syscall_tp_kern.c b/samples/bpf/syscall_tp_kern.c
+index 9149c524d279..8833aacb9c8c 100644
+--- a/samples/bpf/syscall_tp_kern.c
++++ b/samples/bpf/syscall_tp_kern.c
+@@ -50,13 +50,27 @@ static __always_inline void count(void *map)
+ SEC("tracepoint/syscalls/sys_enter_open")
+ int trace_enter_open(struct syscalls_enter_open_args *ctx)
+ {
+-      count((void *)&enter_open_map);
++      count(&enter_open_map);
++      return 0;
++}
++
++SEC("tracepoint/syscalls/sys_enter_openat")
++int trace_enter_open_at(struct syscalls_enter_open_args *ctx)
++{
++      count(&enter_open_map);
+       return 0;
+ }
+ 
+ SEC("tracepoint/syscalls/sys_exit_open")
+ int trace_enter_exit(struct syscalls_exit_open_args *ctx)
+ {
+-      count((void *)&exit_open_map);
++      count(&exit_open_map);
++      return 0;
++}
++
++SEC("tracepoint/syscalls/sys_exit_openat")
++int trace_enter_exit_at(struct syscalls_exit_open_args *ctx)
++{
++      count(&exit_open_map);
+       return 0;
+ }
+diff --git a/samples/bpf/trace_event_user.c b/samples/bpf/trace_event_user.c
+index c7d525e5696e..8c7445874662 100644
+--- a/samples/bpf/trace_event_user.c
++++ b/samples/bpf/trace_event_user.c
+@@ -34,9 +34,9 @@ static void print_ksym(__u64 addr)
+               return;
+       sym = ksym_search(addr);
+       printf("%s;", sym->name);
+-      if (!strcmp(sym->name, "sys_read"))
++      if (!strstr(sym->name, "sys_read"))
+               sys_read_seen = true;
+-      else if (!strcmp(sym->name, "sys_write"))
++      else if (!strstr(sym->name, "sys_write"))
+               sys_write_seen = true;
+ }
+ 
+diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
+index ed29bad1f03a..96420b620963 100644
+--- a/scripts/kconfig/expr.c
++++ b/scripts/kconfig/expr.c
+@@ -201,6 +201,13 @@ static int expr_eq(struct expr *e1, struct expr *e2)
+ {
+       int res, old_count;
+ 
++      /*
++       * A NULL expr is taken to be yes, but there's also a different way to
++       * represent yes. expr_is_yes() checks for either representation.
++       */
++      if (!e1 || !e2)
++              return expr_is_yes(e1) && expr_is_yes(e2);
++
+       if (e1->type != e2->type)
+               return 0;
+       switch (e1->type) {
+diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
+index fd2731d171dd..0e8008d38161 100644
+--- a/sound/soc/codecs/wm8962.c
++++ b/sound/soc/codecs/wm8962.c
+@@ -2791,7 +2791,7 @@ static int fll_factors(struct _fll_div *fll_div, 
unsigned int Fref,
+ 
+       if (target % Fref == 0) {
+               fll_div->theta = 0;
+-              fll_div->lambda = 0;
++              fll_div->lambda = 1;
+       } else {
+               gcd_fll = gcd(target, fratio * Fref);
+ 
+@@ -2861,7 +2861,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, 
int fll_id, int source,
+               return -EINVAL;
+       }
+ 
+-      if (fll_div.theta || fll_div.lambda)
++      if (fll_div.theta)
+               fll1 |= WM8962_FLL_FRAC;
+ 
+       /* Stop the FLL while we reconfigure */
+diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
+index 2d5cf263515b..72301bcad3bd 100644
+--- a/sound/soc/soc-topology.c
++++ b/sound/soc/soc-topology.c
+@@ -1921,6 +1921,7 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
+       int count = hdr->count;
+       int i;
+       bool abi_match;
++      int ret;
+ 
+       if (tplg->pass != SOC_TPLG_PASS_PCM_DAI)
+               return 0;
+@@ -1957,7 +1958,12 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg 
*tplg,
+               }
+ 
+               /* create the FE DAIs and DAI links */
+-              soc_tplg_pcm_create(tplg, _pcm);
++              ret = soc_tplg_pcm_create(tplg, _pcm);
++              if (ret < 0) {
++                      if (!abi_match)
++                              kfree(_pcm);
++                      return ret;
++              }
+ 
+               /* offset by version-specific struct size and
+                * real priv data size
+diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
+index 8107f060fa84..a0ac01c647f5 100644
+--- a/tools/lib/traceevent/Makefile
++++ b/tools/lib/traceevent/Makefile
+@@ -115,6 +115,7 @@ EVENT_PARSE_VERSION = 
$(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION)
+ 
+ LIB_TARGET  = libtraceevent.a libtraceevent.so.$(EVENT_PARSE_VERSION)
+ LIB_INSTALL = libtraceevent.a libtraceevent.so*
++LIB_INSTALL := $(addprefix $(OUTPUT),$(LIB_INSTALL))
+ 
+ INCLUDES = -I. -I $(srctree)/tools/include $(CONFIG_INCLUDES)
+ 
+diff --git a/tools/testing/selftests/bpf/test_verifier.c 
b/tools/testing/selftests/bpf/test_verifier.c
+index 913539aea645..9babb3fef8e2 100644
+--- a/tools/testing/selftests/bpf/test_verifier.c
++++ b/tools/testing/selftests/bpf/test_verifier.c
+@@ -7281,7 +7281,7 @@ static struct bpf_test tests[] = {
+                                   offsetof(struct __sk_buff, mark)),
+                       BPF_EXIT_INSN(),
+               },
+-              .errstr = "dereference of modified ctx ptr R1 off=68+8, 
ctx+const is allowed, ctx+const+const is not",
++              .errstr = "dereference of modified ctx ptr",
+               .result = REJECT,
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+       },
+@@ -7944,6 +7944,62 @@ static struct bpf_test tests[] = {
+               .errstr = "BPF_XADD stores into R2 packet",
+               .prog_type = BPF_PROG_TYPE_XDP,
+       },
++      {
++              "pass unmodified ctx pointer to helper",
++              .insns = {
++                      BPF_MOV64_IMM(BPF_REG_2, 0),
++                      BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
++                                   BPF_FUNC_csum_update),
++                      BPF_MOV64_IMM(BPF_REG_0, 0),
++                      BPF_EXIT_INSN(),
++              },
++              .prog_type = BPF_PROG_TYPE_SCHED_CLS,
++              .result = ACCEPT,
++      },
++      {
++              "pass modified ctx pointer to helper, 1",
++              .insns = {
++                      BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
++                      BPF_MOV64_IMM(BPF_REG_2, 0),
++                      BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
++                                   BPF_FUNC_csum_update),
++                      BPF_MOV64_IMM(BPF_REG_0, 0),
++                      BPF_EXIT_INSN(),
++              },
++              .prog_type = BPF_PROG_TYPE_SCHED_CLS,
++              .result = REJECT,
++              .errstr = "dereference of modified ctx ptr",
++      },
++      {
++              "pass modified ctx pointer to helper, 2",
++              .insns = {
++                      BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
++                      BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
++                                   BPF_FUNC_get_socket_cookie),
++                      BPF_MOV64_IMM(BPF_REG_0, 0),
++                      BPF_EXIT_INSN(),
++              },
++              .result_unpriv = REJECT,
++              .result = REJECT,
++              .errstr_unpriv = "dereference of modified ctx ptr",
++              .errstr = "dereference of modified ctx ptr",
++      },
++      {
++              "pass modified ctx pointer to helper, 3",
++              .insns = {
++                      BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 0),
++                      BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 4),
++                      BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
++                      BPF_MOV64_IMM(BPF_REG_2, 0),
++                      BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
++                                   BPF_FUNC_csum_update),
++                      BPF_MOV64_IMM(BPF_REG_0, 0),
++                      BPF_EXIT_INSN(),
++              },
++              .prog_type = BPF_PROG_TYPE_SCHED_CLS,
++              .result = REJECT,
++              .errstr = "variable ctx access var_off=(0x0; 0x4)",
++      },
+ };
+ 
+ static int probe_filter_length(const struct bpf_insn *fp)

Reply via email to