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, +- ¤t_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, +- ¤t_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, ®_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, ®s[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)