From c63b2129f64a741d71b30bc7bf3bb6ede98de6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Pe=C4=8Dovnik?= Date: Sun, 1 Jul 2018 13:55:11 +0000 Subject: [PATCH] Lock RK3328 to last known working tag. Thanks for idea/tip to @markh-de --- config/kernel/linux-rk3328-default.config | 16 +- config/sources/rk3328.conf | 2 +- .../rk3328-default/04-patch-4.4.126-127.patch | 2215 +++++++ .../rk3328-default/04-patch-4.4.127-128.patch | 5370 +++++++++++++++++ .../rk3328-default/04-patch-4.4.128-129.patch | 3475 +++++++++++ .../rk3328-default/04-patch-4.4.129-130.patch | 2698 +++++++++ .../rk3328-default/04-patch-4.4.130-131.patch | 1558 +++++ .../rk3328-default/04-patch-4.4.131-132.patch | 2948 +++++++++ .../rk3328-default/04-patch-4.4.133-134.patch | 28 - .../rk3328-default/04-patch-4.4.137-138.patch | 1561 +++++ .../rock64-DT-add-ethernet-aliases.patch | 2 +- .../wifi-0001-realtek-881xAU-605ecfa.patch | 172 +- 12 files changed, 19915 insertions(+), 130 deletions(-) create mode 100644 patch/kernel/rk3328-default/04-patch-4.4.126-127.patch create mode 100644 patch/kernel/rk3328-default/04-patch-4.4.127-128.patch create mode 100644 patch/kernel/rk3328-default/04-patch-4.4.128-129.patch create mode 100644 patch/kernel/rk3328-default/04-patch-4.4.129-130.patch create mode 100644 patch/kernel/rk3328-default/04-patch-4.4.130-131.patch create mode 100644 patch/kernel/rk3328-default/04-patch-4.4.131-132.patch create mode 100644 patch/kernel/rk3328-default/04-patch-4.4.137-138.patch diff --git a/config/kernel/linux-rk3328-default.config b/config/kernel/linux-rk3328-default.config index bef6232d5..b5c24bac3 100644 --- a/config/kernel/linux-rk3328-default.config +++ b/config/kernel/linux-rk3328-default.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 4.4.137 Kernel Configuration +# Linux/arm64 4.4.138 Kernel Configuration # CONFIG_ARM64=y CONFIG_64BIT=y @@ -12,8 +12,8 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 CONFIG_ARM64_PAGE_SHIFT=12 CONFIG_ARM64_CONT_SHIFT=4 -CONFIG_STACKTRACE_SUPPORT=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y @@ -568,7 +568,6 @@ CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_COMMON=y CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_TIMES=y # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set @@ -1996,7 +1995,6 @@ CONFIG_WL_ROCKCHIP=y # CONFIG_WIFI_BUILD_MODULE is not set # CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP is not set CONFIG_AP6XXX=m -CONFIG_CYW_BCMDHD=m # CONFIG_RTL_WIRELESS_SOLUTION is not set CONFIG_RTL8188FU=m # CONFIG_RTL8189ES is not set @@ -3896,7 +3894,6 @@ CONFIG_SND_SOC_ROCKCHIP=y # CONFIG_SND_SOC_ROCKCHIP_FORCE_SRAM is not set CONFIG_SND_SOC_ROCKCHIP_I2S=y CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=m -CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS=m # CONFIG_SND_SOC_ROCKCHIP_PDM is not set CONFIG_SND_SOC_ROCKCHIP_SPDIF=y # CONFIG_SND_SOC_ROCKCHIP_VAD is not set @@ -4535,7 +4532,6 @@ CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_DS3232 is not set -CONFIG_RTC_DRV_FAKE=m CONFIG_RTC_DRV_HYM8563=y # CONFIG_RTC_DRV_MAX6900 is not set CONFIG_RTC_DRV_RK808=y @@ -4759,7 +4755,6 @@ CONFIG_ASHMEM=y # CONFIG_ANDROID_TIMED_OUTPUT is not set # CONFIG_ANDROID_LOW_MEMORY_KILLER is not set # CONFIG_SYNC is not set -# CONFIG_ANDROID_VSOC is not set # CONFIG_ION is not set CONFIG_FIQ_DEBUGGER=y CONFIG_FIQ_DEBUGGER_NO_SLEEP=y @@ -5065,7 +5060,6 @@ CONFIG_SENSORS_TSL2563=y # CONFIG_TSL4531 is not set # CONFIG_US5182D is not set # CONFIG_VCNL4000 is not set -CONFIG_VL6180=m # # Magnetometer sensors @@ -5127,10 +5121,8 @@ CONFIG_PWM=y CONFIG_PWM_SYSFS=y # CONFIG_PWM_CROS_EC is not set # CONFIG_PWM_FSL_FTM is not set -# CONFIG_PWM_GPIO is not set # CONFIG_PWM_PCA9685 is not set CONFIG_PWM_ROCKCHIP=y -# CONFIG_PWM_ROCKCHIP_I2S is not set CONFIG_IRQCHIP=y CONFIG_ARM_GIC=y CONFIG_ARM_GIC_V2M=y @@ -5187,7 +5179,6 @@ CONFIG_ROCKCHIP_EFUSE=y # # CONFIG_FPGA is not set # CONFIG_TEE is not set -# CONFIG_RK_FLASH is not set # CONFIG_RK_NAND is not set # @@ -5303,7 +5294,6 @@ CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_PROC_CHILDREN=y -CONFIG_PROC_UID=y CONFIG_KERNFS=y CONFIG_SYSFS=y CONFIG_TMPFS=y @@ -5857,7 +5847,6 @@ CONFIG_CRYPTO_USER_API_RNG=y CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_CCP is not set -CONFIG_CRYPTO_DEV_ROCKCHIP=m CONFIG_ASYMMETRIC_KEY_TYPE=y CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y CONFIG_PUBLIC_KEY_ALGO_RSA=y @@ -5880,7 +5869,6 @@ CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y # CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set # CONFIG_CRYPTO_CRC32_ARM64 is not set -CONFIG_CRYPTO_SPECK_NEON=m CONFIG_BINARY_PRINTF=y # diff --git a/config/sources/rk3328.conf b/config/sources/rk3328.conf index bceaa5abf..00f346065 100644 --- a/config/sources/rk3328.conf +++ b/config/sources/rk3328.conf @@ -26,7 +26,7 @@ case $BRANCH in BOOTBRANCH='branch:rockchip-master' KERNELSOURCE='https://github.com/ayufan-rock64/linux-kernel' - KERNELBRANCH='branch:release-4.4' + KERNELBRANCH='tag:ayufan-rock64/linux-build/0.6.45' KERNELDIR='linux-rk3328' KERNEL_USE_GCC='< 6.3' diff --git a/patch/kernel/rk3328-default/04-patch-4.4.126-127.patch b/patch/kernel/rk3328-default/04-patch-4.4.126-127.patch new file mode 100644 index 000000000..58eadbf3b --- /dev/null +++ b/patch/kernel/rk3328-default/04-patch-4.4.126-127.patch @@ -0,0 +1,2215 @@ +diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt +index caf297bee1fb..c28d4eb83b76 100644 +--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt ++++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-palmas.txt +@@ -35,6 +35,15 @@ Optional properties: + - ti,palmas-enable-dvfs2: Enable DVFS2. Configure pins for DVFS2 mode. + Selection primary or secondary function associated to GPADC_START + and SYSEN2 pin/pad for DVFS2 interface ++- ti,palmas-override-powerhold: This is applicable for PMICs for which ++ GPIO7 is configured in POWERHOLD mode which has higher priority ++ over DEV_ON bit and keeps the PMIC supplies on even after the DEV_ON ++ bit is turned off. This property enables driver to over ride the ++ POWERHOLD value to GPIO7 so as to turn off the PMIC in power off ++ scenarios. So for GPIO7 if ti,palmas-override-powerhold is set ++ then the GPIO_7 field should never be muxed to anything else. ++ It should be set to POWERHOLD by default and only in case of ++ power off scenarios the driver will over ride the mux value. + + This binding uses the following generic properties as defined in + pinctrl-bindings.txt: +diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt +index 6716413c17ba..6d2689ebf824 100644 +--- a/Documentation/filesystems/proc.txt ++++ b/Documentation/filesystems/proc.txt +@@ -383,32 +383,6 @@ is not associated with a file: + + or if empty, the mapping is anonymous. + +-The /proc/PID/task/TID/maps is a view of the virtual memory from the viewpoint +-of the individual tasks of a process. In this file you will see a mapping marked +-as [stack] if that task sees it as a stack. Hence, for the example above, the +-task-level map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this: +- +-08048000-08049000 r-xp 00000000 03:00 8312 /opt/test +-08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test +-0804a000-0806b000 rw-p 00000000 00:00 0 [heap] +-a7cb1000-a7cb2000 ---p 00000000 00:00 0 +-a7cb2000-a7eb2000 rw-p 00000000 00:00 0 +-a7eb2000-a7eb3000 ---p 00000000 00:00 0 +-a7eb3000-a7ed5000 rw-p 00000000 00:00 0 [stack] +-a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6 +-a8008000-a800a000 r--p 00133000 03:00 4222 /lib/libc.so.6 +-a800a000-a800b000 rw-p 00135000 03:00 4222 /lib/libc.so.6 +-a800b000-a800e000 rw-p 00000000 00:00 0 +-a800e000-a8022000 r-xp 00000000 03:00 14462 /lib/libpthread.so.0 +-a8022000-a8023000 r--p 00013000 03:00 14462 /lib/libpthread.so.0 +-a8023000-a8024000 rw-p 00014000 03:00 14462 /lib/libpthread.so.0 +-a8024000-a8027000 rw-p 00000000 00:00 0 +-a8027000-a8043000 r-xp 00000000 03:00 8317 /lib/ld-linux.so.2 +-a8043000-a8044000 r--p 0001b000 03:00 8317 /lib/ld-linux.so.2 +-a8044000-a8045000 rw-p 0001c000 03:00 8317 /lib/ld-linux.so.2 +-aff35000-aff4a000 rw-p 00000000 00:00 0 +-ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso] +- + The /proc/PID/smaps is an extension based on maps, showing the memory + consumption for each of the process's mappings. For each of mappings there + is a series of lines such as the following: +diff --git a/Makefile b/Makefile +index 2b699c5f6de4..58c0390573c1 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 126 ++SUBLEVEL = 127 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arm/boot/dts/am335x-pepper.dts b/arch/arm/boot/dts/am335x-pepper.dts +index 2dbe13a3d89b..7106114c7464 100644 +--- a/arch/arm/boot/dts/am335x-pepper.dts ++++ b/arch/arm/boot/dts/am335x-pepper.dts +@@ -139,7 +139,7 @@ + &audio_codec { + status = "okay"; + +- reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; ++ gpio-reset = <&gpio1 16 GPIO_ACTIVE_LOW>; + AVDD-supply = <&ldo3_reg>; + IOVDD-supply = <&ldo3_reg>; + DRVDD-supply = <&ldo3_reg>; +diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts +index 00352e761b8c..5c3bd34af9fd 100644 +--- a/arch/arm/boot/dts/am57xx-beagle-x15.dts ++++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts +@@ -411,6 +411,7 @@ + interrupt-controller; + + ti,system-power-controller; ++ ti,palmas-override-powerhold; + + tps659038_pmic { + compatible = "ti,tps659038-pmic"; +diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts +index 864f60020124..0736d04f032e 100644 +--- a/arch/arm/boot/dts/dra7-evm.dts ++++ b/arch/arm/boot/dts/dra7-evm.dts +@@ -410,6 +410,8 @@ + tps659038: tps659038@58 { + compatible = "ti,tps659038"; + reg = <0x58>; ++ ti,palmas-override-powerhold; ++ ti,system-power-controller; + + tps659038_pmic { + compatible = "ti,tps659038-pmic"; +diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts +index 731860314ab5..27cd4abfc74d 100644 +--- a/arch/arm/boot/dts/omap3-n900.dts ++++ b/arch/arm/boot/dts/omap3-n900.dts +@@ -488,7 +488,7 @@ + tlv320aic3x: tlv320aic3x@18 { + compatible = "ti,tlv320aic3x"; + reg = <0x18>; +- reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; /* 60 */ ++ gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */ + ai3x-gpio-func = < + 0 /* AIC3X_GPIO1_FUNC_DISABLED */ + 5 /* AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT */ +@@ -505,7 +505,7 @@ + tlv320aic3x_aux: tlv320aic3x@19 { + compatible = "ti,tlv320aic3x"; + reg = <0x19>; +- reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; /* 60 */ ++ gpio-reset = <&gpio2 28 GPIO_ACTIVE_HIGH>; /* 60 */ + + AVDD-supply = <&vmmc2>; + DRVDD-supply = <&vmmc2>; +diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h +index 853953cd1f08..b42b930cc19a 100644 +--- a/arch/arm64/include/asm/memory.h ++++ b/arch/arm64/include/asm/memory.h +@@ -48,8 +48,10 @@ + * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area. + */ + #define VA_BITS (CONFIG_ARM64_VA_BITS) +-#define VA_START (UL(0xffffffffffffffff) << VA_BITS) +-#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1)) ++#define VA_START (UL(0xffffffffffffffff) - \ ++ (UL(1) << VA_BITS) + 1) ++#define PAGE_OFFSET (UL(0xffffffffffffffff) - \ ++ (UL(1) << (VA_BITS - 1)) + 1) + #define KIMAGE_VADDR (MODULES_END) + #define MODULES_END (MODULES_VADDR + MODULES_VSIZE) + #define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE) +diff --git a/arch/frv/include/asm/timex.h b/arch/frv/include/asm/timex.h +index a89bddefdacf..139093fab326 100644 +--- a/arch/frv/include/asm/timex.h ++++ b/arch/frv/include/asm/timex.h +@@ -16,5 +16,11 @@ static inline cycles_t get_cycles(void) + #define vxtime_lock() do {} while (0) + #define vxtime_unlock() do {} while (0) + ++/* This attribute is used in include/linux/jiffies.h alongside with ++ * __cacheline_aligned_in_smp. It is assumed that __cacheline_aligned_in_smp ++ * for frv does not contain another section specification. ++ */ ++#define __jiffy_arch_data __attribute__((__section__(".data"))) ++ + #endif + +diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c +index 8648158f3916..f8fe11d24cde 100644 +--- a/arch/x86/crypto/cast5_avx_glue.c ++++ b/arch/x86/crypto/cast5_avx_glue.c +@@ -66,8 +66,6 @@ static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, + void (*fn)(struct cast5_ctx *ctx, u8 *dst, const u8 *src); + int err; + +- fn = (enc) ? cast5_ecb_enc_16way : cast5_ecb_dec_16way; +- + err = blkcipher_walk_virt(desc, walk); + desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + +@@ -79,6 +77,7 @@ static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, + + /* Process multi-block batch */ + if (nbytes >= bsize * CAST5_PARALLEL_BLOCKS) { ++ fn = (enc) ? cast5_ecb_enc_16way : cast5_ecb_dec_16way; + do { + fn(ctx, wdst, wsrc); + +diff --git a/block/partitions/msdos.c b/block/partitions/msdos.c +index 5610cd537da7..7d8d50c11ce7 100644 +--- a/block/partitions/msdos.c ++++ b/block/partitions/msdos.c +@@ -300,7 +300,9 @@ static void parse_bsd(struct parsed_partitions *state, + continue; + bsd_start = le32_to_cpu(p->p_offset); + bsd_size = le32_to_cpu(p->p_size); +- if (memcmp(flavour, "bsd\0", 4) == 0) ++ /* FreeBSD has relative offset if C partition offset is zero */ ++ if (memcmp(flavour, "bsd\0", 4) == 0 && ++ le32_to_cpu(l->d_partitions[2].p_offset) == 0) + bsd_start += offset; + if (offset == bsd_start && size == bsd_size) + /* full parent partition, we have it already */ +diff --git a/crypto/ahash.c b/crypto/ahash.c +index 7006dbfd39bd..6978ad86e516 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -91,13 +91,14 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err) + + if (nbytes && walk->offset & alignmask && !err) { + walk->offset = ALIGN(walk->offset, alignmask + 1); +- walk->data += walk->offset; +- + nbytes = min(nbytes, + ((unsigned int)(PAGE_SIZE)) - walk->offset); + walk->entrylen -= nbytes; + +- return nbytes; ++ if (nbytes) { ++ walk->data += walk->offset; ++ return nbytes; ++ } + } + + if (walk->flags & CRYPTO_ALG_ASYNC) +diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c +index 8a10a7ae6a8a..c8e169e46673 100644 +--- a/drivers/acpi/pci_irq.c ++++ b/drivers/acpi/pci_irq.c +@@ -131,9 +131,6 @@ static void do_prt_fixups(struct acpi_prt_entry *entry, + quirk = &prt_quirks[i]; + + /* All current quirks involve link devices, not GSIs */ +- if (!prt->source) +- continue; +- + if (dmi_check_system(quirk->system) && + entry->id.segment == quirk->segment && + entry->id.bus == quirk->bus && +diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c +index 9ba89315dae1..55d3d1da72de 100644 +--- a/drivers/block/mtip32xx/mtip32xx.c ++++ b/drivers/block/mtip32xx/mtip32xx.c +@@ -169,25 +169,6 @@ static bool mtip_check_surprise_removal(struct pci_dev *pdev) + return false; /* device present */ + } + +-/* we have to use runtime tag to setup command header */ +-static void mtip_init_cmd_header(struct request *rq) +-{ +- struct driver_data *dd = rq->q->queuedata; +- struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); +- u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; +- +- /* Point the command headers at the command tables. */ +- cmd->command_header = dd->port->command_list + +- (sizeof(struct mtip_cmd_hdr) * rq->tag); +- cmd->command_header_dma = dd->port->command_list_dma + +- (sizeof(struct mtip_cmd_hdr) * rq->tag); +- +- if (host_cap_64) +- cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16); +- +- cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF); +-} +- + static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd) + { + struct request *rq; +@@ -199,9 +180,6 @@ static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd) + if (IS_ERR(rq)) + return NULL; + +- /* Internal cmd isn't submitted via .queue_rq */ +- mtip_init_cmd_header(rq); +- + return blk_mq_rq_to_pdu(rq); + } + +@@ -3840,8 +3818,6 @@ static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx, + struct request *rq = bd->rq; + int ret; + +- mtip_init_cmd_header(rq); +- + if (unlikely(mtip_check_unal_depth(hctx, rq))) + return BLK_MQ_RQ_QUEUE_BUSY; + +@@ -3873,6 +3849,7 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx, + { + struct driver_data *dd = data; + struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); ++ u32 host_cap_64 = readl(dd->mmio + HOST_CAP) & HOST_CAP_64; + + /* + * For flush requests, request_idx starts at the end of the +@@ -3889,6 +3866,17 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx, + + memset(cmd->command, 0, CMD_DMA_ALLOC_SZ); + ++ /* Point the command headers at the command tables. */ ++ cmd->command_header = dd->port->command_list + ++ (sizeof(struct mtip_cmd_hdr) * request_idx); ++ cmd->command_header_dma = dd->port->command_list_dma + ++ (sizeof(struct mtip_cmd_hdr) * request_idx); ++ ++ if (host_cap_64) ++ cmd->command_header->ctbau = __force_bit2int cpu_to_le32((cmd->command_dma >> 16) >> 16); ++ ++ cmd->command_header->ctba = __force_bit2int cpu_to_le32(cmd->command_dma & 0xFFFFFFFF); ++ + sg_init_table(cmd->sg, MTIP_MAX_SG); + return 0; + } +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index c0fb6f12f547..ebed319657e7 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -551,8 +551,6 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, + *governor = t; + err = 0; + } +- if (t && !try_module_get(t->owner)) +- t = NULL; + + mutex_unlock(&cpufreq_governor_mutex); + } +@@ -671,10 +669,6 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy, + return -EINVAL; + + ret = cpufreq_set_policy(policy, &new_policy); +- +- if (new_policy.governor) +- module_put(new_policy.governor->owner); +- + return ret ? ret : count; + } + +diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c +index 6a8024d9d742..864a7c8d82d3 100644 +--- a/drivers/infiniband/core/addr.c ++++ b/drivers/infiniband/core/addr.c +@@ -86,6 +86,22 @@ int rdma_addr_size(struct sockaddr *addr) + } + EXPORT_SYMBOL(rdma_addr_size); + ++int rdma_addr_size_in6(struct sockaddr_in6 *addr) ++{ ++ int ret = rdma_addr_size((struct sockaddr *) addr); ++ ++ return ret <= sizeof(*addr) ? ret : 0; ++} ++EXPORT_SYMBOL(rdma_addr_size_in6); ++ ++int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr) ++{ ++ int ret = rdma_addr_size((struct sockaddr *) addr); ++ ++ return ret <= sizeof(*addr) ? ret : 0; ++} ++EXPORT_SYMBOL(rdma_addr_size_kss); ++ + static struct rdma_addr_client self; + + void rdma_addr_register_client(struct rdma_addr_client *client) +diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c +index cdac2c9421ab..960fcb613198 100644 +--- a/drivers/infiniband/core/ucma.c ++++ b/drivers/infiniband/core/ucma.c +@@ -131,7 +131,7 @@ static inline struct ucma_context *_ucma_find_context(int id, + ctx = idr_find(&ctx_idr, id); + if (!ctx) + ctx = ERR_PTR(-ENOENT); +- else if (ctx->file != file) ++ else if (ctx->file != file || !ctx->cm_id) + ctx = ERR_PTR(-EINVAL); + return ctx; + } +@@ -453,6 +453,7 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, + struct rdma_ucm_create_id cmd; + struct rdma_ucm_create_id_resp resp; + struct ucma_context *ctx; ++ struct rdma_cm_id *cm_id; + enum ib_qp_type qp_type; + int ret; + +@@ -473,10 +474,10 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, + return -ENOMEM; + + ctx->uid = cmd.uid; +- ctx->cm_id = rdma_create_id(current->nsproxy->net_ns, +- ucma_event_handler, ctx, cmd.ps, qp_type); +- if (IS_ERR(ctx->cm_id)) { +- ret = PTR_ERR(ctx->cm_id); ++ cm_id = rdma_create_id(current->nsproxy->net_ns, ++ ucma_event_handler, ctx, cmd.ps, qp_type); ++ if (IS_ERR(cm_id)) { ++ ret = PTR_ERR(cm_id); + goto err1; + } + +@@ -486,14 +487,19 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf, + ret = -EFAULT; + goto err2; + } ++ ++ ctx->cm_id = cm_id; + return 0; + + err2: +- rdma_destroy_id(ctx->cm_id); ++ rdma_destroy_id(cm_id); + err1: + mutex_lock(&mut); + idr_remove(&ctx_idr, ctx->id); + mutex_unlock(&mut); ++ mutex_lock(&file->mut); ++ list_del(&ctx->list); ++ mutex_unlock(&file->mut); + kfree(ctx); + return ret; + } +@@ -623,6 +629,9 @@ static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf, + if (copy_from_user(&cmd, inbuf, sizeof(cmd))) + return -EFAULT; + ++ if (!rdma_addr_size_in6(&cmd.addr)) ++ return -EINVAL; ++ + ctx = ucma_get_ctx(file, cmd.id); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); +@@ -636,22 +645,21 @@ static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf, + int in_len, int out_len) + { + struct rdma_ucm_bind cmd; +- struct sockaddr *addr; + struct ucma_context *ctx; + int ret; + + if (copy_from_user(&cmd, inbuf, sizeof(cmd))) + return -EFAULT; + +- addr = (struct sockaddr *) &cmd.addr; +- if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr))) ++ if (cmd.reserved || !cmd.addr_size || ++ cmd.addr_size != rdma_addr_size_kss(&cmd.addr)) + return -EINVAL; + + ctx = ucma_get_ctx(file, cmd.id); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + +- ret = rdma_bind_addr(ctx->cm_id, addr); ++ ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr); + ucma_put_ctx(ctx); + return ret; + } +@@ -667,13 +675,16 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file, + if (copy_from_user(&cmd, inbuf, sizeof(cmd))) + return -EFAULT; + ++ if (!rdma_addr_size_in6(&cmd.src_addr) || ++ !rdma_addr_size_in6(&cmd.dst_addr)) ++ return -EINVAL; ++ + ctx = ucma_get_ctx(file, cmd.id); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, +- (struct sockaddr *) &cmd.dst_addr, +- cmd.timeout_ms); ++ (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms); + ucma_put_ctx(ctx); + return ret; + } +@@ -683,24 +694,23 @@ static ssize_t ucma_resolve_addr(struct ucma_file *file, + int in_len, int out_len) + { + struct rdma_ucm_resolve_addr cmd; +- struct sockaddr *src, *dst; + struct ucma_context *ctx; + int ret; + + if (copy_from_user(&cmd, inbuf, sizeof(cmd))) + return -EFAULT; + +- src = (struct sockaddr *) &cmd.src_addr; +- dst = (struct sockaddr *) &cmd.dst_addr; +- if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) || +- !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst))) ++ if (cmd.reserved || ++ (cmd.src_size && (cmd.src_size != rdma_addr_size_kss(&cmd.src_addr))) || ++ !cmd.dst_size || (cmd.dst_size != rdma_addr_size_kss(&cmd.dst_addr))) + return -EINVAL; + + ctx = ucma_get_ctx(file, cmd.id); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + +- ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms); ++ ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, ++ (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms); + ucma_put_ctx(ctx); + return ret; + } +@@ -1145,6 +1155,11 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file, + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + ++ if (!ctx->cm_id->device) { ++ ret = -EINVAL; ++ goto out; ++ } ++ + resp.qp_attr_mask = 0; + memset(&qp_attr, 0, sizeof qp_attr); + qp_attr.qp_state = cmd.qp_state; +@@ -1301,7 +1316,7 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, + { + struct rdma_ucm_notify cmd; + struct ucma_context *ctx; +- int ret; ++ int ret = -EINVAL; + + if (copy_from_user(&cmd, inbuf, sizeof(cmd))) + return -EFAULT; +@@ -1310,7 +1325,9 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + +- ret = rdma_notify(ctx->cm_id, (enum ib_event_type) cmd.event); ++ if (ctx->cm_id->device) ++ ret = rdma_notify(ctx->cm_id, (enum ib_event_type)cmd.event); ++ + ucma_put_ctx(ctx); + return ret; + } +@@ -1328,7 +1345,7 @@ static ssize_t ucma_process_join(struct ucma_file *file, + return -ENOSPC; + + addr = (struct sockaddr *) &cmd->addr; +- if (cmd->reserved || !cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr))) ++ if (cmd->reserved || (cmd->addr_size != rdma_addr_size(addr))) + return -EINVAL; + + ctx = ucma_get_ctx(file, cmd->id); +@@ -1387,7 +1404,10 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file, + join_cmd.response = cmd.response; + join_cmd.uid = cmd.uid; + join_cmd.id = cmd.id; +- join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr); ++ join_cmd.addr_size = rdma_addr_size_in6(&cmd.addr); ++ if (!join_cmd.addr_size) ++ return -EINVAL; ++ + join_cmd.reserved = 0; + memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size); + +@@ -1403,6 +1423,9 @@ static ssize_t ucma_join_multicast(struct ucma_file *file, + if (copy_from_user(&cmd, inbuf, sizeof(cmd))) + return -EFAULT; + ++ if (!rdma_addr_size_kss(&cmd.addr)) ++ return -EINVAL; ++ + return ucma_process_join(file, &cmd, out_len); + } + +diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c +index b604564dec5c..30328e57fdda 100644 +--- a/drivers/input/mousedev.c ++++ b/drivers/input/mousedev.c +@@ -15,6 +15,7 @@ + #define MOUSEDEV_MINORS 31 + #define MOUSEDEV_MIX 63 + ++#include + #include + #include + #include +@@ -103,7 +104,7 @@ struct mousedev_client { + spinlock_t packet_lock; + int pos_x, pos_y; + +- signed char ps2[6]; ++ u8 ps2[6]; + unsigned char ready, buffer, bufsiz; + unsigned char imexseq, impsseq; + enum mousedev_emul mode; +@@ -291,11 +292,10 @@ static void mousedev_notify_readers(struct mousedev *mousedev, + } + + client->pos_x += packet->dx; +- client->pos_x = client->pos_x < 0 ? +- 0 : (client->pos_x >= xres ? xres : client->pos_x); ++ client->pos_x = clamp_val(client->pos_x, 0, xres); ++ + client->pos_y += packet->dy; +- client->pos_y = client->pos_y < 0 ? +- 0 : (client->pos_y >= yres ? yres : client->pos_y); ++ client->pos_y = clamp_val(client->pos_y, 0, yres); + + p->dx += packet->dx; + p->dy += packet->dy; +@@ -571,44 +571,50 @@ static int mousedev_open(struct inode *inode, struct file *file) + return error; + } + +-static inline int mousedev_limit_delta(int delta, int limit) +-{ +- return delta > limit ? limit : (delta < -limit ? -limit : delta); +-} +- +-static void mousedev_packet(struct mousedev_client *client, +- signed char *ps2_data) ++static void mousedev_packet(struct mousedev_client *client, u8 *ps2_data) + { + struct mousedev_motion *p = &client->packets[client->tail]; ++ s8 dx, dy, dz; ++ ++ dx = clamp_val(p->dx, -127, 127); ++ p->dx -= dx; ++ ++ dy = clamp_val(p->dy, -127, 127); ++ p->dy -= dy; + +- ps2_data[0] = 0x08 | +- ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07); +- ps2_data[1] = mousedev_limit_delta(p->dx, 127); +- ps2_data[2] = mousedev_limit_delta(p->dy, 127); +- p->dx -= ps2_data[1]; +- p->dy -= ps2_data[2]; ++ ps2_data[0] = BIT(3); ++ ps2_data[0] |= ((dx & BIT(7)) >> 3) | ((dy & BIT(7)) >> 2); ++ ps2_data[0] |= p->buttons & 0x07; ++ ps2_data[1] = dx; ++ ps2_data[2] = dy; + + switch (client->mode) { + case MOUSEDEV_EMUL_EXPS: +- ps2_data[3] = mousedev_limit_delta(p->dz, 7); +- p->dz -= ps2_data[3]; +- ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1); ++ dz = clamp_val(p->dz, -7, 7); ++ p->dz -= dz; ++ ++ ps2_data[3] = (dz & 0x0f) | ((p->buttons & 0x18) << 1); + client->bufsiz = 4; + break; + + case MOUSEDEV_EMUL_IMPS: +- ps2_data[0] |= +- ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); +- ps2_data[3] = mousedev_limit_delta(p->dz, 127); +- p->dz -= ps2_data[3]; ++ dz = clamp_val(p->dz, -127, 127); ++ p->dz -= dz; ++ ++ ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ++ ((p->buttons & 0x08) >> 1); ++ ps2_data[3] = dz; ++ + client->bufsiz = 4; + break; + + case MOUSEDEV_EMUL_PS2: + default: +- ps2_data[0] |= +- ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); + p->dz = 0; ++ ++ ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ++ ((p->buttons & 0x08) >> 1); ++ + client->bufsiz = 3; + break; + } +@@ -714,7 +720,7 @@ static ssize_t mousedev_read(struct file *file, char __user *buffer, + { + struct mousedev_client *client = file->private_data; + struct mousedev *mousedev = client->mousedev; +- signed char data[sizeof(client->ps2)]; ++ u8 data[sizeof(client->ps2)]; + int retval = 0; + + if (!client->ready && !client->buffer && mousedev->exist && +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index d1051e3ce819..e484ea2dc787 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -530,6 +530,20 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { + { } + }; + ++static const struct dmi_system_id i8042_dmi_forcemux_table[] __initconst = { ++ { ++ /* ++ * Sony Vaio VGN-CS series require MUX or the touch sensor ++ * buttons will disturb touchpad operation ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"), ++ }, ++ }, ++ { } ++}; ++ + /* + * On some Asus laptops, just running self tests cause problems. + */ +@@ -692,6 +706,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "20046"), + }, + }, ++ { ++ /* Lenovo ThinkPad L460 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"), ++ }, ++ }, + { + /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ + .matches = { +@@ -1223,6 +1244,9 @@ static int __init i8042_platform_init(void) + if (dmi_check_system(i8042_dmi_nomux_table)) + i8042_nomux = true; + ++ if (dmi_check_system(i8042_dmi_forcemux_table)) ++ i8042_nomux = false; ++ + if (dmi_check_system(i8042_dmi_notimeout_table)) + i8042_notimeout = true; + +diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c +index e503279c34fc..6865b186f749 100644 +--- a/drivers/md/dm-ioctl.c ++++ b/drivers/md/dm-ioctl.c +@@ -1773,12 +1773,12 @@ static int validate_params(uint cmd, struct dm_ioctl *param) + cmd == DM_LIST_VERSIONS_CMD) + return 0; + +- if ((cmd == DM_DEV_CREATE_CMD)) { ++ if (cmd == DM_DEV_CREATE_CMD) { + if (!*param->name) { + DMWARN("name not supplied when creating device"); + return -EINVAL; + } +- } else if ((*param->uuid && *param->name)) { ++ } else if (*param->uuid && *param->name) { + DMWARN("only supply one of name or uuid, cmd(%u)", cmd); + return -EINVAL; + } +diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c +index 3a0d557146c7..bf0410403a6f 100644 +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -3638,6 +3638,7 @@ static int run(struct mddev *mddev) + + if (blk_queue_discard(bdev_get_queue(rdev->bdev))) + discard_supported = true; ++ first = 0; + } + + if (mddev->queue) { +diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c +index 3bbc77aa6a33..483457d4904f 100644 +--- a/drivers/media/usb/usbtv/usbtv-core.c ++++ b/drivers/media/usb/usbtv/usbtv-core.c +@@ -95,6 +95,8 @@ static int usbtv_probe(struct usb_interface *intf, + return 0; + + usbtv_audio_fail: ++ /* we must not free at this point */ ++ usb_get_dev(usbtv->udev); + usbtv_video_free(usbtv); + + usbtv_video_fail: +diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c +index 4ef189a7a2fb..8c04e342e30a 100644 +--- a/drivers/misc/mei/main.c ++++ b/drivers/misc/mei/main.c +@@ -571,7 +571,6 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) + break; + + default: +- dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd); + rets = -ENOIOCTLCMD; + } + +diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c +index 7c0b27d132b1..b479bd81120b 100644 +--- a/drivers/mtd/chips/jedec_probe.c ++++ b/drivers/mtd/chips/jedec_probe.c +@@ -1889,6 +1889,8 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base, + do { + uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi); + mask = (1 << (cfi->device_type * 8)) - 1; ++ if (ofs >= map->size) ++ return 0; + result = map_read(map, base + ofs); + bank++; + } while ((result.x[0] & mask) == CFI_MFR_CONTINUATION); +diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c +index cc1725616f9d..50747573f42e 100644 +--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c ++++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c +@@ -2823,7 +2823,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) + if (!g) { + netif_info(lio, tx_err, lio->netdev, + "Transmit scatter gather: glist null!\n"); +- goto lio_xmit_dma_failed; ++ goto lio_xmit_failed; + } + + cmdsetup.s.gather = 1; +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c +index a20bd8362712..b8517b00e706 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c +@@ -648,7 +648,7 @@ static void hns_gmac_get_strings(u32 stringset, u8 *data) + + static int hns_gmac_get_sset_count(int stringset) + { +- if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) ++ if (stringset == ETH_SS_STATS) + return ARRAY_SIZE(g_gmac_stats_string); + + return 0; +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +index 6634aef0e841..67f33f185a44 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +@@ -384,7 +384,7 @@ void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb) + + int hns_ppe_get_sset_count(int stringset) + { +- if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) ++ if (stringset == ETH_SS_STATS) + return ETH_PPE_STATIC_NUM; + return 0; + } +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +index 1d5b18d7a1d7..4db32c62f062 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +@@ -807,7 +807,7 @@ void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data) + */ + int hns_rcb_get_ring_sset_count(int stringset) + { +- if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS) ++ if (stringset == ETH_SS_STATS) + return HNS_RING_STATIC_REG_NUM; + + return 0; +diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +index a0332129970b..4b91eb70c683 100644 +--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c ++++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +@@ -1000,8 +1000,10 @@ int hns_get_sset_count(struct net_device *netdev, int stringset) + cnt--; + + return cnt; +- } else { ++ } else if (stringset == ETH_SS_STATS) { + return (HNS_NET_STATS_CNT + ops->get_sset_count(h, stringset)); ++ } else { ++ return -EOPNOTSUPP; + } + } + +diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c +index 78530d1714dc..bdce0679674c 100644 +--- a/drivers/parport/parport_pc.c ++++ b/drivers/parport/parport_pc.c +@@ -2646,6 +2646,7 @@ enum parport_pc_pci_cards { + netmos_9901, + netmos_9865, + quatech_sppxp100, ++ wch_ch382l, + }; + + +@@ -2708,6 +2709,7 @@ static struct parport_pc_pci { + /* netmos_9901 */ { 1, { { 0, -1 }, } }, + /* netmos_9865 */ { 1, { { 0, -1 }, } }, + /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, ++ /* wch_ch382l */ { 1, { { 2, -1 }, } }, + }; + + static const struct pci_device_id parport_pc_pci_tbl[] = { +@@ -2797,6 +2799,8 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { + /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ + { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, ++ /* WCH CH382L PCI-E single parallel port card */ ++ { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382l }, + { 0, } /* terminate list */ + }; + MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl); +diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c +index 5e42b5f2f565..32bd8ab79d53 100644 +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -463,6 +463,8 @@ static void pci_device_shutdown(struct device *dev) + + if (drv && drv->shutdown) + drv->shutdown(pci_dev); ++ pci_msi_shutdown(pci_dev); ++ pci_msix_shutdown(pci_dev); + + #ifdef CONFIG_KEXEC_CORE + /* +diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c +index 193ac13de49b..566897f24dee 100644 +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -230,7 +230,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, + res->flags |= IORESOURCE_ROM_ENABLE; + l64 = l & PCI_ROM_ADDRESS_MASK; + sz64 = sz & PCI_ROM_ADDRESS_MASK; +- mask64 = (u32)PCI_ROM_ADDRESS_MASK; ++ mask64 = PCI_ROM_ADDRESS_MASK; + } + + if (res->flags & IORESOURCE_MEM_64) { +diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c +index 25062966cbfa..8b2f8b2a574e 100644 +--- a/drivers/pci/setup-res.c ++++ b/drivers/pci/setup-res.c +@@ -63,7 +63,7 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno) + mask = (u32)PCI_BASE_ADDRESS_IO_MASK; + new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK; + } else if (resno == PCI_ROM_RESOURCE) { +- mask = (u32)PCI_ROM_ADDRESS_MASK; ++ mask = PCI_ROM_ADDRESS_MASK; + } else { + mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; + new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK; +diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c +index 578fae4d474f..8ef905cbfc9c 100644 +--- a/drivers/scsi/virtio_scsi.c ++++ b/drivers/scsi/virtio_scsi.c +@@ -819,6 +819,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { + .eh_abort_handler = virtscsi_abort, + .eh_device_reset_handler = virtscsi_device_reset, + ++ .slave_alloc = virtscsi_device_alloc, + .can_queue = 1024, + .dma_boundary = UINT_MAX, + .use_clustering = ENABLE_CLUSTERING, +diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c +index 1ddba9ae8c0f..c872a2e54c4b 100644 +--- a/drivers/spi/spi-davinci.c ++++ b/drivers/spi/spi-davinci.c +@@ -651,7 +651,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) + buf = t->rx_buf; + t->rx_dma = dma_map_single(&spi->dev, buf, + t->len, DMA_FROM_DEVICE); +- if (dma_mapping_error(&spi->dev, !t->rx_dma)) { ++ if (dma_mapping_error(&spi->dev, t->rx_dma)) { + ret = -EFAULT; + goto err_rx_map; + } +diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c +index c975f6e8be49..8f181caffca3 100644 +--- a/drivers/staging/comedi/drivers/ni_mio_common.c ++++ b/drivers/staging/comedi/drivers/ni_mio_common.c +@@ -1348,6 +1348,8 @@ static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status) + ack |= NISTC_INTA_ACK_AI_START; + if (a_status & NISTC_AI_STATUS1_STOP) + ack |= NISTC_INTA_ACK_AI_STOP; ++ if (a_status & NISTC_AI_STATUS1_OVER) ++ ack |= NISTC_INTA_ACK_AI_ERR; + if (ack) + ni_stc_writew(dev, ack, NISTC_INTA_ACK_REG); + } +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index 251315c35747..ff3286fc22d8 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -1312,6 +1312,11 @@ static void csi_m(struct vc_data *vc) + case 3: + vc->vc_italic = 1; + break; ++ case 21: ++ /* ++ * No console drivers support double underline, so ++ * convert it to a single underline. ++ */ + case 4: + vc->vc_underline = 1; + break; +@@ -1348,7 +1353,6 @@ static void csi_m(struct vc_data *vc) + vc->vc_disp_ctrl = 1; + vc->vc_toggle_meta = 1; + break; +- case 21: + case 22: + vc->vc_intensity = 1; + break; +diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c +index 88bd950665fa..85fb6226770c 100644 +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -1385,7 +1385,6 @@ static void dwc2_conn_id_status_change(struct work_struct *work) + dwc2_core_init(hsotg, false, -1); + dwc2_enable_global_interrupts(hsotg); + spin_lock_irqsave(&hsotg->lock, flags); +- dwc2_hsotg_disconnect(hsotg); + dwc2_hsotg_core_init_disconnected(hsotg, false); + spin_unlock_irqrestore(&hsotg->lock, flags); + dwc2_hsotg_core_connect(hsotg); +@@ -1403,8 +1402,12 @@ static void dwc2_conn_id_status_change(struct work_struct *work) + if (count > 250) + dev_err(hsotg->dev, + "Connection id status change timed out\n"); +- hsotg->op_state = OTG_STATE_A_HOST; + ++ spin_lock_irqsave(&hsotg->lock, flags); ++ dwc2_hsotg_disconnect(hsotg); ++ spin_unlock_irqrestore(&hsotg->lock, flags); ++ ++ hsotg->op_state = OTG_STATE_A_HOST; + /* Initialize the Core for Host mode */ + dwc2_core_init(hsotg, false, -1); + dwc2_enable_global_interrupts(hsotg); +diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c +index ee579ba2b59e..a5dae5bb62ab 100644 +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -223,6 +223,13 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer, + /* pick the first one */ + list = list_first_entry(&hidg->completed_out_req, + struct f_hidg_req_list, list); ++ ++ /* ++ * Remove this from list to protect it from beign free() ++ * while host disables our function ++ */ ++ list_del(&list->list); ++ + req = list->req; + count = min_t(unsigned int, count, req->actual - list->pos); + spin_unlock_irqrestore(&hidg->spinlock, flags); +@@ -238,15 +245,20 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer, + * call, taking into account its current read position. + */ + if (list->pos == req->actual) { +- spin_lock_irqsave(&hidg->spinlock, flags); +- list_del(&list->list); + kfree(list); +- spin_unlock_irqrestore(&hidg->spinlock, flags); + + req->length = hidg->report_length; + ret = usb_ep_queue(hidg->out_ep, req, GFP_KERNEL); +- if (ret < 0) ++ if (ret < 0) { ++ free_ep_req(hidg->out_ep, req); + return ret; ++ } ++ } else { ++ spin_lock_irqsave(&hidg->spinlock, flags); ++ list_add(&list->list, &hidg->completed_out_req); ++ spin_unlock_irqrestore(&hidg->spinlock, flags); ++ ++ wake_up(&hidg->read_queue); + } + + return count; +@@ -490,14 +502,18 @@ static void hidg_disable(struct usb_function *f) + { + struct f_hidg *hidg = func_to_hidg(f); + struct f_hidg_req_list *list, *next; ++ unsigned long flags; + + usb_ep_disable(hidg->in_ep); + usb_ep_disable(hidg->out_ep); + ++ spin_lock_irqsave(&hidg->spinlock, flags); + list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) { ++ free_ep_req(hidg->out_ep, list->req); + list_del(&list->list); + kfree(list); + } ++ spin_unlock_irqrestore(&hidg->spinlock, flags); + } + + static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) +diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c +index af60cc3714c1..5ead414586a1 100644 +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -201,12 +201,6 @@ static inline struct usb_request *midi_alloc_ep_req(struct usb_ep *ep, + return alloc_ep_req(ep, length, length); + } + +-static void free_ep_req(struct usb_ep *ep, struct usb_request *req) +-{ +- kfree(req->buf); +- usb_ep_free_request(ep, req); +-} +- + static const uint8_t f_midi_cin_length[] = { + 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1 + }; +diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c +index 9f3ced62d916..67b243989938 100644 +--- a/drivers/usb/gadget/function/f_sourcesink.c ++++ b/drivers/usb/gadget/function/f_sourcesink.c +@@ -303,12 +303,6 @@ static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len) + return alloc_ep_req(ep, len, ss->buflen); + } + +-void free_ep_req(struct usb_ep *ep, struct usb_request *req) +-{ +- kfree(req->buf); +- usb_ep_free_request(ep, req); +-} +- + static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) + { + int value; +diff --git a/drivers/usb/gadget/function/g_zero.h b/drivers/usb/gadget/function/g_zero.h +index 15f180904f8a..5ed90b437f18 100644 +--- a/drivers/usb/gadget/function/g_zero.h ++++ b/drivers/usb/gadget/function/g_zero.h +@@ -59,7 +59,6 @@ void lb_modexit(void); + int lb_modinit(void); + + /* common utilities */ +-void free_ep_req(struct usb_ep *ep, struct usb_request *req); + void disable_endpoints(struct usb_composite_dev *cdev, + struct usb_ep *in, struct usb_ep *out, + struct usb_ep *iso_in, struct usb_ep *iso_out); +diff --git a/drivers/usb/gadget/u_f.c b/drivers/usb/gadget/u_f.c +index c6276f0268ae..907f8144813c 100644 +--- a/drivers/usb/gadget/u_f.c ++++ b/drivers/usb/gadget/u_f.c +@@ -11,16 +11,18 @@ + * published by the Free Software Foundation. + */ + +-#include + #include "u_f.h" ++#include + +-struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len) ++struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len) + { + struct usb_request *req; + + req = usb_ep_alloc_request(ep, GFP_ATOMIC); + if (req) { + req->length = len ?: default_len; ++ if (usb_endpoint_dir_out(ep->desc)) ++ req->length = usb_ep_align(ep, req->length); + req->buf = kmalloc(req->length, GFP_ATOMIC); + if (!req->buf) { + usb_ep_free_request(ep, req); +diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h +index 1d5f0eb68552..69a1d10df04f 100644 +--- a/drivers/usb/gadget/u_f.h ++++ b/drivers/usb/gadget/u_f.h +@@ -16,6 +16,8 @@ + #ifndef __U_F_H__ + #define __U_F_H__ + ++#include ++ + /* Variable Length Array Macros **********************************************/ + #define vla_group(groupname) size_t groupname##__next = 0 + #define vla_group_size(groupname) groupname##__next +@@ -45,8 +47,26 @@ + struct usb_ep; + struct usb_request; + +-struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len); +- +-#endif /* __U_F_H__ */ ++/** ++ * alloc_ep_req - returns a usb_request allocated by the gadget driver and ++ * allocates the request's buffer. ++ * ++ * @ep: the endpoint to allocate a usb_request ++ * @len: usb_requests's buffer suggested size ++ * @default_len: used if @len is not provided, ie, is 0 ++ * ++ * In case @ep direction is OUT, the @len will be aligned to ep's ++ * wMaxPacketSize. In order to avoid memory leaks or drops, *always* use ++ * usb_requests's length (req->length) to refer to the allocated buffer size. ++ * Requests allocated via alloc_ep_req() *must* be freed by free_ep_req(). ++ */ ++struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len); + ++/* Frees a usb_request previously allocated by alloc_ep_req() */ ++static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req) ++{ ++ kfree(req->buf); ++ usb_ep_free_request(ep, req); ++} + ++#endif /* __U_F_H__ */ +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index a4ab4fdf5ba3..64a4427678b0 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -151,6 +151,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x12B8, 0xEC62) }, /* Link G4+ ECU */ + { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ + { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ ++ { USB_DEVICE(0x155A, 0x1006) }, /* ELDAT Easywave RX09 */ + { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */ + { USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */ + { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 64fe9dc25ed4..a224c7a3ce09 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -773,6 +773,7 @@ static const struct usb_device_id id_table_combined[] = { + .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, + { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, + { USB_DEVICE(NOVITUS_VID, NOVITUS_BONO_E_PID) }, ++ { USB_DEVICE(FTDI_VID, RTSYSTEMS_USB_VX8_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) }, +@@ -935,6 +936,7 @@ static const struct usb_device_id id_table_combined[] = { + { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_FHE_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, + { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index 543d2801632b..76a10b222ff9 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -922,6 +922,9 @@ + /* + * RT Systems programming cables for various ham radios + */ ++/* This device uses the VID of FTDI */ ++#define RTSYSTEMS_USB_VX8_PID 0x9e50 /* USB-VX8 USB to 7 pin modular plug for Yaesu VX-8 radio */ ++ + #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ + #define RTSYSTEMS_USB_S03_PID 0x9001 /* RTS-03 USB to Serial Adapter */ + #define RTSYSTEMS_USB_59_PID 0x9e50 /* USB-59 USB to 8 pin plug */ +@@ -1440,6 +1443,12 @@ + */ + #define FTDI_CINTERION_MC55I_PID 0xA951 + ++/* ++ * Product: FirmwareHubEmulator ++ * Manufacturer: Harman Becker Automotive Systems ++ */ ++#define FTDI_FHE_PID 0xA9A0 ++ + /* + * Product: Comet Caller ID decoder + * Manufacturer: Crucible Technologies +diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c +index dcf26537c935..a52ca5cba015 100644 +--- a/fs/compat_ioctl.c ++++ b/fs/compat_ioctl.c +@@ -811,7 +811,7 @@ static int compat_ioctl_preallocate(struct file *file, + */ + #define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff) + +-#define COMPATIBLE_IOCTL(cmd) XFORM(cmd), ++#define COMPATIBLE_IOCTL(cmd) XFORM((u32)cmd), + /* ioctl should not be warned about even if it's not implemented. + Valid reasons to use this: + - It is implemented with ->compat_ioctl on some device, but programs +diff --git a/include/linux/audit.h b/include/linux/audit.h +index faac391badac..9b95bb222e73 100644 +--- a/include/linux/audit.h ++++ b/include/linux/audit.h +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #define AUDIT_INO_UNSET ((unsigned long)-1) + #define AUDIT_DEV_UNSET ((dev_t)-1) +@@ -239,6 +240,23 @@ static inline unsigned int audit_get_sessionid(struct task_struct *tsk) + return tsk->sessionid; + } + ++static inline struct tty_struct *audit_get_tty(struct task_struct *tsk) ++{ ++ struct tty_struct *tty = NULL; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&tsk->sighand->siglock, flags); ++ if (tsk->signal) ++ tty = tty_kref_get(tsk->signal->tty); ++ spin_unlock_irqrestore(&tsk->sighand->siglock, flags); ++ return tty; ++} ++ ++static inline void audit_put_tty(struct tty_struct *tty) ++{ ++ tty_kref_put(tty); ++} ++ + extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); + extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode); + extern void __audit_bprm(struct linux_binprm *bprm); +@@ -410,6 +428,12 @@ static inline unsigned int audit_get_sessionid(struct task_struct *tsk) + { + return -1; + } ++static inline struct tty_struct *audit_get_tty(struct task_struct *tsk) ++{ ++ return NULL; ++} ++static inline void audit_put_tty(struct tty_struct *tty) ++{ } + static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) + { } + static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, +diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h +index a91b3b75da0f..bb3a4bb35183 100644 +--- a/include/linux/cpumask.h ++++ b/include/linux/cpumask.h +@@ -661,6 +661,11 @@ void alloc_bootmem_cpumask_var(cpumask_var_t *mask); + void free_cpumask_var(cpumask_var_t mask); + void free_bootmem_cpumask_var(cpumask_var_t mask); + ++static inline bool cpumask_available(cpumask_var_t mask) ++{ ++ return mask != NULL; ++} ++ + #else + typedef struct cpumask cpumask_var_t[1]; + +@@ -701,6 +706,11 @@ static inline void free_cpumask_var(cpumask_var_t mask) + static inline void free_bootmem_cpumask_var(cpumask_var_t mask) + { + } ++ ++static inline bool cpumask_available(cpumask_var_t mask) ++{ ++ return true; ++} + #endif /* CONFIG_CPUMASK_OFFSTACK */ + + /* It's common to want to use cpu_all_mask in struct member initializers, +diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h +index 5fdc55312334..2fb10601febe 100644 +--- a/include/linux/jiffies.h ++++ b/include/linux/jiffies.h +@@ -1,6 +1,7 @@ + #ifndef _LINUX_JIFFIES_H + #define _LINUX_JIFFIES_H + ++#include + #include + #include + #include +@@ -63,19 +64,17 @@ extern int register_refined_jiffies(long clock_tick_rate); + /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */ + #define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ) + +-/* some arch's have a small-data section that can be accessed register-relative +- * but that can only take up to, say, 4-byte variables. jiffies being part of +- * an 8-byte variable may not be correctly accessed unless we force the issue +- */ +-#define __jiffy_data __attribute__((section(".data"))) ++#ifndef __jiffy_arch_data ++#define __jiffy_arch_data ++#endif + + /* + * The 64-bit value is not atomic - you MUST NOT read it + * without sampling the sequence number in jiffies_lock. + * get_jiffies_64() will do this for you as appropriate. + */ +-extern u64 __jiffy_data jiffies_64; +-extern unsigned long volatile __jiffy_data jiffies; ++extern u64 __cacheline_aligned_in_smp jiffies_64; ++extern unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data jiffies; + + #if (BITS_PER_LONG < 64) + u64 get_jiffies_64(void); +diff --git a/include/linux/llist.h b/include/linux/llist.h +index fd4ca0b4fe0f..ac6796138ba0 100644 +--- a/include/linux/llist.h ++++ b/include/linux/llist.h +@@ -87,6 +87,23 @@ static inline void init_llist_head(struct llist_head *list) + #define llist_entry(ptr, type, member) \ + container_of(ptr, type, member) + ++/** ++ * member_address_is_nonnull - check whether the member address is not NULL ++ * @ptr: the object pointer (struct type * that contains the llist_node) ++ * @member: the name of the llist_node within the struct. ++ * ++ * This macro is conceptually the same as ++ * &ptr->member != NULL ++ * but it works around the fact that compilers can decide that taking a member ++ * address is never a NULL pointer. ++ * ++ * Real objects that start at a high address and have a member at NULL are ++ * unlikely to exist, but such pointers may be returned e.g. by the ++ * container_of() macro. ++ */ ++#define member_address_is_nonnull(ptr, member) \ ++ ((uintptr_t)(ptr) + offsetof(typeof(*(ptr)), member) != 0) ++ + /** + * llist_for_each - iterate over some deleted entries of a lock-less list + * @pos: the &struct llist_node to use as a loop cursor +@@ -121,7 +138,7 @@ static inline void init_llist_head(struct llist_head *list) + */ + #define llist_for_each_entry(pos, node, member) \ + for ((pos) = llist_entry((node), typeof(*(pos)), member); \ +- &(pos)->member != NULL; \ ++ member_address_is_nonnull(pos, member); \ + (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member)) + + /** +@@ -143,7 +160,7 @@ static inline void init_llist_head(struct llist_head *list) + */ + #define llist_for_each_entry_safe(pos, n, node, member) \ + for (pos = llist_entry((node), typeof(*pos), member); \ +- &pos->member != NULL && \ ++ member_address_is_nonnull(pos, member) && \ + (n = llist_entry(pos->member.next, typeof(*n), member), true); \ + pos = n) + +diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h +index 53e361a9af79..6923e4049de3 100644 +--- a/include/linux/netfilter/x_tables.h ++++ b/include/linux/netfilter/x_tables.h +@@ -247,6 +247,8 @@ unsigned int *xt_alloc_entry_offsets(unsigned int size); + bool xt_find_jump_offset(const unsigned int *offsets, + unsigned int target, unsigned int size); + ++int xt_check_proc_name(const char *name, unsigned int size); ++ + int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto, + bool inv_proto); + int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto, +diff --git a/include/linux/nospec.h b/include/linux/nospec.h +index 115381228203..e791ebc65c9c 100644 +--- a/include/linux/nospec.h ++++ b/include/linux/nospec.h +@@ -20,20 +20,6 @@ + static inline unsigned long array_index_mask_nospec(unsigned long index, + unsigned long size) + { +- /* +- * Warn developers about inappropriate array_index_nospec() usage. +- * +- * Even if the CPU speculates past the WARN_ONCE branch, the +- * sign bit of @index is taken into account when generating the +- * mask. +- * +- * This warning is compiled out when the compiler can infer that +- * @index and @size are less than LONG_MAX. +- */ +- if (WARN_ONCE(index > LONG_MAX || size > LONG_MAX, +- "array_index_nospec() limited to range of [0, LONG_MAX]\n")) +- return 0; +- + /* + * Always calculate and emit the mask even if the compiler + * thinks the mask is not needed. The compiler does not take +diff --git a/include/linux/tty.h b/include/linux/tty.h +index 83b264c52898..a1042afff99a 100644 +--- a/include/linux/tty.h ++++ b/include/linux/tty.h +@@ -372,6 +372,7 @@ extern void proc_clear_tty(struct task_struct *p); + extern struct tty_struct *get_current_tty(void); + /* tty_io.c */ + extern int __init tty_init(void); ++extern const char *tty_name(const struct tty_struct *tty); + #else + static inline void console_init(void) + { } +@@ -392,6 +393,8 @@ static inline struct tty_struct *get_current_tty(void) + /* tty_io.c */ + static inline int __init tty_init(void) + { return 0; } ++static inline const char *tty_name(const struct tty_struct *tty) ++{ return "(none)"; } + #endif + + extern void tty_write_flush(struct tty_struct *); +@@ -420,7 +423,6 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) + + extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, + const char *routine); +-extern const char *tty_name(const struct tty_struct *tty); + extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); + extern int __tty_check_change(struct tty_struct *tty, int sig); + extern int tty_check_change(struct tty_struct *tty); +diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h +index 3d583a10b926..7e84aac39ade 100644 +--- a/include/linux/usb/gadget.h ++++ b/include/linux/usb/gadget.h +@@ -662,9 +662,21 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev) + #define gadget_for_each_ep(tmp, gadget) \ + list_for_each_entry(tmp, &(gadget)->ep_list, ep_list) + ++/** ++ * usb_ep_align - returns @len aligned to ep's maxpacketsize. ++ * @ep: the endpoint whose maxpacketsize is used to align @len ++ * @len: buffer size's length to align to @ep's maxpacketsize ++ * ++ * This helper is used to align buffer's size to an ep's maxpacketsize. ++ */ ++static inline size_t usb_ep_align(struct usb_ep *ep, size_t len) ++{ ++ return round_up(len, (size_t)le16_to_cpu(ep->desc->wMaxPacketSize)); ++} ++ + /** + * usb_ep_align_maybe - returns @len aligned to ep's maxpacketsize if gadget +- * requires quirk_ep_out_aligned_size, otherwise reguens len. ++ * requires quirk_ep_out_aligned_size, otherwise returns len. + * @g: controller to check for quirk + * @ep: the endpoint whose maxpacketsize is used to align @len + * @len: buffer size's length to align to @ep's maxpacketsize +@@ -675,8 +687,7 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev) + static inline size_t + usb_ep_align_maybe(struct usb_gadget *g, struct usb_ep *ep, size_t len) + { +- return !g->quirk_ep_out_aligned_size ? len : +- round_up(len, (size_t)ep->desc->wMaxPacketSize); ++ return g->quirk_ep_out_aligned_size ? usb_ep_align(ep, len) : len; + } + + /** +diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h +index a78ff97eb249..d77416963f05 100644 +--- a/include/rdma/ib_addr.h ++++ b/include/rdma/ib_addr.h +@@ -123,6 +123,8 @@ int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev, + const unsigned char *dst_dev_addr); + + int rdma_addr_size(struct sockaddr *addr); ++int rdma_addr_size_in6(struct sockaddr_in6 *addr); ++int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr); + + int rdma_addr_find_smac_by_sgid(union ib_gid *sgid, u8 *smac, u16 *vlan_id); + int rdma_addr_find_dmac_by_grh(const union ib_gid *sgid, const union ib_gid *dgid, +diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h +index 1becea86c73c..eb3c786afa70 100644 +--- a/include/uapi/linux/pci_regs.h ++++ b/include/uapi/linux/pci_regs.h +@@ -106,7 +106,7 @@ + #define PCI_SUBSYSTEM_ID 0x2e + #define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */ + #define PCI_ROM_ADDRESS_ENABLE 0x01 +-#define PCI_ROM_ADDRESS_MASK (~0x7ffUL) ++#define PCI_ROM_ADDRESS_MASK (~0x7ffU) + + #define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */ + +diff --git a/kernel/audit.c b/kernel/audit.c +index 41f9a38bb800..6881b485aa2a 100644 +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -64,7 +64,6 @@ + #include + #endif + #include +-#include + #include + #include + +@@ -1876,21 +1875,14 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) + { + const struct cred *cred; + char comm[sizeof(tsk->comm)]; +- char *tty; ++ struct tty_struct *tty; + + if (!ab) + return; + + /* tsk == current */ + cred = current_cred(); +- +- spin_lock_irq(&tsk->sighand->siglock); +- if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) +- tty = tsk->signal->tty->name; +- else +- tty = "(none)"; +- spin_unlock_irq(&tsk->sighand->siglock); +- ++ tty = audit_get_tty(tsk); + audit_log_format(ab, + " ppid=%d pid=%d auid=%u uid=%u gid=%u" + " euid=%u suid=%u fsuid=%u" +@@ -1906,11 +1898,11 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) + from_kgid(&init_user_ns, cred->egid), + from_kgid(&init_user_ns, cred->sgid), + from_kgid(&init_user_ns, cred->fsgid), +- tty, audit_get_sessionid(tsk)); +- ++ tty ? tty_name(tty) : "(none)", ++ audit_get_sessionid(tsk)); ++ audit_put_tty(tty); + audit_log_format(ab, " comm="); + audit_log_untrustedstring(ab, get_task_comm(comm, tsk)); +- + audit_log_d_path_exe(ab, tsk->mm); + audit_log_task_context(ab); + } +diff --git a/kernel/auditsc.c b/kernel/auditsc.c +index 48f45987dc6c..4bdea31cf6ce 100644 +--- a/kernel/auditsc.c ++++ b/kernel/auditsc.c +@@ -1976,6 +1976,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, + { + struct audit_buffer *ab; + uid_t uid, oldloginuid, loginuid; ++ struct tty_struct *tty; + + if (!audit_enabled) + return; +@@ -1984,14 +1984,17 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, + uid = from_kuid(&init_user_ns, task_uid(current)); + oldloginuid = from_kuid(&init_user_ns, koldloginuid); + loginuid = from_kuid(&init_user_ns, kloginuid), +- ++ tty = audit_get_tty(current); ++ + ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); + if (!ab) + return; + audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid); + audit_log_task_context(ab); +- audit_log_format(ab, " old-auid=%u auid=%u old-ses=%u ses=%u res=%d", +- oldloginuid, loginuid, oldsessionid, sessionid, !rc); ++ audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d", ++ oldloginuid, loginuid, tty ? tty_name(tty) : "(none)", ++ oldsessionid, sessionid, !rc); ++ audit_put_tty(tty); + audit_log_end(ab); + } + +diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c +index 92ce5f4ccc26..a27245fdcd81 100644 +--- a/kernel/events/hw_breakpoint.c ++++ b/kernel/events/hw_breakpoint.c +@@ -427,16 +427,9 @@ EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); + * modify_user_hw_breakpoint - modify a user-space hardware breakpoint + * @bp: the breakpoint structure to modify + * @attr: new breakpoint attributes +- * @triggered: callback to trigger when we hit the breakpoint +- * @tsk: pointer to 'task_struct' of the process to which the address belongs + */ + int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr) + { +- u64 old_addr = bp->attr.bp_addr; +- u64 old_len = bp->attr.bp_len; +- int old_type = bp->attr.bp_type; +- int err = 0; +- + /* + * modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it + * will not be possible to raise IPIs that invoke __perf_event_disable. +@@ -451,27 +444,18 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att + bp->attr.bp_addr = attr->bp_addr; + bp->attr.bp_type = attr->bp_type; + bp->attr.bp_len = attr->bp_len; ++ bp->attr.disabled = 1; + +- if (attr->disabled) +- goto end; +- +- err = validate_hw_breakpoint(bp); +- if (!err) +- perf_event_enable(bp); ++ if (!attr->disabled) { ++ int err = validate_hw_breakpoint(bp); + +- if (err) { +- bp->attr.bp_addr = old_addr; +- bp->attr.bp_type = old_type; +- bp->attr.bp_len = old_len; +- if (!bp->attr.disabled) +- perf_event_enable(bp); ++ if (err) ++ return err; + +- return err; ++ perf_event_enable(bp); ++ bp->attr.disabled = 0; + } + +-end: +- bp->attr.disabled = attr->disabled; +- + return 0; + } + EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint); +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index a079ed14f230..5f55a8bf5264 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -836,7 +836,7 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) + * This code is triggered unconditionally. Check the affinity + * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out. + */ +- if (desc->irq_common_data.affinity) ++ if (cpumask_available(desc->irq_common_data.affinity)) + cpumask_copy(mask, desc->irq_common_data.affinity); + else + valid = false; +diff --git a/kernel/kprobes.c b/kernel/kprobes.c +index 695763516908..bbe9dd0886bd 100644 +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -125,7 +125,7 @@ static void *alloc_insn_page(void) + return module_alloc(PAGE_SIZE); + } + +-static void free_insn_page(void *page) ++void __weak free_insn_page(void *page) + { + module_memfree(page); + } +diff --git a/mm/backing-dev.c b/mm/backing-dev.c +index a988d4ef39da..7f80b1a1bc34 100644 +--- a/mm/backing-dev.c ++++ b/mm/backing-dev.c +@@ -922,7 +922,7 @@ static atomic_t nr_wb_congested[2]; + void clear_wb_congested(struct bdi_writeback_congested *congested, int sync) + { + wait_queue_head_t *wqh = &congestion_wqh[sync]; +- enum wb_state bit; ++ enum wb_congested_state bit; + + bit = sync ? WB_sync_congested : WB_async_congested; + if (test_and_clear_bit(bit, &congested->state)) +@@ -935,7 +935,7 @@ EXPORT_SYMBOL(clear_wb_congested); + + void set_wb_congested(struct bdi_writeback_congested *congested, int sync) + { +- enum wb_state bit; ++ enum wb_congested_state bit; + + bit = sync ? WB_sync_congested : WB_async_congested; + if (!test_and_set_bit(bit, &congested->state)) +diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c +index 906f88550cd8..0dc27d2e8f18 100644 +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -2251,8 +2251,14 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) + else + sec_level = authreq_to_seclevel(auth); + +- if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) ++ if (smp_sufficient_security(hcon, sec_level, SMP_USE_LTK)) { ++ /* If link is already encrypted with sufficient security we ++ * still need refresh encryption as per Core Spec 5.0 Vol 3, ++ * Part H 2.4.6 ++ */ ++ smp_ltk_encrypt(conn, hcon->sec_level); + return 0; ++ } + + if (sec_level > hcon->pending_sec_level) + hcon->pending_sec_level = sec_level; +diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c +index 9637a681bdda..9adf16258cab 100644 +--- a/net/bridge/netfilter/ebt_among.c ++++ b/net/bridge/netfilter/ebt_among.c +@@ -177,6 +177,28 @@ static bool poolsize_invalid(const struct ebt_mac_wormhash *w) + return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple)); + } + ++static bool wormhash_offset_invalid(int off, unsigned int len) ++{ ++ if (off == 0) /* not present */ ++ return false; ++ ++ if (off < (int)sizeof(struct ebt_among_info) || ++ off % __alignof__(struct ebt_mac_wormhash)) ++ return true; ++ ++ off += sizeof(struct ebt_mac_wormhash); ++ ++ return off > len; ++} ++ ++static bool wormhash_sizes_valid(const struct ebt_mac_wormhash *wh, int a, int b) ++{ ++ if (a == 0) ++ a = sizeof(struct ebt_among_info); ++ ++ return ebt_mac_wormhash_size(wh) + a == b; ++} ++ + static int ebt_among_mt_check(const struct xt_mtchk_param *par) + { + const struct ebt_among_info *info = par->matchinfo; +@@ -189,6 +211,10 @@ static int ebt_among_mt_check(const struct xt_mtchk_param *par) + if (expected_length > em->match_size) + return -EINVAL; + ++ if (wormhash_offset_invalid(info->wh_dst_ofs, em->match_size) || ++ wormhash_offset_invalid(info->wh_src_ofs, em->match_size)) ++ return -EINVAL; ++ + wh_dst = ebt_among_wh_dst(info); + if (poolsize_invalid(wh_dst)) + return -EINVAL; +@@ -201,6 +227,14 @@ static int ebt_among_mt_check(const struct xt_mtchk_param *par) + if (poolsize_invalid(wh_src)) + return -EINVAL; + ++ if (info->wh_src_ofs < info->wh_dst_ofs) { ++ if (!wormhash_sizes_valid(wh_src, info->wh_src_ofs, info->wh_dst_ofs)) ++ return -EINVAL; ++ } else { ++ if (!wormhash_sizes_valid(wh_dst, info->wh_dst_ofs, info->wh_src_ofs)) ++ return -EINVAL; ++ } ++ + expected_length += ebt_mac_wormhash_size(wh_src); + + if (em->match_size != EBT_ALIGN(expected_length)) { +diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c +index 574f7ebba0b6..ac8342dcb55e 100644 +--- a/net/ipv4/netfilter/nf_nat_h323.c ++++ b/net/ipv4/netfilter/nf_nat_h323.c +@@ -252,16 +252,16 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, + if (set_h245_addr(skb, protoff, data, dataoff, taddr, + &ct->tuplehash[!dir].tuple.dst.u3, + htons((port & htons(1)) ? nated_port + 1 : +- nated_port)) == 0) { +- /* Save ports */ +- info->rtp_port[i][dir] = rtp_port; +- info->rtp_port[i][!dir] = htons(nated_port); +- } else { ++ nated_port))) { + nf_ct_unexpect_related(rtp_exp); + nf_ct_unexpect_related(rtcp_exp); + return -1; + } + ++ /* Save ports */ ++ info->rtp_port[i][dir] = rtp_port; ++ info->rtp_port[i][!dir] = htons(nated_port); ++ + /* Success */ + pr_debug("nf_nat_h323: expect RTP %pI4:%hu->%pI4:%hu\n", + &rtp_exp->tuple.src.u3.ip, +@@ -370,15 +370,15 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct, + /* Modify signal */ + if (set_h225_addr(skb, protoff, data, dataoff, taddr, + &ct->tuplehash[!dir].tuple.dst.u3, +- htons(nated_port)) == 0) { +- /* Save ports */ +- info->sig_port[dir] = port; +- info->sig_port[!dir] = htons(nated_port); +- } else { ++ htons(nated_port))) { + nf_ct_unexpect_related(exp); + return -1; + } + ++ /* Save ports */ ++ info->sig_port[dir] = port; ++ info->sig_port[!dir] = htons(nated_port); ++ + pr_debug("nf_nat_q931: expect H.245 %pI4:%hu->%pI4:%hu\n", + &exp->tuple.src.u3.ip, + ntohs(exp->tuple.src.u.tcp.port), +@@ -462,24 +462,27 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct, + /* Modify signal */ + if (set_h225_addr(skb, protoff, data, 0, &taddr[idx], + &ct->tuplehash[!dir].tuple.dst.u3, +- htons(nated_port)) == 0) { +- /* Save ports */ +- info->sig_port[dir] = port; +- info->sig_port[!dir] = htons(nated_port); +- +- /* Fix for Gnomemeeting */ +- if (idx > 0 && +- get_h225_addr(ct, *data, &taddr[0], &addr, &port) && +- (ntohl(addr.ip) & 0xff000000) == 0x7f000000) { +- set_h225_addr(skb, protoff, data, 0, &taddr[0], +- &ct->tuplehash[!dir].tuple.dst.u3, +- info->sig_port[!dir]); +- } +- } else { ++ htons(nated_port))) { + nf_ct_unexpect_related(exp); + return -1; + } + ++ /* Save ports */ ++ info->sig_port[dir] = port; ++ info->sig_port[!dir] = htons(nated_port); ++ ++ /* Fix for Gnomemeeting */ ++ if (idx > 0 && ++ get_h225_addr(ct, *data, &taddr[0], &addr, &port) && ++ (ntohl(addr.ip) & 0xff000000) == 0x7f000000) { ++ if (set_h225_addr(skb, protoff, data, 0, &taddr[0], ++ &ct->tuplehash[!dir].tuple.dst.u3, ++ info->sig_port[!dir])) { ++ nf_ct_unexpect_related(exp); ++ return -1; ++ } ++ } ++ + /* Success */ + pr_debug("nf_nat_ras: expect Q.931 %pI4:%hu->%pI4:%hu\n", + &exp->tuple.src.u3.ip, +@@ -550,9 +553,9 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, + } + + /* Modify signal */ +- if (!set_h225_addr(skb, protoff, data, dataoff, taddr, +- &ct->tuplehash[!dir].tuple.dst.u3, +- htons(nated_port)) == 0) { ++ if (set_h225_addr(skb, protoff, data, dataoff, taddr, ++ &ct->tuplehash[!dir].tuple.dst.u3, ++ htons(nated_port))) { + nf_ct_unexpect_related(exp); + return -1; + } +diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c +index e4b0fb2f06a3..d7105422bc63 100644 +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -614,7 +614,6 @@ static void vti6_link_config(struct ip6_tnl *t) + { + struct net_device *dev = t->dev; + struct __ip6_tnl_parm *p = &t->parms; +- struct net_device *tdev = NULL; + + memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr)); + memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr)); +@@ -627,25 +626,6 @@ static void vti6_link_config(struct ip6_tnl *t) + dev->flags |= IFF_POINTOPOINT; + else + dev->flags &= ~IFF_POINTOPOINT; +- +- if (p->flags & IP6_TNL_F_CAP_XMIT) { +- int strict = (ipv6_addr_type(&p->raddr) & +- (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL)); +- struct rt6_info *rt = rt6_lookup(t->net, +- &p->raddr, &p->laddr, +- p->link, strict); +- +- if (rt) +- tdev = rt->dst.dev; +- ip6_rt_put(rt); +- } +- +- if (!tdev && p->link) +- tdev = __dev_get_by_index(t->net, p->link); +- +- if (tdev) +- dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len, +- IPV6_MIN_MTU); + } + + /** +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 660939df7c94..4ece07c68b3f 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -999,9 +999,8 @@ static const struct nla_policy tuple_nla_policy[CTA_TUPLE_MAX+1] = { + + static int + ctnetlink_parse_tuple(const struct nlattr * const cda[], +- struct nf_conntrack_tuple *tuple, +- enum ctattr_type type, u_int8_t l3num, +- struct nf_conntrack_zone *zone) ++ struct nf_conntrack_tuple *tuple, u32 type, ++ u_int8_t l3num, struct nf_conntrack_zone *zone) + { + struct nlattr *tb[CTA_TUPLE_MAX+1]; + int err; +@@ -2416,7 +2415,7 @@ static struct nfnl_ct_hook ctnetlink_glue_hook = { + static inline int + ctnetlink_exp_dump_tuple(struct sk_buff *skb, + const struct nf_conntrack_tuple *tuple, +- enum ctattr_expect type) ++ u32 type) + { + struct nlattr *nest_parms; + +diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c +index 34ae20490c94..1f3c305df45d 100644 +--- a/net/netfilter/x_tables.c ++++ b/net/netfilter/x_tables.c +@@ -366,6 +366,36 @@ textify_hooks(char *buf, size_t size, unsigned int mask, uint8_t nfproto) + return buf; + } + ++/** ++ * xt_check_proc_name - check that name is suitable for /proc file creation ++ * ++ * @name: file name candidate ++ * @size: length of buffer ++ * ++ * some x_tables modules wish to create a file in /proc. ++ * This function makes sure that the name is suitable for this ++ * purpose, it checks that name is NUL terminated and isn't a 'special' ++ * name, like "..". ++ * ++ * returns negative number on error or 0 if name is useable. ++ */ ++int xt_check_proc_name(const char *name, unsigned int size) ++{ ++ if (name[0] == '\0') ++ return -EINVAL; ++ ++ if (strnlen(name, size) == size) ++ return -ENAMETOOLONG; ++ ++ if (strcmp(name, ".") == 0 || ++ strcmp(name, "..") == 0 || ++ strchr(name, '/')) ++ return -EINVAL; ++ ++ return 0; ++} ++EXPORT_SYMBOL(xt_check_proc_name); ++ + int xt_check_match(struct xt_mtchk_param *par, + unsigned int size, u_int8_t proto, bool inv_proto) + { +diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c +index 178696852bde..7381be0cdcdf 100644 +--- a/net/netfilter/xt_hashlimit.c ++++ b/net/netfilter/xt_hashlimit.c +@@ -668,8 +668,9 @@ static int hashlimit_mt_check(const struct xt_mtchk_param *par) + + if (info->cfg.gc_interval == 0 || info->cfg.expire == 0) + return -EINVAL; +- if (info->name[sizeof(info->name)-1] != '\0') +- return -EINVAL; ++ ret = xt_check_proc_name(info->name, sizeof(info->name)); ++ if (ret) ++ return ret; + if (par->family == NFPROTO_IPV4) { + if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32) + return -EINVAL; +diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c +index d725a27743a1..cd53b861a15c 100644 +--- a/net/netfilter/xt_recent.c ++++ b/net/netfilter/xt_recent.c +@@ -364,9 +364,9 @@ static int recent_mt_check(const struct xt_mtchk_param *par, + info->hit_count, XT_RECENT_MAX_NSTAMPS - 1); + return -EINVAL; + } +- if (info->name[0] == '\0' || +- strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN) +- return -EINVAL; ++ ret = xt_check_proc_name(info->name, sizeof(info->name)); ++ if (ret) ++ return ret; + + if (ip_pkt_list_tot && info->hit_count < ip_pkt_list_tot) + nstamp_mask = roundup_pow_of_two(ip_pkt_list_tot) - 1; +diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c +index ccfdc7115a83..a00ec715aa46 100644 +--- a/net/xfrm/xfrm_ipcomp.c ++++ b/net/xfrm/xfrm_ipcomp.c +@@ -283,7 +283,7 @@ static struct crypto_comp * __percpu *ipcomp_alloc_tfms(const char *alg_name) + struct crypto_comp *tfm; + + /* This can be any valid CPU ID so we don't need locking. */ +- tfm = __this_cpu_read(*pos->tfms); ++ tfm = this_cpu_read(*pos->tfms); + + if (!strcmp(crypto_comp_name(tfm), alg_name)) { + pos->users++; +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index 96d664e198bf..34b5b4bcf5cb 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -1845,6 +1845,11 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen + struct xfrm_mgr *km; + struct xfrm_policy *pol = NULL; + ++#ifdef CONFIG_COMPAT ++ if (is_compat_task()) ++ return -EOPNOTSUPP; ++#endif ++ + if (!optval && !optlen) { + xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL); + xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL); +diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c +index fa856a07e40b..5d9f25cb6426 100644 +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -121,22 +121,17 @@ static inline int verify_replay(struct xfrm_usersa_info *p, + struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL]; + struct xfrm_replay_state_esn *rs; + +- if (p->flags & XFRM_STATE_ESN) { +- if (!rt) +- return -EINVAL; ++ if (!rt) ++ return (p->flags & XFRM_STATE_ESN) ? -EINVAL : 0; + +- rs = nla_data(rt); ++ rs = nla_data(rt); + +- if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8) +- return -EINVAL; +- +- if (nla_len(rt) < xfrm_replay_state_esn_len(rs) && +- nla_len(rt) != sizeof(*rs)) +- return -EINVAL; +- } ++ if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8) ++ return -EINVAL; + +- if (!rt) +- return 0; ++ if (nla_len(rt) < xfrm_replay_state_esn_len(rs) && ++ nla_len(rt) != sizeof(*rs)) ++ return -EINVAL; + + /* As only ESP and AH support ESN feature. */ + if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH)) +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index 4c7db967b7bb..4f690ab0feed 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -333,18 +333,6 @@ static void superblock_free_security(struct super_block *sb) + kfree(sbsec); + } + +-/* The file system's label must be initialized prior to use. */ +- +-static const char *labeling_behaviors[7] = { +- "uses xattr", +- "uses transition SIDs", +- "uses task SIDs", +- "uses genfs_contexts", +- "not configured for labeling", +- "uses mountpoint labeling", +- "uses native labeling", +-}; +- + static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); + + static inline int inode_doinit(struct inode *inode) +@@ -456,10 +444,6 @@ static int sb_finish_set_opts(struct super_block *sb) + } + } + +- if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) +- printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", +- sb->s_id, sb->s_type->name); +- + sbsec->flags |= SE_SBINITIALIZED; + if (selinux_is_sblabel_mnt(sb)) + sbsec->flags |= SBLABEL_MNT; +diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c +index db7eff3573a9..23dca68ffe25 100644 +--- a/security/selinux/ss/services.c ++++ b/security/selinux/ss/services.c +@@ -155,7 +155,7 @@ static int selinux_set_mapping(struct policydb *pol, + } + + k = 0; +- while (p_in->perms && p_in->perms[k]) { ++ while (p_in->perms[k]) { + /* An empty permission string skips ahead */ + if (!*p_in->perms[k]) { + k++; +diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c +index daa1feac66bf..6cd8aec146f2 100644 +--- a/sound/core/oss/pcm_oss.c ++++ b/sound/core/oss/pcm_oss.c +@@ -1361,7 +1361,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha + static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const char __user *buf, size_t bytes) + { + size_t xfer = 0; +- ssize_t tmp; ++ ssize_t tmp = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + + if (atomic_read(&substream->mmap_count)) +@@ -1468,7 +1468,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, + static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __user *buf, size_t bytes) + { + size_t xfer = 0; +- ssize_t tmp; ++ ssize_t tmp = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + + if (atomic_read(&substream->mmap_count)) +diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c +index 4ba64fd49759..ce2954a31238 100644 +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -3408,7 +3408,7 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, + area, + substream->runtime->dma_area, + substream->runtime->dma_addr, +- area->vm_end - area->vm_start); ++ substream->runtime->dma_bytes); + #endif /* CONFIG_X86 */ + /* mmap with fault handler */ + area->vm_ops = &snd_pcm_vm_ops_data_fault; diff --git a/patch/kernel/rk3328-default/04-patch-4.4.127-128.patch b/patch/kernel/rk3328-default/04-patch-4.4.127-128.patch new file mode 100644 index 000000000..60f95543c --- /dev/null +++ b/patch/kernel/rk3328-default/04-patch-4.4.127-128.patch @@ -0,0 +1,5370 @@ +diff --git a/Makefile b/Makefile +index 58c0390573c1..575459bb47eb 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 127 ++SUBLEVEL = 128 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arm/boot/dts/imx53-qsrb.dts b/arch/arm/boot/dts/imx53-qsrb.dts +index 96d7eede412e..036c9bd9bf75 100644 +--- a/arch/arm/boot/dts/imx53-qsrb.dts ++++ b/arch/arm/boot/dts/imx53-qsrb.dts +@@ -23,7 +23,7 @@ + imx53-qsrb { + pinctrl_pmic: pmicgrp { + fsl,pins = < +- MX53_PAD_CSI0_DAT5__GPIO5_23 0x1e4 /* IRQ */ ++ MX53_PAD_CSI0_DAT5__GPIO5_23 0x1c4 /* IRQ */ + >; + }; + }; +diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi +index 9e096d811bed..7a032dd84bb2 100644 +--- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi +@@ -88,6 +88,7 @@ + clocks = <&clks 201>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; ++ lrclk-strength = <3>; + }; + }; + +diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi +index 9430a9928199..00de37fe5f8a 100644 +--- a/arch/arm/boot/dts/ls1021a.dtsi ++++ b/arch/arm/boot/dts/ls1021a.dtsi +@@ -132,7 +132,7 @@ + }; + + esdhc: esdhc@1560000 { +- compatible = "fsl,esdhc"; ++ compatible = "fsl,ls1021a-esdhc", "fsl,esdhc"; + reg = <0x0 0x1560000 0x0 0x10000>; + interrupts = ; + clock-frequency = <0>; +diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h +index 71e473d05fcc..620dc75362e5 100644 +--- a/arch/arm/include/asm/xen/events.h ++++ b/arch/arm/include/asm/xen/events.h +@@ -16,7 +16,7 @@ static inline int xen_irqs_disabled(struct pt_regs *regs) + return raw_irqs_disabled_flags(regs->ARM_cpsr); + } + +-#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr), \ ++#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((long long*)(ptr),\ + atomic64_t, \ + counter), (val)) + +diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c +index 28c90bc372bd..78d325f3245a 100644 +--- a/arch/arm/mach-davinci/devices-da8xx.c ++++ b/arch/arm/mach-davinci/devices-da8xx.c +@@ -795,6 +795,8 @@ static struct platform_device da8xx_dsp = { + .resource = da8xx_rproc_resources, + }; + ++static bool rproc_mem_inited __initdata; ++ + #if IS_ENABLED(CONFIG_DA8XX_REMOTEPROC) + + static phys_addr_t rproc_base __initdata; +@@ -833,6 +835,8 @@ void __init da8xx_rproc_reserve_cma(void) + ret = dma_declare_contiguous(&da8xx_dsp.dev, rproc_size, rproc_base, 0); + if (ret) + pr_err("%s: dma_declare_contiguous failed %d\n", __func__, ret); ++ else ++ rproc_mem_inited = true; + } + + #else +@@ -847,6 +851,12 @@ int __init da8xx_register_rproc(void) + { + int ret; + ++ if (!rproc_mem_inited) { ++ pr_warn("%s: memory not reserved for DSP, not registering DSP device\n", ++ __func__); ++ return -ENOMEM; ++ } ++ + ret = platform_device_register(&da8xx_dsp); + if (ret) + pr_err("%s: can't register DSP device: %d\n", __func__, ret); +diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c +index 5b0f752d5507..24be631e487d 100644 +--- a/arch/arm/mach-imx/cpu.c ++++ b/arch/arm/mach-imx/cpu.c +@@ -133,6 +133,9 @@ struct device * __init imx_soc_device_init(void) + case MXC_CPU_IMX6UL: + soc_id = "i.MX6UL"; + break; ++ case MXC_CPU_IMX6ULL: ++ soc_id = "i.MX6ULL"; ++ break; + case MXC_CPU_IMX7D: + soc_id = "i.MX7D"; + break; +diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h +index a5b1af6d7441..478cd91d0885 100644 +--- a/arch/arm/mach-imx/mxc.h ++++ b/arch/arm/mach-imx/mxc.h +@@ -39,6 +39,7 @@ + #define MXC_CPU_IMX6SX 0x62 + #define MXC_CPU_IMX6Q 0x63 + #define MXC_CPU_IMX6UL 0x64 ++#define MXC_CPU_IMX6ULL 0x65 + #define MXC_CPU_IMX7D 0x72 + + #define IMX_DDR_TYPE_LPDDR2 1 +@@ -171,6 +172,11 @@ static inline bool cpu_is_imx6ul(void) + return __mxc_cpu_type == MXC_CPU_IMX6UL; + } + ++static inline bool cpu_is_imx6ull(void) ++{ ++ return __mxc_cpu_type == MXC_CPU_IMX6ULL; ++} ++ + static inline bool cpu_is_imx6q(void) + { + return __mxc_cpu_type == MXC_CPU_IMX6Q; +diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h +index 5f3ab8c1db55..f50753573989 100644 +--- a/arch/arm64/include/asm/futex.h ++++ b/arch/arm64/include/asm/futex.h +@@ -53,16 +53,16 @@ + : "memory") + + static inline int +-futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) ++futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) + { + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; +- int oparg = (encoded_op << 8) >> 20; +- int cmparg = (encoded_op << 20) >> 20; ++ int oparg = (int)(encoded_op << 8) >> 20; ++ int cmparg = (int)(encoded_op << 20) >> 20; + int oldval = 0, ret, tmp; + + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) +- oparg = 1 << oparg; ++ oparg = 1U << (oparg & 0x1f); + + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; +diff --git a/arch/mips/include/asm/kprobes.h b/arch/mips/include/asm/kprobes.h +index daba1f9a4f79..174aedce3167 100644 +--- a/arch/mips/include/asm/kprobes.h ++++ b/arch/mips/include/asm/kprobes.h +@@ -40,7 +40,8 @@ typedef union mips_instruction kprobe_opcode_t; + + #define flush_insn_slot(p) \ + do { \ +- flush_icache_range((unsigned long)p->addr, \ ++ if (p->addr) \ ++ flush_icache_range((unsigned long)p->addr, \ + (unsigned long)p->addr + \ + (MAX_INSN_SIZE * sizeof(kprobe_opcode_t))); \ + } while (0) +diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h +index 832e2167d00f..ef7c02af7522 100644 +--- a/arch/mips/include/asm/pgtable-32.h ++++ b/arch/mips/include/asm/pgtable-32.h +@@ -18,6 +18,10 @@ + + #include + ++#ifdef CONFIG_HIGHMEM ++#include ++#endif ++ + extern int temp_tlb_entry; + + /* +@@ -61,7 +65,8 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, + + #define VMALLOC_START MAP_BASE + +-#define PKMAP_BASE (0xfe000000UL) ++#define PKMAP_END ((FIXADDR_START) & ~((LAST_PKMAP << PAGE_SHIFT)-1)) ++#define PKMAP_BASE (PKMAP_END - PAGE_SIZE * LAST_PKMAP) + + #ifdef CONFIG_HIGHMEM + # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE) +diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c +index adc6911ba748..b19a3c506b1e 100644 +--- a/arch/mips/mm/pgtable-32.c ++++ b/arch/mips/mm/pgtable-32.c +@@ -51,15 +51,15 @@ void __init pagetable_init(void) + /* + * Fixed mappings: + */ +- vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; +- fixrange_init(vaddr, vaddr + FIXADDR_SIZE, pgd_base); ++ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1); ++ fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, pgd_base); + + #ifdef CONFIG_HIGHMEM + /* + * Permanent kmaps: + */ + vaddr = PKMAP_BASE; +- fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); ++ fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); + + pgd = swapper_pg_dir + __pgd_offset(vaddr); + pud = pud_offset(pgd, vaddr); +diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h +index 3140c19c448c..70b379ee6b7e 100644 +--- a/arch/powerpc/include/asm/page.h ++++ b/arch/powerpc/include/asm/page.h +@@ -132,7 +132,19 @@ extern long long virt_phys_offset; + #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) + #define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) + #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) ++ ++#ifdef CONFIG_PPC_BOOK3S_64 ++/* ++ * On hash the vmalloc and other regions alias to the kernel region when passed ++ * through __pa(), which virt_to_pfn() uses. That means virt_addr_valid() can ++ * return true for some vmalloc addresses, which is incorrect. So explicitly ++ * check that the address is in the kernel region. ++ */ ++#define virt_addr_valid(kaddr) (REGION_ID(kaddr) == KERNEL_REGION_ID && \ ++ pfn_valid(virt_to_pfn(kaddr))) ++#else + #define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) ++#endif + + /* + * On Book-E parts we need __va to parse the device tree and we can't +diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c +index 1be1092c7204..9baba9576e99 100644 +--- a/arch/powerpc/kernel/time.c ++++ b/arch/powerpc/kernel/time.c +@@ -686,12 +686,20 @@ static int __init get_freq(char *name, int cells, unsigned long *val) + static void start_cpu_decrementer(void) + { + #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) ++ unsigned int tcr; ++ + /* Clear any pending timer interrupts */ + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); + +- /* Enable decrementer interrupt */ +- mtspr(SPRN_TCR, TCR_DIE); +-#endif /* defined(CONFIG_BOOKE) || defined(CONFIG_40x) */ ++ tcr = mfspr(SPRN_TCR); ++ /* ++ * The watchdog may have already been enabled by u-boot. So leave ++ * TRC[WP] (Watchdog Period) alone. ++ */ ++ tcr &= TCR_WP_MASK; /* Clear all bits except for TCR[WP] */ ++ tcr |= TCR_DIE; /* Enable decrementer */ ++ mtspr(SPRN_TCR, tcr); ++#endif + } + + void __init generic_calibrate_decr(void) +diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c +index f2c75a1e0536..0d91baf63fed 100644 +--- a/arch/powerpc/kvm/book3s_pr_papr.c ++++ b/arch/powerpc/kvm/book3s_pr_papr.c +@@ -50,7 +50,9 @@ static int kvmppc_h_pr_enter(struct kvm_vcpu *vcpu) + pteg_addr = get_pteg_addr(vcpu, pte_index); + + mutex_lock(&vcpu->kvm->arch.hpt_mutex); +- copy_from_user(pteg, (void __user *)pteg_addr, sizeof(pteg)); ++ ret = H_FUNCTION; ++ if (copy_from_user(pteg, (void __user *)pteg_addr, sizeof(pteg))) ++ goto done; + hpte = pteg; + + ret = H_PTEG_FULL; +@@ -71,7 +73,9 @@ static int kvmppc_h_pr_enter(struct kvm_vcpu *vcpu) + hpte[0] = cpu_to_be64(kvmppc_get_gpr(vcpu, 6)); + hpte[1] = cpu_to_be64(kvmppc_get_gpr(vcpu, 7)); + pteg_addr += i * HPTE_SIZE; +- copy_to_user((void __user *)pteg_addr, hpte, HPTE_SIZE); ++ ret = H_FUNCTION; ++ if (copy_to_user((void __user *)pteg_addr, hpte, HPTE_SIZE)) ++ goto done; + kvmppc_set_gpr(vcpu, 4, pte_index | i); + ret = H_SUCCESS; + +@@ -93,7 +97,9 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu) + + pteg = get_pteg_addr(vcpu, pte_index); + mutex_lock(&vcpu->kvm->arch.hpt_mutex); +- copy_from_user(pte, (void __user *)pteg, sizeof(pte)); ++ ret = H_FUNCTION; ++ if (copy_from_user(pte, (void __user *)pteg, sizeof(pte))) ++ goto done; + pte[0] = be64_to_cpu((__force __be64)pte[0]); + pte[1] = be64_to_cpu((__force __be64)pte[1]); + +@@ -103,7 +109,9 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu) + ((flags & H_ANDCOND) && (pte[0] & avpn) != 0)) + goto done; + +- copy_to_user((void __user *)pteg, &v, sizeof(v)); ++ ret = H_FUNCTION; ++ if (copy_to_user((void __user *)pteg, &v, sizeof(v))) ++ goto done; + + rb = compute_tlbie_rb(pte[0], pte[1], pte_index); + vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false); +@@ -171,7 +179,10 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu) + } + + pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX); +- copy_from_user(pte, (void __user *)pteg, sizeof(pte)); ++ if (copy_from_user(pte, (void __user *)pteg, sizeof(pte))) { ++ ret = H_FUNCTION; ++ break; ++ } + pte[0] = be64_to_cpu((__force __be64)pte[0]); + pte[1] = be64_to_cpu((__force __be64)pte[1]); + +@@ -184,7 +195,10 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu) + tsh |= H_BULK_REMOVE_NOT_FOUND; + } else { + /* Splat the pteg in (userland) hpt */ +- copy_to_user((void __user *)pteg, &v, sizeof(v)); ++ if (copy_to_user((void __user *)pteg, &v, sizeof(v))) { ++ ret = H_FUNCTION; ++ break; ++ } + + rb = compute_tlbie_rb(pte[0], pte[1], + tsh & H_BULK_REMOVE_PTEX); +@@ -211,7 +225,9 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu) + + pteg = get_pteg_addr(vcpu, pte_index); + mutex_lock(&vcpu->kvm->arch.hpt_mutex); +- copy_from_user(pte, (void __user *)pteg, sizeof(pte)); ++ ret = H_FUNCTION; ++ if (copy_from_user(pte, (void __user *)pteg, sizeof(pte))) ++ goto done; + pte[0] = be64_to_cpu((__force __be64)pte[0]); + pte[1] = be64_to_cpu((__force __be64)pte[1]); + +@@ -234,7 +250,9 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu) + vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false); + pte[0] = (__force u64)cpu_to_be64(pte[0]); + pte[1] = (__force u64)cpu_to_be64(pte[1]); +- copy_to_user((void __user *)pteg, pte, sizeof(pte)); ++ ret = H_FUNCTION; ++ if (copy_to_user((void __user *)pteg, pte, sizeof(pte))) ++ goto done; + ret = H_SUCCESS; + + done: +diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c +index be6212ddbf06..7e42e3ec2142 100644 +--- a/arch/powerpc/platforms/cell/spufs/coredump.c ++++ b/arch/powerpc/platforms/cell/spufs/coredump.c +@@ -174,6 +174,8 @@ static int spufs_arch_write_note(struct spu_context *ctx, int i, + if (!dump_skip(cprm, + roundup(cprm->written - total + sz, 4) - cprm->written)) + goto Eio; ++ ++ rc = 0; + out: + free_page((unsigned long)buf); + return rc; +diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S +index 445657fe658c..6c553f6e791a 100644 +--- a/arch/s390/kernel/vmlinux.lds.S ++++ b/arch/s390/kernel/vmlinux.lds.S +@@ -21,8 +21,14 @@ SECTIONS + { + . = 0x00000000; + .text : { +- _text = .; /* Text and read-only data */ ++ /* Text and read-only data */ + HEAD_TEXT ++ /* ++ * E.g. perf doesn't like symbols starting at address zero, ++ * therefore skip the initial PSW and channel program located ++ * at address zero and let _text start at 0x200. ++ */ ++ _text = 0x200; + TEXT_TEXT + SCHED_TEXT + LOCK_TEXT +diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c +index 59d503866431..9cc600b2d68c 100644 +--- a/arch/sparc/kernel/ldc.c ++++ b/arch/sparc/kernel/ldc.c +@@ -1733,9 +1733,14 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size) + + lp->rcv_nxt = p->seqid; + ++ /* ++ * If this is a control-only packet, there is nothing ++ * else to do but advance the rx queue since the packet ++ * was already processed above. ++ */ + if (!(p->type & LDC_DATA)) { + new = rx_advance(lp, new); +- goto no_data; ++ break; + } + if (p->stype & (LDC_ACK | LDC_NACK)) { + err = data_ack_nack(lp, p); +diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c +index c7c4d9c51e99..eb02087650d2 100644 +--- a/arch/x86/kernel/tsc.c ++++ b/arch/x86/kernel/tsc.c +@@ -365,6 +365,8 @@ static int __init tsc_setup(char *str) + tsc_clocksource_reliable = 1; + if (!strncmp(str, "noirqtime", 9)) + no_sched_irq_time = 1; ++ if (!strcmp(str, "unstable")) ++ mark_tsc_unstable("boot parameter"); + return 1; + } + +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index 2038e5bacce6..42654375b73f 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -1386,6 +1386,7 @@ static void svm_get_segment(struct kvm_vcpu *vcpu, + */ + if (var->unusable) + var->db = 0; ++ /* This is symmetric with svm_set_segment() */ + var->dpl = to_svm(vcpu)->vmcb->save.cpl; + break; + } +@@ -1531,18 +1532,14 @@ static void svm_set_segment(struct kvm_vcpu *vcpu, + s->base = var->base; + s->limit = var->limit; + s->selector = var->selector; +- if (var->unusable) +- s->attrib = 0; +- else { +- s->attrib = (var->type & SVM_SELECTOR_TYPE_MASK); +- s->attrib |= (var->s & 1) << SVM_SELECTOR_S_SHIFT; +- s->attrib |= (var->dpl & 3) << SVM_SELECTOR_DPL_SHIFT; +- s->attrib |= (var->present & 1) << SVM_SELECTOR_P_SHIFT; +- s->attrib |= (var->avl & 1) << SVM_SELECTOR_AVL_SHIFT; +- s->attrib |= (var->l & 1) << SVM_SELECTOR_L_SHIFT; +- s->attrib |= (var->db & 1) << SVM_SELECTOR_DB_SHIFT; +- s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT; +- } ++ s->attrib = (var->type & SVM_SELECTOR_TYPE_MASK); ++ s->attrib |= (var->s & 1) << SVM_SELECTOR_S_SHIFT; ++ s->attrib |= (var->dpl & 3) << SVM_SELECTOR_DPL_SHIFT; ++ s->attrib |= ((var->present & 1) && !var->unusable) << SVM_SELECTOR_P_SHIFT; ++ s->attrib |= (var->avl & 1) << SVM_SELECTOR_AVL_SHIFT; ++ s->attrib |= (var->l & 1) << SVM_SELECTOR_L_SHIFT; ++ s->attrib |= (var->db & 1) << SVM_SELECTOR_DB_SHIFT; ++ s->attrib |= (var->g & 1) << SVM_SELECTOR_G_SHIFT; + + /* + * This is always accurate, except if SYSRET returned to a segment +@@ -1551,7 +1548,8 @@ static void svm_set_segment(struct kvm_vcpu *vcpu, + * would entail passing the CPL to userspace and back. + */ + if (seg == VCPU_SREG_SS) +- svm->vmcb->save.cpl = (s->attrib >> SVM_SELECTOR_DPL_SHIFT) & 3; ++ /* This is symmetric with svm_get_segment() */ ++ svm->vmcb->save.cpl = (var->dpl & 3); + + mark_dirty(svm->vmcb, VMCB_SEG); + } +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 46bbc69844bd..528b4352fa99 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -7657,11 +7657,13 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu, + { + unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + int cr = exit_qualification & 15; +- int reg = (exit_qualification >> 8) & 15; +- unsigned long val = kvm_register_readl(vcpu, reg); ++ int reg; ++ unsigned long val; + + switch ((exit_qualification >> 4) & 3) { + case 0: /* mov to cr */ ++ reg = (exit_qualification >> 8) & 15; ++ val = kvm_register_readl(vcpu, reg); + switch (cr) { + case 0: + if (vmcs12->cr0_guest_host_mask & +@@ -7716,6 +7718,7 @@ static bool nested_vmx_exit_handled_cr(struct kvm_vcpu *vcpu, + * lmsw can change bits 1..3 of cr0, and only set bit 0 of + * cr0. Other attempted changes are ignored, with no exit. + */ ++ val = (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f; + if (vmcs12->cr0_guest_host_mask & 0xe & + (val ^ vmcs12->cr0_read_shadow)) + return true; +diff --git a/arch/x86/lib/csum-copy_64.S b/arch/x86/lib/csum-copy_64.S +index 7e48807b2fa1..45a53dfe1859 100644 +--- a/arch/x86/lib/csum-copy_64.S ++++ b/arch/x86/lib/csum-copy_64.S +@@ -55,7 +55,7 @@ ENTRY(csum_partial_copy_generic) + movq %r12, 3*8(%rsp) + movq %r14, 4*8(%rsp) + movq %r13, 5*8(%rsp) +- movq %rbp, 6*8(%rsp) ++ movq %r15, 6*8(%rsp) + + movq %r8, (%rsp) + movq %r9, 1*8(%rsp) +@@ -74,7 +74,7 @@ ENTRY(csum_partial_copy_generic) + /* main loop. clear in 64 byte blocks */ + /* r9: zero, r8: temp2, rbx: temp1, rax: sum, rcx: saved length */ + /* r11: temp3, rdx: temp4, r12 loopcnt */ +- /* r10: temp5, rbp: temp6, r14 temp7, r13 temp8 */ ++ /* r10: temp5, r15: temp6, r14 temp7, r13 temp8 */ + .p2align 4 + .Lloop: + source +@@ -89,7 +89,7 @@ ENTRY(csum_partial_copy_generic) + source + movq 32(%rdi), %r10 + source +- movq 40(%rdi), %rbp ++ movq 40(%rdi), %r15 + source + movq 48(%rdi), %r14 + source +@@ -103,7 +103,7 @@ ENTRY(csum_partial_copy_generic) + adcq %r11, %rax + adcq %rdx, %rax + adcq %r10, %rax +- adcq %rbp, %rax ++ adcq %r15, %rax + adcq %r14, %rax + adcq %r13, %rax + +@@ -121,7 +121,7 @@ ENTRY(csum_partial_copy_generic) + dest + movq %r10, 32(%rsi) + dest +- movq %rbp, 40(%rsi) ++ movq %r15, 40(%rsi) + dest + movq %r14, 48(%rsi) + dest +@@ -203,7 +203,7 @@ ENTRY(csum_partial_copy_generic) + movq 3*8(%rsp), %r12 + movq 4*8(%rsp), %r14 + movq 5*8(%rsp), %r13 +- movq 6*8(%rsp), %rbp ++ movq 6*8(%rsp), %r15 + addq $7*8, %rsp + ret + +diff --git a/block/bio-integrity.c b/block/bio-integrity.c +index f6325d573c10..6e091ccadcd4 100644 +--- a/block/bio-integrity.c ++++ b/block/bio-integrity.c +@@ -175,6 +175,9 @@ bool bio_integrity_enabled(struct bio *bio) + if (!bio_is_rw(bio)) + return false; + ++ if (!bio_sectors(bio)) ++ return false; ++ + /* Already protected? */ + if (bio_integrity(bio)) + return false; +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 0d1af3e44efb..8649dbf06ce4 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -1252,13 +1252,13 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) + + blk_queue_bounce(q, &bio); + ++ blk_queue_split(q, &bio, q->bio_split); ++ + if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) { + bio_io_error(bio); + return BLK_QC_T_NONE; + } + +- blk_queue_split(q, &bio, q->bio_split); +- + if (!is_flush_fua && !blk_queue_nomerges(q) && + blk_attempt_plug_merge(q, bio, &request_count, &same_queue_rq)) + return BLK_QC_T_NONE; +@@ -1634,7 +1634,8 @@ static void blk_mq_exit_hctx(struct request_queue *q, + { + unsigned flush_start_tag = set->queue_depth; + +- blk_mq_tag_idle(hctx); ++ if (blk_mq_hw_queue_mapped(hctx)) ++ blk_mq_tag_idle(hctx); + + if (set->ops->exit_request) + set->ops->exit_request(set->driver_data, +diff --git a/block/partition-generic.c b/block/partition-generic.c +index 3c062699f28b..29521753fb23 100644 +--- a/block/partition-generic.c ++++ b/block/partition-generic.c +@@ -309,8 +309,10 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, + + if (info) { + struct partition_meta_info *pinfo = alloc_part_info(disk); +- if (!pinfo) ++ if (!pinfo) { ++ err = -ENOMEM; + goto out_free_stats; ++ } + memcpy(pinfo, info, sizeof(*info)); + p->info = pinfo; + } +diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c +index 84f8d4d8b6bc..09f706b7b06e 100644 +--- a/crypto/async_tx/async_pq.c ++++ b/crypto/async_tx/async_pq.c +@@ -62,9 +62,6 @@ do_async_gen_syndrome(struct dma_chan *chan, + dma_addr_t dma_dest[2]; + int src_off = 0; + +- if (submit->flags & ASYNC_TX_FENCE) +- dma_flags |= DMA_PREP_FENCE; +- + while (src_cnt > 0) { + submit->flags = flags_orig; + pq_src_cnt = min(src_cnt, dma_maxpq(dma, dma_flags)); +@@ -83,6 +80,8 @@ do_async_gen_syndrome(struct dma_chan *chan, + if (cb_fn_orig) + dma_flags |= DMA_PREP_INTERRUPT; + } ++ if (submit->flags & ASYNC_TX_FENCE) ++ dma_flags |= DMA_PREP_FENCE; + + /* Drivers force forward progress in case they can not provide + * a descriptor +diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c +index 10ce48e16ebf..d830705f8a18 100644 +--- a/drivers/acpi/acpica/evxfevnt.c ++++ b/drivers/acpi/acpica/evxfevnt.c +@@ -180,6 +180,12 @@ acpi_status acpi_enable_event(u32 event, u32 flags) + + ACPI_FUNCTION_TRACE(acpi_enable_event); + ++ /* If Hardware Reduced flag is set, there are no fixed events */ ++ ++ if (acpi_gbl_reduced_hardware) { ++ return_ACPI_STATUS(AE_OK); ++ } ++ + /* Decode the Fixed Event */ + + if (event > ACPI_EVENT_MAX) { +@@ -237,6 +243,12 @@ acpi_status acpi_disable_event(u32 event, u32 flags) + + ACPI_FUNCTION_TRACE(acpi_disable_event); + ++ /* If Hardware Reduced flag is set, there are no fixed events */ ++ ++ if (acpi_gbl_reduced_hardware) { ++ return_ACPI_STATUS(AE_OK); ++ } ++ + /* Decode the Fixed Event */ + + if (event > ACPI_EVENT_MAX) { +@@ -290,6 +302,12 @@ acpi_status acpi_clear_event(u32 event) + + ACPI_FUNCTION_TRACE(acpi_clear_event); + ++ /* If Hardware Reduced flag is set, there are no fixed events */ ++ ++ if (acpi_gbl_reduced_hardware) { ++ return_ACPI_STATUS(AE_OK); ++ } ++ + /* Decode the Fixed Event */ + + if (event > ACPI_EVENT_MAX) { +diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c +index e54bc2aa7a88..a05b3b79b987 100644 +--- a/drivers/acpi/acpica/psobject.c ++++ b/drivers/acpi/acpica/psobject.c +@@ -121,6 +121,9 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) + (u32)(aml_offset + + sizeof(struct acpi_table_header))); + ++ ACPI_ERROR((AE_INFO, ++ "Aborting disassembly, AML byte code is corrupt")); ++ + /* Dump the context surrounding the invalid opcode */ + + acpi_ut_dump_buffer(((u8 *)walk_state->parser_state. +@@ -129,6 +132,14 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) + sizeof(struct acpi_table_header) - + 16)); + acpi_os_printf(" */\n"); ++ ++ /* ++ * Just abort the disassembly, cannot continue because the ++ * parser is essentially lost. The disassembler can then ++ * randomly fail because an ill-constructed parse tree ++ * can result. ++ */ ++ return_ACPI_STATUS(AE_AML_BAD_OPCODE); + #endif + } + +@@ -293,6 +304,9 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state, + if (status == AE_CTRL_PARSE_CONTINUE) { + return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); + } ++ if (ACPI_FAILURE(status)) { ++ return_ACPI_STATUS(status); ++ } + + /* Create Op structure and append to parent's argument list */ + +diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c +index aaa761b9081c..cd2eab6aa92e 100644 +--- a/drivers/ata/libahci_platform.c ++++ b/drivers/ata/libahci_platform.c +@@ -514,8 +514,9 @@ int ahci_platform_init_host(struct platform_device *pdev, + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { +- dev_err(dev, "no irq\n"); +- return -EINVAL; ++ if (irq != -EPROBE_DEFER) ++ dev_err(dev, "no irq\n"); ++ return irq; + } + + hpriv->irq = irq; +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 3e65ae144fde..1dd16f26e77d 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -623,6 +623,9 @@ static int loop_switch(struct loop_device *lo, struct file *file) + */ + static int loop_flush(struct loop_device *lo) + { ++ /* loop not yet configured, no running thread, nothing to flush */ ++ if (lo->lo_state != Lo_bound) ++ return 0; + return loop_switch(lo, NULL); + } + +diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c +index f364fa4d24eb..f59183018280 100644 +--- a/drivers/bus/brcmstb_gisb.c ++++ b/drivers/bus/brcmstb_gisb.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (C) 2014 Broadcom Corporation ++ * Copyright (C) 2014-2017 Broadcom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as +@@ -33,8 +33,6 @@ + #define ARB_ERR_CAP_CLEAR (1 << 0) + #define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12) + #define ARB_ERR_CAP_STATUS_TEA (1 << 11) +-#define ARB_ERR_CAP_STATUS_BS_SHIFT (1 << 2) +-#define ARB_ERR_CAP_STATUS_BS_MASK 0x3c + #define ARB_ERR_CAP_STATUS_WRITE (1 << 1) + #define ARB_ERR_CAP_STATUS_VALID (1 << 0) + +@@ -43,7 +41,6 @@ enum { + ARB_ERR_CAP_CLR, + ARB_ERR_CAP_HI_ADDR, + ARB_ERR_CAP_ADDR, +- ARB_ERR_CAP_DATA, + ARB_ERR_CAP_STATUS, + ARB_ERR_CAP_MASTER, + }; +@@ -53,7 +50,6 @@ static const int gisb_offsets_bcm7038[] = { + [ARB_ERR_CAP_CLR] = 0x0c4, + [ARB_ERR_CAP_HI_ADDR] = -1, + [ARB_ERR_CAP_ADDR] = 0x0c8, +- [ARB_ERR_CAP_DATA] = 0x0cc, + [ARB_ERR_CAP_STATUS] = 0x0d0, + [ARB_ERR_CAP_MASTER] = -1, + }; +@@ -63,7 +59,6 @@ static const int gisb_offsets_bcm7400[] = { + [ARB_ERR_CAP_CLR] = 0x0c8, + [ARB_ERR_CAP_HI_ADDR] = -1, + [ARB_ERR_CAP_ADDR] = 0x0cc, +- [ARB_ERR_CAP_DATA] = 0x0d0, + [ARB_ERR_CAP_STATUS] = 0x0d4, + [ARB_ERR_CAP_MASTER] = 0x0d8, + }; +@@ -73,7 +68,6 @@ static const int gisb_offsets_bcm7435[] = { + [ARB_ERR_CAP_CLR] = 0x168, + [ARB_ERR_CAP_HI_ADDR] = -1, + [ARB_ERR_CAP_ADDR] = 0x16c, +- [ARB_ERR_CAP_DATA] = 0x170, + [ARB_ERR_CAP_STATUS] = 0x174, + [ARB_ERR_CAP_MASTER] = 0x178, + }; +@@ -83,7 +77,6 @@ static const int gisb_offsets_bcm7445[] = { + [ARB_ERR_CAP_CLR] = 0x7e4, + [ARB_ERR_CAP_HI_ADDR] = 0x7e8, + [ARB_ERR_CAP_ADDR] = 0x7ec, +- [ARB_ERR_CAP_DATA] = 0x7f0, + [ARB_ERR_CAP_STATUS] = 0x7f4, + [ARB_ERR_CAP_MASTER] = 0x7f8, + }; +@@ -105,9 +98,13 @@ static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg) + { + int offset = gdev->gisb_offsets[reg]; + +- /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */ +- if (offset == -1) +- return 1; ++ if (offset < 0) { ++ /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */ ++ if (reg == ARB_ERR_CAP_MASTER) ++ return 1; ++ else ++ return 0; ++ } + + if (gdev->big_endian) + return ioread32be(gdev->base + offset); +@@ -115,6 +112,16 @@ static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg) + return ioread32(gdev->base + offset); + } + ++static u64 gisb_read_address(struct brcmstb_gisb_arb_device *gdev) ++{ ++ u64 value; ++ ++ value = gisb_read(gdev, ARB_ERR_CAP_ADDR); ++ value |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32; ++ ++ return value; ++} ++ + static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg) + { + int offset = gdev->gisb_offsets[reg]; +@@ -123,9 +130,9 @@ static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg) + return; + + if (gdev->big_endian) +- iowrite32be(val, gdev->base + reg); ++ iowrite32be(val, gdev->base + offset); + else +- iowrite32(val, gdev->base + reg); ++ iowrite32(val, gdev->base + offset); + } + + static ssize_t gisb_arb_get_timeout(struct device *dev, +@@ -181,7 +188,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev, + const char *reason) + { + u32 cap_status; +- unsigned long arb_addr; ++ u64 arb_addr; + u32 master; + const char *m_name; + char m_fmt[11]; +@@ -193,10 +200,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev, + return 1; + + /* Read the address and master */ +- arb_addr = gisb_read(gdev, ARB_ERR_CAP_ADDR) & 0xffffffff; +-#if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT)) +- arb_addr |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32; +-#endif ++ arb_addr = gisb_read_address(gdev); + master = gisb_read(gdev, ARB_ERR_CAP_MASTER); + + m_name = brcmstb_gisb_master_to_str(gdev, master); +@@ -205,7 +209,7 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev, + m_name = m_fmt; + } + +- pr_crit("%s: %s at 0x%lx [%c %s], core: %s\n", ++ pr_crit("%s: %s at 0x%llx [%c %s], core: %s\n", + __func__, reason, arb_addr, + cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R', + cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "", +diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c +index f53e8ba2c718..83c206f0fc98 100644 +--- a/drivers/char/ipmi/ipmi_ssif.c ++++ b/drivers/char/ipmi/ipmi_ssif.c +@@ -409,6 +409,7 @@ static void start_event_fetch(struct ssif_info *ssif_info, unsigned long *flags) + msg = ipmi_alloc_smi_msg(); + if (!msg) { + ssif_info->ssif_state = SSIF_NORMAL; ++ ipmi_ssif_unlock_cond(ssif_info, flags); + return; + } + +@@ -431,6 +432,7 @@ static void start_recv_msg_fetch(struct ssif_info *ssif_info, + msg = ipmi_alloc_smi_msg(); + if (!msg) { + ssif_info->ssif_state = SSIF_NORMAL; ++ ipmi_ssif_unlock_cond(ssif_info, flags); + return; + } + +diff --git a/drivers/char/random.c b/drivers/char/random.c +index 1822472dffab..bd9fc2baa6aa 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -886,12 +886,16 @@ static void add_interrupt_bench(cycles_t start) + static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs) + { + __u32 *ptr = (__u32 *) regs; ++ unsigned int idx; + + if (regs == NULL) + return 0; +- if (f->reg_idx >= sizeof(struct pt_regs) / sizeof(__u32)) +- f->reg_idx = 0; +- return *(ptr + f->reg_idx++); ++ idx = READ_ONCE(f->reg_idx); ++ if (idx >= sizeof(struct pt_regs) / sizeof(__u32)) ++ idx = 0; ++ ptr += idx++; ++ WRITE_ONCE(f->reg_idx, idx); ++ return *ptr; + } + + void add_interrupt_randomness(int irq, int irq_flags) +diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c +index 43a218f35b19..4ad32ce428cf 100644 +--- a/drivers/clk/clk-conf.c ++++ b/drivers/clk/clk-conf.c +@@ -106,7 +106,7 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) + + rc = clk_set_rate(clk, rate); + if (rc < 0) +- pr_err("clk: couldn't set %s clk rate to %d (%d), current rate: %ld\n", ++ pr_err("clk: couldn't set %s clk rate to %u (%d), current rate: %lu\n", + __clk_get_name(clk), rate, rc, + clk_get_rate(clk)); + clk_put(clk); +diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c +index cd0f2726f5e0..c40445488d3a 100644 +--- a/drivers/clk/clk-scpi.c ++++ b/drivers/clk/clk-scpi.c +@@ -71,15 +71,15 @@ static const struct clk_ops scpi_clk_ops = { + }; + + /* find closest match to given frequency in OPP table */ +-static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate) ++static long __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate) + { + int idx; +- u32 fmin = 0, fmax = ~0, ftmp; ++ unsigned long fmin = 0, fmax = ~0, ftmp; + const struct scpi_opp *opp = clk->info->opps; + + for (idx = 0; idx < clk->info->count; idx++, opp++) { + ftmp = opp->freq; +- if (ftmp >= (u32)rate) { ++ if (ftmp >= rate) { + if (ftmp <= fmax) + fmax = ftmp; + break; +diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c +index a5c111b67f37..ea11a33e7fff 100644 +--- a/drivers/cpuidle/dt_idle_states.c ++++ b/drivers/cpuidle/dt_idle_states.c +@@ -174,8 +174,10 @@ int dt_init_idle_driver(struct cpuidle_driver *drv, + if (!state_node) + break; + +- if (!of_device_is_available(state_node)) ++ if (!of_device_is_available(state_node)) { ++ of_node_put(state_node); + continue; ++ } + + if (!idle_state_valid(state_node, i, cpumask)) { + pr_warn("%s idle state not valid, bailing out\n", +diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c +index f8d740a6740d..48d4dddf4941 100644 +--- a/drivers/dma/imx-sdma.c ++++ b/drivers/dma/imx-sdma.c +@@ -1722,17 +1722,24 @@ static int sdma_probe(struct platform_device *pdev) + if (IS_ERR(sdma->clk_ahb)) + return PTR_ERR(sdma->clk_ahb); + +- clk_prepare(sdma->clk_ipg); +- clk_prepare(sdma->clk_ahb); ++ ret = clk_prepare(sdma->clk_ipg); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare(sdma->clk_ahb); ++ if (ret) ++ goto err_clk; + + ret = devm_request_irq(&pdev->dev, irq, sdma_int_handler, 0, "sdma", + sdma); + if (ret) +- return ret; ++ goto err_irq; + + sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL); +- if (!sdma->script_addrs) +- return -ENOMEM; ++ if (!sdma->script_addrs) { ++ ret = -ENOMEM; ++ goto err_irq; ++ } + + /* initially no scripts available */ + saddr_arr = (s32 *)sdma->script_addrs; +@@ -1847,6 +1854,10 @@ err_register: + dma_async_device_unregister(&sdma->dma_device); + err_init: + kfree(sdma->script_addrs); ++err_irq: ++ clk_unprepare(sdma->clk_ahb); ++err_clk: ++ clk_unprepare(sdma->clk_ipg); + return ret; + } + +@@ -1857,6 +1868,8 @@ static int sdma_remove(struct platform_device *pdev) + + dma_async_device_unregister(&sdma->dma_device); + kfree(sdma->script_addrs); ++ clk_unprepare(sdma->clk_ahb); ++ clk_unprepare(sdma->clk_ipg); + /* Kill the tasklet */ + for (i = 0; i < MAX_DMA_CHANNELS; i++) { + struct sdma_channel *sdmac = &sdma->channel[i]; +diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c +index 0574e1bbe45c..3ce5609b4611 100644 +--- a/drivers/edac/mv64x60_edac.c ++++ b/drivers/edac/mv64x60_edac.c +@@ -763,7 +763,7 @@ static int mv64x60_mc_err_probe(struct platform_device *pdev) + /* Non-ECC RAM? */ + printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__); + res = -ENODEV; +- goto err2; ++ goto err; + } + + edac_dbg(3, "init mci\n"); +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 06d345b087f8..759a39906a52 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -2145,7 +2145,8 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, + return desc; + } + +- status = gpiod_request(desc, con_id); ++ /* If a connection label was passed use that, else use the device name as label */ ++ status = gpiod_request(desc, con_id ? con_id : dev_name(dev)); + if (status < 0) + return ERR_PTR(status); + +diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c +index 7ed08fdc4c42..393e5335e33b 100644 +--- a/drivers/gpu/drm/omapdrm/omap_gem.c ++++ b/drivers/gpu/drm/omapdrm/omap_gem.c +@@ -158,7 +158,7 @@ static void evict_entry(struct drm_gem_object *obj, + size_t size = PAGE_SIZE * n; + loff_t off = mmap_offset(obj) + + (entry->obj_pgoff << PAGE_SHIFT); +- const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE); ++ const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE); + + if (m > 1) { + int i; +@@ -415,7 +415,7 @@ static int fault_2d(struct drm_gem_object *obj, + * into account in some of the math, so figure out virtual stride + * in pages + */ +- const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE); ++ const int m = DIV_ROUND_UP(omap_obj->width << fmt, PAGE_SIZE); + + /* We don't use vmf->pgoff since that has the fake offset: */ + pgoff = ((unsigned long)vmf->virtual_address - +diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c +index b24f1d3045f0..a629f7c130f0 100644 +--- a/drivers/hwmon/ina2xx.c ++++ b/drivers/hwmon/ina2xx.c +@@ -94,18 +94,20 @@ enum ina2xx_ids { ina219, ina226 }; + + struct ina2xx_config { + u16 config_default; +- int calibration_factor; ++ int calibration_value; + int registers; + int shunt_div; + int bus_voltage_shift; + int bus_voltage_lsb; /* uV */ +- int power_lsb; /* uW */ ++ int power_lsb_factor; + }; + + struct ina2xx_data { + const struct ina2xx_config *config; + + long rshunt; ++ long current_lsb_uA; ++ long power_lsb_uW; + struct mutex config_lock; + struct regmap *regmap; + +@@ -115,21 +117,21 @@ struct ina2xx_data { + static const struct ina2xx_config ina2xx_config[] = { + [ina219] = { + .config_default = INA219_CONFIG_DEFAULT, +- .calibration_factor = 40960000, ++ .calibration_value = 4096, + .registers = INA219_REGISTERS, + .shunt_div = 100, + .bus_voltage_shift = 3, + .bus_voltage_lsb = 4000, +- .power_lsb = 20000, ++ .power_lsb_factor = 20, + }, + [ina226] = { + .config_default = INA226_CONFIG_DEFAULT, +- .calibration_factor = 5120000, ++ .calibration_value = 2048, + .registers = INA226_REGISTERS, + .shunt_div = 400, + .bus_voltage_shift = 0, + .bus_voltage_lsb = 1250, +- .power_lsb = 25000, ++ .power_lsb_factor = 25, + }, + }; + +@@ -168,12 +170,16 @@ static u16 ina226_interval_to_reg(int interval) + return INA226_SHIFT_AVG(avg_bits); + } + ++/* ++ * Calibration register is set to the best value, which eliminates ++ * truncation errors on calculating current register in hardware. ++ * According to datasheet (eq. 3) the best values are 2048 for ++ * ina226 and 4096 for ina219. They are hardcoded as calibration_value. ++ */ + static int ina2xx_calibrate(struct ina2xx_data *data) + { +- u16 val = DIV_ROUND_CLOSEST(data->config->calibration_factor, +- data->rshunt); +- +- return regmap_write(data->regmap, INA2XX_CALIBRATION, val); ++ return regmap_write(data->regmap, INA2XX_CALIBRATION, ++ data->config->calibration_value); + } + + /* +@@ -186,10 +192,6 @@ static int ina2xx_init(struct ina2xx_data *data) + if (ret < 0) + return ret; + +- /* +- * Set current LSB to 1mA, shunt is in uOhms +- * (equation 13 in datasheet). +- */ + return ina2xx_calibrate(data); + } + +@@ -267,15 +269,15 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg, + val = DIV_ROUND_CLOSEST(val, 1000); + break; + case INA2XX_POWER: +- val = regval * data->config->power_lsb; ++ val = regval * data->power_lsb_uW; + break; + case INA2XX_CURRENT: +- /* signed register, LSB=1mA (selected), in mA */ +- val = (s16)regval; ++ /* signed register, result in mA */ ++ val = regval * data->current_lsb_uA; ++ val = DIV_ROUND_CLOSEST(val, 1000); + break; + case INA2XX_CALIBRATION: +- val = DIV_ROUND_CLOSEST(data->config->calibration_factor, +- regval); ++ val = regval; + break; + default: + /* programmer goofed */ +@@ -303,9 +305,32 @@ static ssize_t ina2xx_show_value(struct device *dev, + ina2xx_get_value(data, attr->index, regval)); + } + +-static ssize_t ina2xx_set_shunt(struct device *dev, +- struct device_attribute *da, +- const char *buf, size_t count) ++/* ++ * In order to keep calibration register value fixed, the product ++ * of current_lsb and shunt_resistor should also be fixed and equal ++ * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order ++ * to keep the scale. ++ */ ++static int ina2xx_set_shunt(struct ina2xx_data *data, long val) ++{ ++ unsigned int dividend = DIV_ROUND_CLOSEST(1000000000, ++ data->config->shunt_div); ++ if (val <= 0 || val > dividend) ++ return -EINVAL; ++ ++ mutex_lock(&data->config_lock); ++ data->rshunt = val; ++ data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val); ++ data->power_lsb_uW = data->config->power_lsb_factor * ++ data->current_lsb_uA; ++ mutex_unlock(&data->config_lock); ++ ++ return 0; ++} ++ ++static ssize_t ina2xx_store_shunt(struct device *dev, ++ struct device_attribute *da, ++ const char *buf, size_t count) + { + unsigned long val; + int status; +@@ -315,18 +340,9 @@ static ssize_t ina2xx_set_shunt(struct device *dev, + if (status < 0) + return status; + +- if (val == 0 || +- /* Values greater than the calibration factor make no sense. */ +- val > data->config->calibration_factor) +- return -EINVAL; +- +- mutex_lock(&data->config_lock); +- data->rshunt = val; +- status = ina2xx_calibrate(data); +- mutex_unlock(&data->config_lock); ++ status = ina2xx_set_shunt(data, val); + if (status < 0) + return status; +- + return count; + } + +@@ -386,7 +402,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina2xx_show_value, NULL, + + /* shunt resistance */ + static SENSOR_DEVICE_ATTR(shunt_resistor, S_IRUGO | S_IWUSR, +- ina2xx_show_value, ina2xx_set_shunt, ++ ina2xx_show_value, ina2xx_store_shunt, + INA2XX_CALIBRATION); + + /* update interval (ina226 only) */ +@@ -441,10 +457,7 @@ static int ina2xx_probe(struct i2c_client *client, + val = INA2XX_RSHUNT_DEFAULT; + } + +- if (val <= 0 || val > data->config->calibration_factor) +- return -ENODEV; +- +- data->rshunt = val; ++ ina2xx_set_shunt(data, val); + + ina2xx_regmap_config.max_register = data->config->registers; + +diff --git a/drivers/iio/adc/hi8435.c b/drivers/iio/adc/hi8435.c +index c73c6c62a6ac..7401f102dff4 100644 +--- a/drivers/iio/adc/hi8435.c ++++ b/drivers/iio/adc/hi8435.c +@@ -121,10 +121,21 @@ static int hi8435_write_event_config(struct iio_dev *idev, + enum iio_event_direction dir, int state) + { + struct hi8435_priv *priv = iio_priv(idev); ++ int ret; ++ u32 tmp; ++ ++ if (state) { ++ ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp); ++ if (ret < 0) ++ return ret; ++ if (tmp & BIT(chan->channel)) ++ priv->event_prev_val |= BIT(chan->channel); ++ else ++ priv->event_prev_val &= ~BIT(chan->channel); + +- priv->event_scan_mask &= ~BIT(chan->channel); +- if (state) + priv->event_scan_mask |= BIT(chan->channel); ++ } else ++ priv->event_scan_mask &= ~BIT(chan->channel); + + return 0; + } +@@ -442,13 +453,15 @@ static int hi8435_probe(struct spi_device *spi) + priv->spi = spi; + + reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW); +- if (IS_ERR(reset_gpio)) { +- /* chip s/w reset if h/w reset failed */ ++ if (!IS_ERR(reset_gpio)) { ++ /* need >=100ns low pulse to reset chip */ ++ gpiod_set_raw_value_cansleep(reset_gpio, 0); ++ udelay(1); ++ gpiod_set_raw_value_cansleep(reset_gpio, 1); ++ } else { ++ /* s/w reset chip if h/w reset is not available */ + hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST); + hi8435_writeb(priv, HI8435_CTRL_REG, 0); +- } else { +- udelay(5); +- gpiod_set_value(reset_gpio, 1); + } + + spi_set_drvdata(spi, idev); +diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c +index 6325e7dc8e03..f3cb4dc05391 100644 +--- a/drivers/iio/magnetometer/st_magn_spi.c ++++ b/drivers/iio/magnetometer/st_magn_spi.c +@@ -48,8 +48,6 @@ static int st_magn_spi_remove(struct spi_device *spi) + } + + static const struct spi_device_id st_magn_id_table[] = { +- { LSM303DLHC_MAGN_DEV_NAME }, +- { LSM303DLM_MAGN_DEV_NAME }, + { LIS3MDL_MAGN_DEV_NAME }, + { LSM303AGR_MAGN_DEV_NAME }, + {}, +diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c +index a73874508c3a..cb3a8623ff54 100644 +--- a/drivers/infiniband/ulp/srpt/ib_srpt.c ++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c +@@ -2974,12 +2974,8 @@ static void srpt_queue_response(struct se_cmd *cmd) + } + spin_unlock_irqrestore(&ioctx->spinlock, flags); + +- if (unlikely(transport_check_aborted_status(&ioctx->cmd, false) +- || WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) { +- atomic_inc(&ch->req_lim_delta); +- srpt_abort_cmd(ioctx); ++ if (unlikely(WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) + return; +- } + + dir = ioctx->cmd.data_direction; + +diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c +index c9d491bc85e0..3851d5715772 100644 +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -1082,6 +1082,13 @@ static int elan_probe(struct i2c_client *client, + return error; + } + ++ /* Make sure there is something at this address */ ++ error = i2c_smbus_read_byte(client); ++ if (error < 0) { ++ dev_dbg(&client->dev, "nothing at this address: %d\n", error); ++ return -ENXIO; ++ } ++ + /* Initialize the touchpad. */ + error = elan_initialize(data); + if (error) +diff --git a/drivers/input/mouse/elan_i2c_i2c.c b/drivers/input/mouse/elan_i2c_i2c.c +index a679e56c44cd..765879dcaf85 100644 +--- a/drivers/input/mouse/elan_i2c_i2c.c ++++ b/drivers/input/mouse/elan_i2c_i2c.c +@@ -557,7 +557,14 @@ static int elan_i2c_finish_fw_update(struct i2c_client *client, + long ret; + int error; + int len; +- u8 buffer[ETP_I2C_INF_LENGTH]; ++ u8 buffer[ETP_I2C_REPORT_LEN]; ++ ++ len = i2c_master_recv(client, buffer, ETP_I2C_REPORT_LEN); ++ if (len != ETP_I2C_REPORT_LEN) { ++ error = len < 0 ? len : -EIO; ++ dev_warn(dev, "failed to read I2C data after FW WDT reset: %d (%d)\n", ++ error, len); ++ } + + reinit_completion(completion); + enable_irq(client->irq); +diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c +index 51b96e9bf793..06ea28e5d7b4 100644 +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1715,6 +1715,17 @@ int elantech_init(struct psmouse *psmouse) + etd->samples[0], etd->samples[1], etd->samples[2]); + } + ++ if (etd->samples[1] == 0x74 && etd->hw_version == 0x03) { ++ /* ++ * This module has a bug which makes absolute mode ++ * unusable, so let's abort so we'll be using standard ++ * PS/2 protocol. ++ */ ++ psmouse_info(psmouse, ++ "absolute mode broken, forcing standard PS/2 protocol\n"); ++ goto init_fail; ++ } ++ + if (elantech_set_absolute_mode(psmouse)) { + psmouse_err(psmouse, + "failed to put touchpad into absolute mode.\n"); +diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c +index 9cb4b621fbc3..b92a19a594a1 100644 +--- a/drivers/isdn/mISDN/stack.c ++++ b/drivers/isdn/mISDN/stack.c +@@ -72,7 +72,7 @@ send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb) + if (sk->sk_state != MISDN_BOUND) + continue; + if (!cskb) +- cskb = skb_copy(skb, GFP_KERNEL); ++ cskb = skb_copy(skb, GFP_ATOMIC); + if (!cskb) { + printk(KERN_WARNING "%s no skb\n", __func__); + break; +diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c +index b775e1efecd3..b9f71a87b7e1 100644 +--- a/drivers/leds/leds-pca955x.c ++++ b/drivers/leds/leds-pca955x.c +@@ -281,7 +281,7 @@ static int pca955x_probe(struct i2c_client *client, + "slave address 0x%02x\n", + id->name, chip->bits, client->addr); + +- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) ++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -EIO; + + if (pdata) { +diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c +index 4d46f2ce606f..aa84fcfd59fc 100644 +--- a/drivers/md/bcache/alloc.c ++++ b/drivers/md/bcache/alloc.c +@@ -514,15 +514,21 @@ struct open_bucket { + + /* + * We keep multiple buckets open for writes, and try to segregate different +- * write streams for better cache utilization: first we look for a bucket where +- * the last write to it was sequential with the current write, and failing that +- * we look for a bucket that was last used by the same task. ++ * write streams for better cache utilization: first we try to segregate flash ++ * only volume write streams from cached devices, secondly we look for a bucket ++ * where the last write to it was sequential with the current write, and ++ * failing that we look for a bucket that was last used by the same task. + * + * The ideas is if you've got multiple tasks pulling data into the cache at the + * same time, you'll get better cache utilization if you try to segregate their + * data and preserve locality. + * +- * For example, say you've starting Firefox at the same time you're copying a ++ * For example, dirty sectors of flash only volume is not reclaimable, if their ++ * dirty sectors mixed with dirty sectors of cached device, such buckets will ++ * be marked as dirty and won't be reclaimed, though the dirty data of cached ++ * device have been written back to backend device. ++ * ++ * And say you've starting Firefox at the same time you're copying a + * bunch of files. Firefox will likely end up being fairly hot and stay in the + * cache awhile, but the data you copied might not be; if you wrote all that + * data to the same buckets it'd get invalidated at the same time. +@@ -539,7 +545,10 @@ static struct open_bucket *pick_data_bucket(struct cache_set *c, + struct open_bucket *ret, *ret_task = NULL; + + list_for_each_entry_reverse(ret, &c->data_buckets, list) +- if (!bkey_cmp(&ret->key, search)) ++ if (UUID_FLASH_ONLY(&c->uuids[KEY_INODE(&ret->key)]) != ++ UUID_FLASH_ONLY(&c->uuids[KEY_INODE(search)])) ++ continue; ++ else if (!bkey_cmp(&ret->key, search)) + goto found; + else if (ret->last_write_point == write_point) + ret_task = ret; +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index be8307550bd7..f636af441da6 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -890,6 +890,12 @@ static void cached_dev_detach_finish(struct work_struct *w) + + mutex_lock(&bch_register_lock); + ++ cancel_delayed_work_sync(&dc->writeback_rate_update); ++ if (!IS_ERR_OR_NULL(dc->writeback_thread)) { ++ kthread_stop(dc->writeback_thread); ++ dc->writeback_thread = NULL; ++ } ++ + memset(&dc->sb.set_uuid, 0, 16); + SET_BDEV_STATE(&dc->sb, BDEV_STATE_NONE); + +diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c +index 494d01d0e92a..a7a561af05c9 100644 +--- a/drivers/md/md-cluster.c ++++ b/drivers/md/md-cluster.c +@@ -945,8 +945,10 @@ static int add_new_disk(struct mddev *mddev, struct md_rdev *rdev) + cmsg.raid_slot = cpu_to_le32(rdev->desc_nr); + lock_comm(cinfo); + ret = __sendmsg(cinfo, &cmsg); +- if (ret) ++ if (ret) { ++ unlock_comm(cinfo); + return ret; ++ } + cinfo->no_new_dev_lockres->flags |= DLM_LKF_NOQUEUE; + ret = dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_EX); + cinfo->no_new_dev_lockres->flags &= ~DLM_LKF_NOQUEUE; +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index ca968c3f25c7..e2130fb4597d 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -110,8 +110,7 @@ static inline void unlock_device_hash_lock(struct r5conf *conf, int hash) + static inline void lock_all_device_hash_locks_irq(struct r5conf *conf) + { + int i; +- local_irq_disable(); +- spin_lock(conf->hash_locks); ++ spin_lock_irq(conf->hash_locks); + for (i = 1; i < NR_STRIPE_HASH_LOCKS; i++) + spin_lock_nest_lock(conf->hash_locks + i, conf->hash_locks); + spin_lock(&conf->device_lock); +@@ -121,9 +120,9 @@ static inline void unlock_all_device_hash_locks_irq(struct r5conf *conf) + { + int i; + spin_unlock(&conf->device_lock); +- for (i = NR_STRIPE_HASH_LOCKS; i; i--) +- spin_unlock(conf->hash_locks + i - 1); +- local_irq_enable(); ++ for (i = NR_STRIPE_HASH_LOCKS - 1; i; i--) ++ spin_unlock(conf->hash_locks + i); ++ spin_unlock_irq(conf->hash_locks); + } + + /* bio's attached to a stripe+device for I/O are linked together in bi_sector +@@ -726,12 +725,11 @@ static bool is_full_stripe_write(struct stripe_head *sh) + + static void lock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2) + { +- local_irq_disable(); + if (sh1 > sh2) { +- spin_lock(&sh2->stripe_lock); ++ spin_lock_irq(&sh2->stripe_lock); + spin_lock_nested(&sh1->stripe_lock, 1); + } else { +- spin_lock(&sh1->stripe_lock); ++ spin_lock_irq(&sh1->stripe_lock); + spin_lock_nested(&sh2->stripe_lock, 1); + } + } +@@ -739,8 +737,7 @@ static void lock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2) + static void unlock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2) + { + spin_unlock(&sh1->stripe_lock); +- spin_unlock(&sh2->stripe_lock); +- local_irq_enable(); ++ spin_unlock_irq(&sh2->stripe_lock); + } + + /* Only freshly new full stripe normal write stripe can be added to a batch list */ +diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c +index fe6eb78b6914..a47ab1947cc4 100644 +--- a/drivers/media/i2c/cx25840/cx25840-core.c ++++ b/drivers/media/i2c/cx25840/cx25840-core.c +@@ -420,11 +420,13 @@ static void cx25840_initialize(struct i2c_client *client) + INIT_WORK(&state->fw_work, cx25840_work_handler); + init_waitqueue_head(&state->fw_wait); + q = create_singlethread_workqueue("cx25840_fw"); +- prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); +- queue_work(q, &state->fw_work); +- schedule(); +- finish_wait(&state->fw_wait, &wait); +- destroy_workqueue(q); ++ if (q) { ++ prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); ++ queue_work(q, &state->fw_work); ++ schedule(); ++ finish_wait(&state->fw_wait, &wait); ++ destroy_workqueue(q); ++ } + + /* 6. */ + cx25840_write(client, 0x115, 0x8c); +@@ -631,11 +633,13 @@ static void cx23885_initialize(struct i2c_client *client) + INIT_WORK(&state->fw_work, cx25840_work_handler); + init_waitqueue_head(&state->fw_wait); + q = create_singlethread_workqueue("cx25840_fw"); +- prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); +- queue_work(q, &state->fw_work); +- schedule(); +- finish_wait(&state->fw_wait, &wait); +- destroy_workqueue(q); ++ if (q) { ++ prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); ++ queue_work(q, &state->fw_work); ++ schedule(); ++ finish_wait(&state->fw_wait, &wait); ++ destroy_workqueue(q); ++ } + + /* Call the cx23888 specific std setup func, we no longer rely on + * the generic cx24840 func. +@@ -746,11 +750,13 @@ static void cx231xx_initialize(struct i2c_client *client) + INIT_WORK(&state->fw_work, cx25840_work_handler); + init_waitqueue_head(&state->fw_wait); + q = create_singlethread_workqueue("cx25840_fw"); +- prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); +- queue_work(q, &state->fw_work); +- schedule(); +- finish_wait(&state->fw_wait, &wait); +- destroy_workqueue(q); ++ if (q) { ++ prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); ++ queue_work(q, &state->fw_work); ++ schedule(); ++ finish_wait(&state->fw_wait, &wait); ++ destroy_workqueue(q); ++ } + + cx25840_std_setup(client); + +diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c +index f838d9c7ed12..0fba4a2c1602 100644 +--- a/drivers/media/rc/mceusb.c ++++ b/drivers/media/rc/mceusb.c +@@ -1370,8 +1370,13 @@ static int mceusb_dev_probe(struct usb_interface *intf, + goto rc_dev_fail; + + /* wire up inbound data handler */ +- usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp, +- mceusb_dev_recv, ir, ep_in->bInterval); ++ if (usb_endpoint_xfer_int(ep_in)) ++ usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp, ++ mceusb_dev_recv, ir, ep_in->bInterval); ++ else ++ usb_fill_bulk_urb(ir->urb_in, dev, pipe, ir->buf_in, maxp, ++ mceusb_dev_recv, ir); ++ + ir->urb_in->transfer_dma = ir->dma_in; + ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + +diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c +index 3dc9ed2e0774..bb1e19f7ed5a 100644 +--- a/drivers/media/v4l2-core/videobuf2-core.c ++++ b/drivers/media/v4l2-core/videobuf2-core.c +@@ -205,6 +205,10 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, + struct vb2_buffer *vb; + int ret; + ++ /* Ensure that q->num_buffers+num_buffers is below VB2_MAX_FRAME */ ++ num_buffers = min_t(unsigned int, num_buffers, ++ VB2_MAX_FRAME - q->num_buffers); ++ + for (buffer = 0; buffer < num_buffers; ++buffer) { + /* Allocate videobuf buffer structures */ + vb = kzalloc(q->buf_struct_size, GFP_KERNEL); +diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c +index f42d9c4e4561..cc277f7849b0 100644 +--- a/drivers/misc/vmw_vmci/vmci_queue_pair.c ++++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c +@@ -298,8 +298,11 @@ static void *qp_alloc_queue(u64 size, u32 flags) + size_t pas_size; + size_t vas_size; + size_t queue_size = sizeof(*queue) + sizeof(*queue->kernel_if); +- const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; ++ u64 num_pages; + ++ if (size > SIZE_MAX - PAGE_SIZE) ++ return NULL; ++ num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; + if (num_pages > + (SIZE_MAX - queue_size) / + (sizeof(*queue->kernel_if->u.g.pas) + +@@ -624,9 +627,12 @@ static struct vmci_queue *qp_host_alloc_queue(u64 size) + { + struct vmci_queue *queue; + size_t queue_page_size; +- const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; ++ u64 num_pages; + const size_t queue_size = sizeof(*queue) + sizeof(*(queue->kernel_if)); + ++ if (size > SIZE_MAX - PAGE_SIZE) ++ return NULL; ++ num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; + if (num_pages > (SIZE_MAX - queue_size) / + sizeof(*queue->kernel_if->u.h.page)) + return NULL; +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index eadccf498589..278d12888cab 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1490,39 +1490,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) + goto err_close; + } + +- /* If the mode uses primary, then the following is handled by +- * bond_change_active_slave(). +- */ +- if (!bond_uses_primary(bond)) { +- /* set promiscuity level to new slave */ +- if (bond_dev->flags & IFF_PROMISC) { +- res = dev_set_promiscuity(slave_dev, 1); +- if (res) +- goto err_close; +- } +- +- /* set allmulti level to new slave */ +- if (bond_dev->flags & IFF_ALLMULTI) { +- res = dev_set_allmulti(slave_dev, 1); +- if (res) +- goto err_close; +- } +- +- netif_addr_lock_bh(bond_dev); +- +- dev_mc_sync_multiple(slave_dev, bond_dev); +- dev_uc_sync_multiple(slave_dev, bond_dev); +- +- netif_addr_unlock_bh(bond_dev); +- } +- +- if (BOND_MODE(bond) == BOND_MODE_8023AD) { +- /* add lacpdu mc addr to mc list */ +- u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR; +- +- dev_mc_add(slave_dev, lacpdu_multicast); +- } +- + res = vlan_vids_add_by_dev(slave_dev, bond_dev); + if (res) { + netdev_err(bond_dev, "Couldn't add bond vlan ids to %s\n", +@@ -1679,6 +1646,40 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) + goto err_upper_unlink; + } + ++ /* If the mode uses primary, then the following is handled by ++ * bond_change_active_slave(). ++ */ ++ if (!bond_uses_primary(bond)) { ++ /* set promiscuity level to new slave */ ++ if (bond_dev->flags & IFF_PROMISC) { ++ res = dev_set_promiscuity(slave_dev, 1); ++ if (res) ++ goto err_sysfs_del; ++ } ++ ++ /* set allmulti level to new slave */ ++ if (bond_dev->flags & IFF_ALLMULTI) { ++ res = dev_set_allmulti(slave_dev, 1); ++ if (res) { ++ if (bond_dev->flags & IFF_PROMISC) ++ dev_set_promiscuity(slave_dev, -1); ++ goto err_sysfs_del; ++ } ++ } ++ ++ netif_addr_lock_bh(bond_dev); ++ dev_mc_sync_multiple(slave_dev, bond_dev); ++ dev_uc_sync_multiple(slave_dev, bond_dev); ++ netif_addr_unlock_bh(bond_dev); ++ ++ if (BOND_MODE(bond) == BOND_MODE_8023AD) { ++ /* add lacpdu mc addr to mc list */ ++ u8 lacpdu_multicast[ETH_ALEN] = MULTICAST_LACPDU_ADDR; ++ ++ dev_mc_add(slave_dev, lacpdu_multicast); ++ } ++ } ++ + bond->slave_cnt++; + bond_compute_features(bond); + bond_set_carrier(bond); +@@ -1702,6 +1703,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) + return 0; + + /* Undo stages on error */ ++err_sysfs_del: ++ bond_sysfs_slave_del(new_slave); ++ + err_upper_unlink: + bond_upper_dev_unlink(bond_dev, slave_dev); + +@@ -1709,9 +1713,6 @@ err_unregister: + netdev_rx_handler_unregister(slave_dev); + + err_detach: +- if (!bond_uses_primary(bond)) +- bond_hw_addr_flush(bond_dev, slave_dev); +- + vlan_vids_del_by_dev(slave_dev, bond_dev); + if (rcu_access_pointer(bond->primary_slave) == new_slave) + RCU_INIT_POINTER(bond->primary_slave, NULL); +@@ -2555,11 +2556,13 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) + bond_for_each_slave_rcu(bond, slave, iter) { + unsigned long trans_start = dev_trans_start(slave->dev); + ++ slave->new_link = BOND_LINK_NOCHANGE; ++ + if (slave->link != BOND_LINK_UP) { + if (bond_time_in_interval(bond, trans_start, 1) && + bond_time_in_interval(bond, slave->last_rx, 1)) { + +- slave->link = BOND_LINK_UP; ++ slave->new_link = BOND_LINK_UP; + slave_state_changed = 1; + + /* primary_slave has no meaning in round-robin +@@ -2586,7 +2589,7 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) + if (!bond_time_in_interval(bond, trans_start, 2) || + !bond_time_in_interval(bond, slave->last_rx, 2)) { + +- slave->link = BOND_LINK_DOWN; ++ slave->new_link = BOND_LINK_DOWN; + slave_state_changed = 1; + + if (slave->link_failure_count < UINT_MAX) +@@ -2617,6 +2620,11 @@ static void bond_loadbalance_arp_mon(struct work_struct *work) + if (!rtnl_trylock()) + goto re_arm; + ++ bond_for_each_slave(bond, slave, iter) { ++ if (slave->new_link != BOND_LINK_NOCHANGE) ++ slave->link = slave->new_link; ++ } ++ + if (slave_state_changed) { + bond_slave_state_change(bond); + if (BOND_MODE(bond) == BOND_MODE_XOR) +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +index d1103d612d8b..949a82458a29 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -3943,15 +3943,26 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) + /* when transmitting in a vf, start bd must hold the ethertype + * for fw to enforce it + */ ++ u16 vlan_tci = 0; + #ifndef BNX2X_STOP_ON_ERROR +- if (IS_VF(bp)) ++ if (IS_VF(bp)) { + #endif +- tx_start_bd->vlan_or_ethertype = +- cpu_to_le16(ntohs(eth->h_proto)); ++ /* Still need to consider inband vlan for enforced */ ++ if (__vlan_get_tag(skb, &vlan_tci)) { ++ tx_start_bd->vlan_or_ethertype = ++ cpu_to_le16(ntohs(eth->h_proto)); ++ } else { ++ tx_start_bd->bd_flags.as_bitfield |= ++ (X_ETH_INBAND_VLAN << ++ ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); ++ tx_start_bd->vlan_or_ethertype = ++ cpu_to_le16(vlan_tci); ++ } + #ifndef BNX2X_STOP_ON_ERROR +- else ++ } else { + /* used by FW for packet accounting */ + tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); ++ } + #endif + } + +diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c +index 0f6811860ad5..a36e38676640 100644 +--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c ++++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c +@@ -2845,7 +2845,7 @@ bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver) + static void + bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer) + { +- memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); ++ strncpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); + } + + static void +diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +index cf61a5869c6e..de23f23b41de 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +@@ -6076,13 +6076,18 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, + if (!t4_fw_matches_chip(adap, fw_hdr)) + return -EINVAL; + ++ /* Disable FW_OK flag so that mbox commands with FW_OK flag set ++ * wont be sent when we are flashing FW. ++ */ ++ adap->flags &= ~FW_OK; ++ + ret = t4_fw_halt(adap, mbox, force); + if (ret < 0 && !force) +- return ret; ++ goto out; + + ret = t4_load_fw(adap, fw_data, size); + if (ret < 0) +- return ret; ++ goto out; + + /* + * Older versions of the firmware don't understand the new +@@ -6093,7 +6098,17 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, + * its header flags to see if it advertises the capability. + */ + reset = ((be32_to_cpu(fw_hdr->flags) & FW_HDR_FLAGS_RESET_HALT) == 0); +- return t4_fw_restart(adap, mbox, reset); ++ ret = t4_fw_restart(adap, mbox, reset); ++ ++ /* Grab potentially new Firmware Device Log parameters so we can see ++ * how healthy the new Firmware is. It's okay to contact the new ++ * Firmware for these parameters even though, as far as it's ++ * concerned, we've never said "HELLO" to it ... ++ */ ++ (void)t4_init_devlog_params(adap); ++out: ++ adap->flags |= FW_OK; ++ return ret; + } + + /** +@@ -7696,7 +7711,16 @@ int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr) + ret = t4_cim_read(adap, UP_UP_DBG_LA_DATA_A, 1, &la_buf[i]); + if (ret) + break; +- idx = (idx + 1) & UPDBGLARDPTR_M; ++ ++ /* Bits 0-3 of UpDbgLaRdPtr can be between 0000 to 1001 to ++ * identify the 32-bit portion of the full 312-bit data ++ */ ++ if (is_t6(adap->params.chip) && (idx & 0xf) >= 9) ++ idx = (idx & 0xff0) + 0x10; ++ else ++ idx++; ++ /* address can't exceed 0xfff */ ++ idx &= UPDBGLARDPTR_M; + } + restart: + if (cfg & UPDBGLAEN_F) { +diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +index fa3786a9d30e..ec8ffd7eae33 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c ++++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +@@ -2604,8 +2604,8 @@ void t4vf_sge_stop(struct adapter *adapter) + int t4vf_sge_init(struct adapter *adapter) + { + struct sge_params *sge_params = &adapter->params.sge; +- u32 fl0 = sge_params->sge_fl_buffer_size[0]; +- u32 fl1 = sge_params->sge_fl_buffer_size[1]; ++ u32 fl_small_pg = sge_params->sge_fl_buffer_size[0]; ++ u32 fl_large_pg = sge_params->sge_fl_buffer_size[1]; + struct sge *s = &adapter->sge; + unsigned int ingpadboundary, ingpackboundary; + +@@ -2614,9 +2614,20 @@ int t4vf_sge_init(struct adapter *adapter) + * the Physical Function Driver. Ideally we should be able to deal + * with _any_ configuration. Practice is different ... + */ +- if (fl0 != PAGE_SIZE || (fl1 != 0 && fl1 <= fl0)) { ++ ++ /* We only bother using the Large Page logic if the Large Page Buffer ++ * is larger than our Page Size Buffer. ++ */ ++ if (fl_large_pg <= fl_small_pg) ++ fl_large_pg = 0; ++ ++ /* The Page Size Buffer must be exactly equal to our Page Size and the ++ * Large Page Size Buffer should be 0 (per above) or a power of 2. ++ */ ++ if (fl_small_pg != PAGE_SIZE || ++ (fl_large_pg & (fl_large_pg - 1)) != 0) { + dev_err(adapter->pdev_dev, "bad SGE FL buffer sizes [%d, %d]\n", +- fl0, fl1); ++ fl_small_pg, fl_large_pg); + return -EINVAL; + } + if ((sge_params->sge_control & RXPKTCPLMODE_F) == 0) { +@@ -2627,8 +2638,8 @@ int t4vf_sge_init(struct adapter *adapter) + /* + * Now translate the adapter parameters into our internal forms. + */ +- if (fl1) +- s->fl_pg_order = ilog2(fl1) - PAGE_SHIFT; ++ if (fl_large_pg) ++ s->fl_pg_order = ilog2(fl_large_pg) - PAGE_SHIFT; + s->stat_len = ((sge_params->sge_control & EGRSTATUSPAGESIZE_F) + ? 128 : 64); + s->pktshift = PKTSHIFT_G(sge_params->sge_control); +diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c +index 40071dad1c57..9c76f1a2f57b 100644 +--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c ++++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c +@@ -382,7 +382,7 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) + { + const struct of_device_id *id = + of_match_device(fsl_pq_mdio_match, &pdev->dev); +- const struct fsl_pq_mdio_data *data = id->data; ++ const struct fsl_pq_mdio_data *data; + struct device_node *np = pdev->dev.of_node; + struct resource res; + struct device_node *tbi; +@@ -390,6 +390,13 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev) + struct mii_bus *new_bus; + int err; + ++ if (!id) { ++ dev_err(&pdev->dev, "Failed to match device\n"); ++ return -ENODEV; ++ } ++ ++ data = id->data; ++ + dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible); + + new_bus = mdiobus_alloc_size(sizeof(*priv)); +diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c +index 5d7db6c01c46..f301c03c527b 100644 +--- a/drivers/net/ethernet/ibm/emac/core.c ++++ b/drivers/net/ethernet/ibm/emac/core.c +@@ -342,6 +342,7 @@ static int emac_reset(struct emac_instance *dev) + { + struct emac_regs __iomem *p = dev->emacp; + int n = 20; ++ bool __maybe_unused try_internal_clock = false; + + DBG(dev, "reset" NL); + +@@ -354,6 +355,7 @@ static int emac_reset(struct emac_instance *dev) + } + + #ifdef CONFIG_PPC_DCR_NATIVE ++do_retry: + /* + * PPC460EX/GT Embedded Processor Advanced User's Manual + * section 28.10.1 Mode Register 0 (EMACx_MR0) states: +@@ -361,10 +363,19 @@ static int emac_reset(struct emac_instance *dev) + * of the EMAC. If none is present, select the internal clock + * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1). + * After a soft reset, select the external clock. ++ * ++ * The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the ++ * ethernet cable is not attached. This causes the reset to timeout ++ * and the PHY detection code in emac_init_phy() is unable to ++ * communicate and detect the AR8035-A PHY. As a result, the emac ++ * driver bails out early and the user has no ethernet. ++ * In order to stay compatible with existing configurations, the ++ * driver will temporarily switch to the internal clock, after ++ * the first reset fails. + */ + if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { +- if (dev->phy_address == 0xffffffff && +- dev->phy_map == 0xffffffff) { ++ if (try_internal_clock || (dev->phy_address == 0xffffffff && ++ dev->phy_map == 0xffffffff)) { + /* No PHY: select internal loop clock before reset */ + dcri_clrset(SDR0, SDR0_ETH_CFG, + 0, SDR0_ETH_CFG_ECS << dev->cell_index); +@@ -382,8 +393,15 @@ static int emac_reset(struct emac_instance *dev) + + #ifdef CONFIG_PPC_DCR_NATIVE + if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { +- if (dev->phy_address == 0xffffffff && +- dev->phy_map == 0xffffffff) { ++ if (!n && !try_internal_clock) { ++ /* first attempt has timed out. */ ++ n = 20; ++ try_internal_clock = true; ++ goto do_retry; ++ } ++ ++ if (try_internal_clock || (dev->phy_address == 0xffffffff && ++ dev->phy_map == 0xffffffff)) { + /* No PHY: restore external clock source after reset */ + dcri_clrset(SDR0, SDR0_ETH_CFG, + SDR0_ETH_CFG_ECS << dev->cell_index, 0); +diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c +index e356e9187e84..20d8806d2bff 100644 +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -1182,6 +1182,7 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work) + struct e1000_hw *hw = &adapter->hw; + + if (er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID) { ++ struct sk_buff *skb = adapter->tx_hwtstamp_skb; + struct skb_shared_hwtstamps shhwtstamps; + u64 txstmp; + +@@ -1190,9 +1191,14 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work) + + e1000e_systim_to_hwtstamp(adapter, &shhwtstamps, txstmp); + +- skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps); +- dev_kfree_skb_any(adapter->tx_hwtstamp_skb); ++ /* Clear the global tx_hwtstamp_skb pointer and force writes ++ * prior to notifying the stack of a Tx timestamp. ++ */ + adapter->tx_hwtstamp_skb = NULL; ++ wmb(); /* force write prior to skb_tstamp_tx */ ++ ++ skb_tstamp_tx(skb, &shhwtstamps); ++ dev_kfree_skb_any(skb); + } else if (time_after(jiffies, adapter->tx_hwtstamp_start + + adapter->tx_timeout_factor * HZ)) { + dev_kfree_skb_any(adapter->tx_hwtstamp_skb); +@@ -6589,12 +6595,17 @@ static int e1000e_pm_thaw(struct device *dev) + static int e1000e_pm_suspend(struct device *dev) + { + struct pci_dev *pdev = to_pci_dev(dev); ++ int rc; + + e1000e_flush_lpic(pdev); + + e1000e_pm_freeze(dev); + +- return __e1000_shutdown(pdev, false); ++ rc = __e1000_shutdown(pdev, false); ++ if (rc) ++ e1000e_pm_thaw(dev); ++ ++ return rc; + } + + static int e1000e_pm_resume(struct device *dev) +diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c +index 4b62aa1f9ff8..6e5065f0907b 100644 +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -5079,7 +5079,7 @@ static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + INIT_WORK(&hw->restart_work, sky2_restart); + + pci_set_drvdata(pdev, hw); +- pdev->d3_delay = 150; ++ pdev->d3_delay = 200; + + return 0; + +diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c +index 1d4e2e054647..897d061e4f03 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c ++++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c +@@ -35,6 +35,7 @@ + #include + + #include ++#include + #include + + #include "mlx4.h" +@@ -985,16 +986,21 @@ int mlx4_flow_attach(struct mlx4_dev *dev, + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + ++ if (!mlx4_qp_lookup(dev, rule->qpn)) { ++ mlx4_err_rule(dev, "QP doesn't exist\n", rule); ++ ret = -EINVAL; ++ goto out; ++ } ++ + trans_rule_ctrl_to_hw(rule, mailbox->buf); + + size += sizeof(struct mlx4_net_trans_rule_hw_ctrl); + + list_for_each_entry(cur, &rule->list, list) { + ret = parse_trans_rule(dev, cur, mailbox->buf + size); +- if (ret < 0) { +- mlx4_free_cmd_mailbox(dev, mailbox); +- return ret; +- } ++ if (ret < 0) ++ goto out; ++ + size += ret; + } + +@@ -1021,6 +1027,7 @@ int mlx4_flow_attach(struct mlx4_dev *dev, + } + } + ++out: + mlx4_free_cmd_mailbox(dev, mailbox); + + return ret; +diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c +index d8359ffba026..62f1a3433a62 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/qp.c ++++ b/drivers/net/ethernet/mellanox/mlx4/qp.c +@@ -381,6 +381,19 @@ static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn) + __mlx4_qp_free_icm(dev, qpn); + } + ++struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn) ++{ ++ struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table; ++ struct mlx4_qp *qp; ++ ++ spin_lock(&qp_table->lock); ++ ++ qp = __mlx4_qp_lookup(dev, qpn); ++ ++ spin_unlock(&qp_table->lock); ++ return qp; ++} ++ + int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp) + { + struct mlx4_priv *priv = mlx4_priv(dev); +@@ -468,6 +481,12 @@ int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn, + } + + if (attr & MLX4_UPDATE_QP_QOS_VPORT) { ++ if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QOS_VPP)) { ++ mlx4_warn(dev, "Granular QoS per VF is not enabled\n"); ++ err = -EOPNOTSUPP; ++ goto out; ++ } ++ + qp_mask |= 1ULL << MLX4_UPD_QP_MASK_QOS_VPP; + cmd->qp_context.qos_vport = params->qos_vport; + } +diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +index d1fc7fa87b05..e3080fbd9d00 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c ++++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +@@ -5040,6 +5040,13 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) + mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); + } + ++static void update_qos_vpp(struct mlx4_update_qp_context *ctx, ++ struct mlx4_vf_immed_vlan_work *work) ++{ ++ ctx->qp_mask |= cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_QOS_VPP); ++ ctx->qp_context.qos_vport = work->qos_vport; ++} ++ + void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work) + { + struct mlx4_vf_immed_vlan_work *work = +@@ -5144,11 +5151,10 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work) + qp->sched_queue & 0xC7; + upd_context->qp_context.pri_path.sched_queue |= + ((work->qos & 0x7) << 3); +- upd_context->qp_mask |= +- cpu_to_be64(1ULL << +- MLX4_UPD_QP_MASK_QOS_VPP); +- upd_context->qp_context.qos_vport = +- work->qos_vport; ++ ++ if (dev->caps.flags2 & ++ MLX4_DEV_CAP_FLAG2_QOS_VPP) ++ update_qos_vpp(upd_context, work); + } + + err = mlx4_cmd(dev, mailbox->dma, +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c +index f5c1f4acc57b..7c42be586be8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c +@@ -513,7 +513,6 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) + struct mlx5_priv *priv = &mdev->priv; + struct msix_entry *msix = priv->msix_arr; + int irq = msix[i + MLX5_EQ_VEC_COMP_BASE].vector; +- int err; + + if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) { + mlx5_core_warn(mdev, "zalloc_cpumask_var failed"); +@@ -523,18 +522,11 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i) + cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node), + priv->irq_info[i].mask); + +- err = irq_set_affinity_hint(irq, priv->irq_info[i].mask); +- if (err) { +- mlx5_core_warn(mdev, "irq_set_affinity_hint failed,irq 0x%.4x", +- irq); +- goto err_clear_mask; +- } ++ if (IS_ENABLED(CONFIG_SMP) && ++ irq_set_affinity_hint(irq, priv->irq_info[i].mask)) ++ mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq); + + return 0; +- +-err_clear_mask: +- free_cpumask_var(priv->irq_info[i].mask); +- return err; + } + + static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i) +diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +index b8d5270359cd..e30676515529 100644 +--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c ++++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c +@@ -247,7 +247,7 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu) + cmd.req.arg3 = 0; + + if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE) +- netxen_issue_cmd(adapter, &cmd); ++ rcode = netxen_issue_cmd(adapter, &cmd); + + if (rcode != NX_RCODE_SUCCESS) + return -EIO; +diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +index 509b596cf1e8..bd1ec70fb736 100644 +--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c ++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +@@ -341,7 +341,7 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) + } + return -EIO; + } +- usleep_range(1000, 1500); ++ udelay(1200); + } + + if (id_reg) +diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c +index be258d90de9e..e3223f2fe2ff 100644 +--- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c ++++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c +@@ -765,7 +765,7 @@ int ql_core_dump(struct ql_adapter *qdev, struct ql_mpi_coredump *mpi_coredump) + sizeof(struct mpi_coredump_global_header); + mpi_coredump->mpi_global_header.imageSize = + sizeof(struct ql_mpi_coredump); +- memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump", ++ strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump", + sizeof(mpi_coredump->mpi_global_header.idString)); + + /* Get generic NIC reg dump */ +@@ -1255,7 +1255,7 @@ static void ql_gen_reg_dump(struct ql_adapter *qdev, + sizeof(struct mpi_coredump_global_header); + mpi_coredump->mpi_global_header.imageSize = + sizeof(struct ql_reg_dump); +- memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump", ++ strncpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump", + sizeof(mpi_coredump->mpi_global_header.idString)); + + +diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c +index 1ef03939d25f..c90ae4d4be7d 100644 +--- a/drivers/net/ethernet/qualcomm/qca_spi.c ++++ b/drivers/net/ethernet/qualcomm/qca_spi.c +@@ -296,8 +296,9 @@ qcaspi_receive(struct qcaspi *qca) + + /* Allocate rx SKB if we don't have one available. */ + if (!qca->rx_skb) { +- qca->rx_skb = netdev_alloc_skb(net_dev, +- net_dev->mtu + VLAN_ETH_HLEN); ++ qca->rx_skb = netdev_alloc_skb_ip_align(net_dev, ++ net_dev->mtu + ++ VLAN_ETH_HLEN); + if (!qca->rx_skb) { + netdev_dbg(net_dev, "out of RX resources\n"); + qca->stats.out_of_mem++; +@@ -377,7 +378,7 @@ qcaspi_receive(struct qcaspi *qca) + qca->rx_skb, qca->rx_skb->dev); + qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY; + netif_rx_ni(qca->rx_skb); +- qca->rx_skb = netdev_alloc_skb(net_dev, ++ qca->rx_skb = netdev_alloc_skb_ip_align(net_dev, + net_dev->mtu + VLAN_ETH_HLEN); + if (!qca->rx_skb) { + netdev_dbg(net_dev, "out of RX resources\n"); +@@ -759,7 +760,8 @@ qcaspi_netdev_init(struct net_device *dev) + if (!qca->rx_buffer) + return -ENOBUFS; + +- qca->rx_skb = netdev_alloc_skb(dev, qca->net_dev->mtu + VLAN_ETH_HLEN); ++ qca->rx_skb = netdev_alloc_skb_ip_align(dev, qca->net_dev->mtu + ++ VLAN_ETH_HLEN); + if (!qca->rx_skb) { + kfree(qca->rx_buffer); + netdev_info(qca->net_dev, "Failed to allocate RX sk_buff.\n"); +diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c +index 3783c40f568b..a82c89af7124 100644 +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -8411,12 +8411,12 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + goto err_out_msi_4; + } + ++ pci_set_drvdata(pdev, dev); ++ + rc = register_netdev(dev); + if (rc < 0) + goto err_out_cnt_5; + +- pci_set_drvdata(pdev, dev); +- + netif_info(tp, probe, dev, "%s at 0x%p, %pM, XID %08x IRQ %d\n", + rtl_chip_infos[chipset].name, ioaddr, dev->dev_addr, + (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), pdev->irq); +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index 424d1dee55c9..afaf79b8761f 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -3222,7 +3222,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev) + /* MDIO bus init */ + ret = sh_mdio_init(mdp, pd); + if (ret) { +- dev_err(&ndev->dev, "failed to initialise MDIO\n"); ++ dev_err(&pdev->dev, "failed to initialise MDIO\n"); + goto out_release; + } + +diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c +index 435466c17852..c69b0bdd891d 100644 +--- a/drivers/net/ethernet/ti/cpsw.c ++++ b/drivers/net/ethernet/ti/cpsw.c +@@ -280,6 +280,10 @@ struct cpsw_ss_regs { + /* Bit definitions for the CPSW1_TS_SEQ_LTYPE register */ + #define CPSW_V1_SEQ_ID_OFS_SHIFT 16 + ++#define CPSW_MAX_BLKS_TX 15 ++#define CPSW_MAX_BLKS_TX_SHIFT 4 ++#define CPSW_MAX_BLKS_RX 5 ++ + struct cpsw_host_regs { + u32 max_blks; + u32 blk_cnt; +@@ -1127,11 +1131,23 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) + switch (priv->version) { + case CPSW_VERSION_1: + slave_write(slave, TX_PRIORITY_MAPPING, CPSW1_TX_PRI_MAP); ++ /* Increase RX FIFO size to 5 for supporting fullduplex ++ * flow control mode ++ */ ++ slave_write(slave, ++ (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) | ++ CPSW_MAX_BLKS_RX, CPSW1_MAX_BLKS); + break; + case CPSW_VERSION_2: + case CPSW_VERSION_3: + case CPSW_VERSION_4: + slave_write(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP); ++ /* Increase RX FIFO size to 5 for supporting fullduplex ++ * flow control mode ++ */ ++ slave_write(slave, ++ (CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) | ++ CPSW_MAX_BLKS_RX, CPSW2_MAX_BLKS); + break; + } + +diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c +index 49fe59b180a8..a75ce9051a7f 100644 +--- a/drivers/net/hamradio/hdlcdrv.c ++++ b/drivers/net/hamradio/hdlcdrv.c +@@ -574,6 +574,8 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) + case HDLCDRVCTL_CALIBRATE: + if(!capable(CAP_SYS_RAWIO)) + return -EPERM; ++ if (s->par.bitrate <= 0) ++ return -EINVAL; + if (bi.data.calibrate > INT_MAX / s->par.bitrate) + return -EINVAL; + s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16; +diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c +index 7d0690433ee0..7d2cf015c5e7 100644 +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -148,6 +148,12 @@ static inline int phy_aneg_done(struct phy_device *phydev) + if (phydev->drv->aneg_done) + return phydev->drv->aneg_done(phydev); + ++ /* Avoid genphy_aneg_done() if the Clause 45 PHY does not ++ * implement Clause 22 registers ++ */ ++ if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0))) ++ return -EINVAL; ++ + return genphy_aneg_done(phydev); + } + +diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c +index f7e8c79349ad..12a627fcc02c 100644 +--- a/drivers/net/ppp/pptp.c ++++ b/drivers/net/ppp/pptp.c +@@ -501,7 +501,6 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, + po->chan.mtu = dst_mtu(&rt->dst); + if (!po->chan.mtu) + po->chan.mtu = PPP_MRU; +- ip_rt_put(rt); + po->chan.mtu -= PPTP_HEADER_OVERHEAD; + + po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header); +diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c +index 72cb30828a12..c8e98c8e29fa 100644 +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -1069,6 +1069,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + u16 n = 0, index, ndplen; + u8 ready2send = 0; + u32 delayed_ndp_size; ++ size_t padding_count; + + /* When our NDP gets written in cdc_ncm_ndp(), then skb_out->len gets updated + * accordingly. Otherwise, we should check here. +@@ -1225,11 +1226,13 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) + * a ZLP after full sized NTBs. + */ + if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && +- skb_out->len > ctx->min_tx_pkt) +- memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0, +- ctx->tx_max - skb_out->len); +- else if (skb_out->len < ctx->tx_max && (skb_out->len % dev->maxpacket) == 0) ++ skb_out->len > ctx->min_tx_pkt) { ++ padding_count = ctx->tx_max - skb_out->len; ++ memset(skb_put(skb_out, padding_count), 0, padding_count); ++ } else if (skb_out->len < ctx->tx_max && ++ (skb_out->len % dev->maxpacket) == 0) { + *skb_put(skb_out, 1) = 0; /* force short packet */ ++ } + + /* set final frame length */ + nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index 8dfc75250583..d01285250204 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -556,7 +556,12 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq, + hdr = skb_vnet_hdr(skb); + sg_init_table(rq->sg, 2); + sg_set_buf(rq->sg, hdr, vi->hdr_len); +- skb_to_sgvec(skb, rq->sg + 1, 0, skb->len); ++ ++ err = skb_to_sgvec(skb, rq->sg + 1, 0, skb->len); ++ if (unlikely(err < 0)) { ++ dev_kfree_skb(skb); ++ return err; ++ } + + err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp); + if (err < 0) +@@ -858,7 +863,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) + struct virtio_net_hdr_mrg_rxbuf *hdr; + const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; + struct virtnet_info *vi = sq->vq->vdev->priv; +- unsigned num_sg; ++ int num_sg; + unsigned hdr_len = vi->hdr_len; + bool can_push; + +@@ -911,11 +916,16 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) + if (can_push) { + __skb_push(skb, hdr_len); + num_sg = skb_to_sgvec(skb, sq->sg, 0, skb->len); ++ if (unlikely(num_sg < 0)) ++ return num_sg; + /* Pull header back to avoid skew in tx bytes calculations. */ + __skb_pull(skb, hdr_len); + } else { + sg_set_buf(sq->sg, hdr, hdr_len); +- num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len) + 1; ++ num_sg = skb_to_sgvec(skb, sq->sg + 1, 0, skb->len); ++ if (unlikely(num_sg < 0)) ++ return num_sg; ++ num_sg++; + } + return virtqueue_add_outbuf(sq->vq, sq->sg, num_sg, skb, GFP_ATOMIC); + } +diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c +index 82bf85ae5d08..419c045d0752 100644 +--- a/drivers/net/vmxnet3/vmxnet3_drv.c ++++ b/drivers/net/vmxnet3/vmxnet3_drv.c +@@ -2789,6 +2789,11 @@ vmxnet3_force_close(struct vmxnet3_adapter *adapter) + /* we need to enable NAPI, otherwise dev_close will deadlock */ + for (i = 0; i < adapter->num_rx_queues; i++) + napi_enable(&adapter->rx_queue[i].napi); ++ /* ++ * Need to clear the quiesce bit to ensure that vmxnet3_close ++ * can quiesce the device properly ++ */ ++ clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state); + dev_close(adapter->netdev); + } + +diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c +index ac945f8781ac..d3d59122a357 100644 +--- a/drivers/net/vrf.c ++++ b/drivers/net/vrf.c +@@ -550,13 +550,15 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s + neigh = __ipv4_neigh_lookup_noref(dev, nexthop); + if (unlikely(!neigh)) + neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); +- if (!IS_ERR(neigh)) ++ if (!IS_ERR(neigh)) { + ret = dst_neigh_output(dst, neigh, skb); ++ rcu_read_unlock_bh(); ++ return ret; ++ } + + rcu_read_unlock_bh(); + err: +- if (unlikely(ret < 0)) +- vrf_tx_error(skb->dev, skb); ++ vrf_tx_error(skb->dev, skb); + return ret; + } + +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index e4ff1e45c02e..c41378214ede 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -962,7 +962,7 @@ static bool vxlan_snoop(struct net_device *dev, + return false; + + /* Don't migrate static entries, drop packets */ +- if (f->state & NUD_NOARP) ++ if (f->state & (NUD_PERMANENT | NUD_NOARP)) + return true; + + if (net_ratelimit()) +diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c +index 654a1e33f827..7c5f189cace7 100644 +--- a/drivers/net/wireless/ath/ath5k/debug.c ++++ b/drivers/net/wireless/ath/ath5k/debug.c +@@ -939,7 +939,10 @@ static int open_file_eeprom(struct inode *inode, struct file *file) + } + + for (i = 0; i < eesize; ++i) { +- AR5K_EEPROM_READ(i, val); ++ if (!ath5k_hw_nvram_read(ah, i, &val)) { ++ ret = -EIO; ++ goto freebuf; ++ } + buf[i] = val; + } + +diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c +index 0881ba8535f4..c78abfc7bd96 100644 +--- a/drivers/net/wireless/ray_cs.c ++++ b/drivers/net/wireless/ray_cs.c +@@ -247,7 +247,10 @@ static const UCHAR b4_default_startup_parms[] = { + 0x04, 0x08, /* Noise gain, limit offset */ + 0x28, 0x28, /* det rssi, med busy offsets */ + 7, /* det sync thresh */ +- 0, 2, 2 /* test mode, min, max */ ++ 0, 2, 2, /* test mode, min, max */ ++ 0, /* rx/tx delay */ ++ 0, 0, 0, 0, 0, 0, /* current BSS id */ ++ 0 /* hop set */ + }; + + /*===========================================================================*/ +@@ -598,7 +601,7 @@ static void init_startup_params(ray_dev_t *local) + * a_beacon_period = hops a_beacon_period = KuS + *//* 64ms = 010000 */ + if (local->fw_ver == 0x55) { +- memcpy((UCHAR *) &local->sparm.b4, b4_default_startup_parms, ++ memcpy(&local->sparm.b4, b4_default_startup_parms, + sizeof(struct b4_startup_params)); + /* Translate sane kus input values to old build 4/5 format */ + /* i = hop time in uS truncated to 3 bytes */ +diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c +index 9bee3f11898a..869411f55d88 100644 +--- a/drivers/net/wireless/ti/wl1251/main.c ++++ b/drivers/net/wireless/ti/wl1251/main.c +@@ -1196,8 +1196,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, + WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); + + enable = bss_conf->arp_addr_cnt == 1 && bss_conf->assoc; +- wl1251_acx_arp_ip_filter(wl, enable, addr); +- ++ ret = wl1251_acx_arp_ip_filter(wl, enable, addr); + if (ret < 0) + goto out_sleep; + } +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index 84419af16f77..fd12ccc11e26 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -538,6 +538,7 @@ struct powercap_zone *powercap_register_zone( + + power_zone->id = result; + idr_init(&power_zone->idr); ++ result = -ENOMEM; + power_zone->name = kstrdup(name, GFP_KERNEL); + if (!power_zone->name) + goto err_name_alloc; +diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c +index dcfd3655ef0a..c2cf9485fe32 100644 +--- a/drivers/rtc/interface.c ++++ b/drivers/rtc/interface.c +@@ -217,6 +217,13 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) + missing = year; + } + ++ /* Can't proceed if alarm is still invalid after replacing ++ * missing fields. ++ */ ++ err = rtc_valid_tm(&alarm->time); ++ if (err) ++ goto done; ++ + /* with luck, no rollover is needed */ + t_now = rtc_tm_to_time64(&now); + t_alm = rtc_tm_to_time64(&alarm->time); +@@ -268,9 +275,9 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) + dev_warn(&rtc->dev, "alarm rollover not handled\n"); + } + +-done: + err = rtc_valid_tm(&alarm->time); + ++done: + if (err) { + dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n", + alarm->time.tm_year + 1900, alarm->time.tm_mon + 1, +diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c +index 229dd2fe8f45..c6b0c7ed7a30 100644 +--- a/drivers/rtc/rtc-opal.c ++++ b/drivers/rtc/rtc-opal.c +@@ -150,6 +150,16 @@ static int opal_get_tpo_time(struct device *dev, struct rtc_wkalrm *alarm) + + y_m_d = be32_to_cpu(__y_m_d); + h_m_s_ms = ((u64)be32_to_cpu(__h_m) << 32); ++ ++ /* check if no alarm is set */ ++ if (y_m_d == 0 && h_m_s_ms == 0) { ++ pr_debug("No alarm is set\n"); ++ rc = -ENOENT; ++ goto exit; ++ } else { ++ pr_debug("Alarm set to %x %llx\n", y_m_d, h_m_s_ms); ++ } ++ + opal_to_tm(y_m_d, h_m_s_ms, &alarm->time); + + exit: +diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c +index 950c5d0b6dca..afab89f5be48 100644 +--- a/drivers/rtc/rtc-snvs.c ++++ b/drivers/rtc/rtc-snvs.c +@@ -257,7 +257,7 @@ static int snvs_rtc_probe(struct platform_device *pdev) + of_property_read_u32(pdev->dev.of_node, "offset", &data->offset); + } + +- if (!data->regmap) { ++ if (IS_ERR(data->regmap)) { + dev_err(&pdev->dev, "Can't find snvs syscon\n"); + return -ENODEV; + } +diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c +index e7a6f1222642..b76a85d14ef0 100644 +--- a/drivers/s390/block/dasd.c ++++ b/drivers/s390/block/dasd.c +@@ -1881,8 +1881,12 @@ static int __dasd_device_is_unusable(struct dasd_device *device, + { + int mask = ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM); + +- if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) { +- /* dasd is being set offline. */ ++ if (test_bit(DASD_FLAG_OFFLINE, &device->flags) && ++ !test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) { ++ /* ++ * dasd is being set offline ++ * but it is no safe offline where we have to allow I/O ++ */ + return 1; + } + if (device->stopped) { +diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h +index 499e369eabf0..8bc1625337f6 100644 +--- a/drivers/scsi/bnx2fc/bnx2fc.h ++++ b/drivers/scsi/bnx2fc/bnx2fc.h +@@ -191,6 +191,7 @@ struct bnx2fc_hba { + struct bnx2fc_cmd_mgr *cmd_mgr; + spinlock_t hba_lock; + struct mutex hba_mutex; ++ struct mutex hba_stats_mutex; + unsigned long adapter_state; + #define ADAPTER_STATE_UP 0 + #define ADAPTER_STATE_GOING_DOWN 1 +diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +index 67405c628864..d0b227ffbd5f 100644 +--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c ++++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +@@ -641,15 +641,17 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost) + if (!fw_stats) + return NULL; + ++ mutex_lock(&hba->hba_stats_mutex); ++ + bnx2fc_stats = fc_get_host_stats(shost); + + init_completion(&hba->stat_req_done); + if (bnx2fc_send_stat_req(hba)) +- return bnx2fc_stats; ++ goto unlock_stats_mutex; + rc = wait_for_completion_timeout(&hba->stat_req_done, (2 * HZ)); + if (!rc) { + BNX2FC_HBA_DBG(lport, "FW stat req timed out\n"); +- return bnx2fc_stats; ++ goto unlock_stats_mutex; + } + BNX2FC_STATS(hba, rx_stat2, fc_crc_cnt); + bnx2fc_stats->invalid_crc_count += hba->bfw_stats.fc_crc_cnt; +@@ -671,6 +673,9 @@ static struct fc_host_statistics *bnx2fc_get_host_stats(struct Scsi_Host *shost) + + memcpy(&hba->prev_stats, hba->stats_buffer, + sizeof(struct fcoe_statistics_params)); ++ ++unlock_stats_mutex: ++ mutex_unlock(&hba->hba_stats_mutex); + return bnx2fc_stats; + } + +@@ -1302,6 +1307,7 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) + } + spin_lock_init(&hba->hba_lock); + mutex_init(&hba->hba_mutex); ++ mutex_init(&hba->hba_stats_mutex); + + hba->cnic = cnic; + +diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c +index 622bdabc8894..dab195f04da7 100644 +--- a/drivers/scsi/csiostor/csio_hw.c ++++ b/drivers/scsi/csiostor/csio_hw.c +@@ -1769,7 +1769,6 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param) + goto bye; + } + +- mempool_free(mbp, hw->mb_mempool); + if (finicsum != cfcsum) { + csio_warn(hw, + "Config File checksum mismatch: csum=%#x, computed=%#x\n", +@@ -1780,6 +1779,10 @@ csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param) + rv = csio_hw_validate_caps(hw, mbp); + if (rv != 0) + goto bye; ++ ++ mempool_free(mbp, hw->mb_mempool); ++ mbp = NULL; ++ + /* + * Note that we're operating with parameters + * not supplied by the driver, rather than from hard-wired +diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c +index efce04df2109..9f0b00c38658 100644 +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -1695,6 +1695,15 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) + */ + switch (session->state) { + case ISCSI_STATE_FAILED: ++ /* ++ * cmds should fail during shutdown, if the session ++ * state is bad, allowing completion to happen ++ */ ++ if (unlikely(system_state != SYSTEM_RUNNING)) { ++ reason = FAILURE_SESSION_FAILED; ++ sc->result = DID_NO_CONNECT << 16; ++ break; ++ } + case ISCSI_STATE_IN_RECOVERY: + reason = FAILURE_SESSION_IN_RECOVERY; + sc->result = DID_IMM_RETRY << 16; +@@ -1979,6 +1988,19 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) + } + + if (session->state != ISCSI_STATE_LOGGED_IN) { ++ /* ++ * During shutdown, if session is prematurely disconnected, ++ * recovery won't happen and there will be hung cmds. Not ++ * handling cmds would trigger EH, also bad in this case. ++ * Instead, handle cmd, allow completion to happen and let ++ * upper layer to deal with the result. ++ */ ++ if (unlikely(system_state != SYSTEM_RUNNING)) { ++ sc->result = DID_NO_CONNECT << 16; ++ ISCSI_DBG_EH(session, "sc on shutdown, handled\n"); ++ rc = BLK_EH_HANDLED; ++ goto done; ++ } + /* + * We are probably in the middle of iscsi recovery so let + * that complete and handle the error. +@@ -2083,7 +2105,7 @@ done: + task->last_timeout = jiffies; + spin_unlock(&session->frwd_lock); + ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? +- "timer reset" : "nh"); ++ "timer reset" : "shutdown or nh"); + return rc; + } + +diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c +index 022bb6e10d98..12886f96b286 100644 +--- a/drivers/scsi/libsas/sas_expander.c ++++ b/drivers/scsi/libsas/sas_expander.c +@@ -282,6 +282,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) + phy->phy->minimum_linkrate = dr->pmin_linkrate; + phy->phy->maximum_linkrate = dr->pmax_linkrate; + phy->phy->negotiated_linkrate = phy->linkrate; ++ phy->phy->enabled = (phy->linkrate != SAS_PHY_DISABLED); + + skip: + if (new_phy) +@@ -675,7 +676,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy) + res = smp_execute_task(dev, req, RPEL_REQ_SIZE, + resp, RPEL_RESP_SIZE); + +- if (!res) ++ if (res) + goto out; + + phy->invalid_dword_count = scsi_to_u32(&resp[12]); +@@ -684,6 +685,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy) + phy->phy_reset_problem_count = scsi_to_u32(&resp[24]); + + out: ++ kfree(req); + kfree(resp); + return res; + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index e111c3d8c5d6..b868ef3b2ca3 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -3886,19 +3886,6 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) + return 0; + } + +- /* +- * Bug work around for firmware SATL handling. The loop +- * is based on atomic operations and ensures consistency +- * since we're lockless at this point +- */ +- do { +- if (test_bit(0, &sas_device_priv_data->ata_command_pending)) { +- scmd->result = SAM_STAT_BUSY; +- scmd->scsi_done(scmd); +- return 0; +- } +- } while (_scsih_set_satl_pending(scmd, true)); +- + sas_target_priv_data = sas_device_priv_data->sas_target; + + /* invalid device handle */ +@@ -3924,6 +3911,19 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) + sas_device_priv_data->block) + return SCSI_MLQUEUE_DEVICE_BUSY; + ++ /* ++ * Bug work around for firmware SATL handling. The loop ++ * is based on atomic operations and ensures consistency ++ * since we're lockless at this point ++ */ ++ do { ++ if (test_bit(0, &sas_device_priv_data->ata_command_pending)) { ++ scmd->result = SAM_STAT_BUSY; ++ scmd->scsi_done(scmd); ++ return 0; ++ } ++ } while (_scsih_set_satl_pending(scmd, true)); ++ + if (scmd->sc_data_direction == DMA_FROM_DEVICE) + mpi_control = MPI2_SCSIIO_CONTROL_READ; + else if (scmd->sc_data_direction == DMA_TO_DEVICE) +@@ -3945,6 +3945,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) + if (!smid) { + pr_err(MPT3SAS_FMT "%s: failed obtaining a smid\n", + ioc->name, __func__); ++ _scsih_set_satl_pending(scmd, false); + goto out; + } + mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); +@@ -3975,6 +3976,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) + if (mpi_request->DataLength) { + if (ioc->build_sg_scmd(ioc, scmd, smid)) { + mpt3sas_base_free_smid(ioc, smid); ++ _scsih_set_satl_pending(scmd, false); + goto out; + } + } else +diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c +index 013a6240f193..c1ad0aea23b9 100644 +--- a/drivers/staging/wlan-ng/prism2mgmt.c ++++ b/drivers/staging/wlan-ng/prism2mgmt.c +@@ -169,7 +169,7 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp) + hw->ident_sta_fw.variant) > + HFA384x_FIRMWARE_VERSION(1, 5, 0)) { + if (msg->scantype.data != P80211ENUM_scantype_active) +- word = cpu_to_le16(msg->maxchanneltime.data); ++ word = msg->maxchanneltime.data; + else + word = 0; + +diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/power_allocator.c +index 1246aa6fcab0..737635f0bec0 100644 +--- a/drivers/thermal/power_allocator.c ++++ b/drivers/thermal/power_allocator.c +@@ -523,6 +523,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz) + struct thermal_instance *instance; + struct power_allocator_params *params = tz->governor_data; + ++ mutex_lock(&tz->lock); + list_for_each_entry(instance, &tz->thermal_instances, tz_node) { + if ((instance->trip != params->trip_max_desired_temperature) || + (!cdev_is_power_actor(instance->cdev))) +@@ -532,6 +533,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz) + instance->cdev->updated = false; + thermal_cdev_update(instance->cdev); + } ++ mutex_unlock(&tz->lock); + } + + /** +diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c +index 9aff37186246..78bd121ecede 100644 +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -1467,6 +1467,10 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) + * in which case an opening port goes back to closed and a closing port + * is simply put into closed state (any further frames from the other + * end will get a DM response) ++ * ++ * Some control dlci can stay in ADM mode with other dlci working just ++ * fine. In that case we can just keep the control dlci open after the ++ * DLCI_OPENING retries time out. + */ + + static void gsm_dlci_t1(unsigned long data) +@@ -1480,8 +1484,15 @@ static void gsm_dlci_t1(unsigned long data) + if (dlci->retries) { + gsm_command(dlci->gsm, dlci->addr, SABM|PF); + mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); +- } else ++ } else if (!dlci->addr && gsm->control == (DM | PF)) { ++ if (debug & 8) ++ pr_info("DLCI %d opening in ADM mode.\n", ++ dlci->addr); ++ gsm_dlci_open(dlci); ++ } else { + gsm_dlci_close(dlci); ++ } ++ + break; + case DLCI_CLOSING: + dlci->retries--; +@@ -1499,8 +1510,8 @@ static void gsm_dlci_t1(unsigned long data) + * @dlci: DLCI to open + * + * Commence opening a DLCI from the Linux side. We issue SABM messages +- * to the modem which should then reply with a UA, at which point we +- * will move into open state. Opening is done asynchronously with retry ++ * to the modem which should then reply with a UA or ADM, at which point ++ * we will move into open state. Opening is done asynchronously with retry + * running off timers and the responses. + */ + +diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c +index e8dd296fb25b..c4383573cf66 100644 +--- a/drivers/tty/serial/8250/8250_omap.c ++++ b/drivers/tty/serial/8250/8250_omap.c +@@ -608,6 +608,10 @@ static int omap_8250_startup(struct uart_port *port) + up->lsr_saved_flags = 0; + up->msr_saved_flags = 0; + ++ /* Disable DMA for console UART */ ++ if (uart_console(port)) ++ up->dma = NULL; ++ + if (up->dma) { + ret = serial8250_request_dma(up); + if (ret) { +diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c +index fcf803ffad19..cdd2f942317c 100644 +--- a/drivers/tty/serial/sccnxp.c ++++ b/drivers/tty/serial/sccnxp.c +@@ -884,14 +884,19 @@ static int sccnxp_probe(struct platform_device *pdev) + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { +- if (PTR_ERR(clk) == -EPROBE_DEFER) { +- ret = -EPROBE_DEFER; ++ ret = PTR_ERR(clk); ++ if (ret == -EPROBE_DEFER) + goto err_out; +- } ++ uartclk = 0; ++ } else { ++ clk_prepare_enable(clk); ++ uartclk = clk_get_rate(clk); ++ } ++ ++ if (!uartclk) { + dev_notice(&pdev->dev, "Using default clock frequency\n"); + uartclk = s->chip->freq_std; +- } else +- uartclk = clk_get_rate(clk); ++ } + + /* Check input frequency */ + if ((uartclk < s->chip->freq_min) || (uartclk > s->chip->freq_max)) { +diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c +index fc7711c75b01..8dd822feb972 100644 +--- a/drivers/tty/serial/sh-sci.c ++++ b/drivers/tty/serial/sh-sci.c +@@ -1457,7 +1457,16 @@ static void sci_free_dma(struct uart_port *port) + if (s->chan_rx) + sci_rx_dma_release(s, false); + } +-#else ++ ++static void sci_flush_buffer(struct uart_port *port) ++{ ++ /* ++ * In uart_flush_buffer(), the xmit circular buffer has just been ++ * cleared, so we have to reset tx_dma_len accordingly. ++ */ ++ to_sci_port(port)->tx_dma_len = 0; ++} ++#else /* !CONFIG_SERIAL_SH_SCI_DMA */ + static inline void sci_request_dma(struct uart_port *port) + { + } +@@ -1465,7 +1474,9 @@ static inline void sci_request_dma(struct uart_port *port) + static inline void sci_free_dma(struct uart_port *port) + { + } +-#endif ++ ++#define sci_flush_buffer NULL ++#endif /* !CONFIG_SERIAL_SH_SCI_DMA */ + + static irqreturn_t sci_rx_interrupt(int irq, void *ptr) + { +@@ -2205,6 +2216,7 @@ static struct uart_ops sci_uart_ops = { + .break_ctl = sci_break_ctl, + .startup = sci_startup, + .shutdown = sci_shutdown, ++ .flush_buffer = sci_flush_buffer, + .set_termios = sci_set_termios, + .pm = sci_pm, + .type = sci_type, +diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c +index 939c6ad71068..57ee43512992 100644 +--- a/drivers/usb/chipidea/core.c ++++ b/drivers/usb/chipidea/core.c +@@ -851,7 +851,7 @@ static inline void ci_role_destroy(struct ci_hdrc *ci) + { + ci_hdrc_gadget_destroy(ci); + ci_hdrc_host_destroy(ci); +- if (ci->is_otg) ++ if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) + ci_hdrc_otg_destroy(ci); + } + +@@ -951,27 +951,35 @@ static int ci_hdrc_probe(struct platform_device *pdev) + /* initialize role(s) before the interrupt is requested */ + if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) { + ret = ci_hdrc_host_init(ci); +- if (ret) +- dev_info(dev, "doesn't support host\n"); ++ if (ret) { ++ if (ret == -ENXIO) ++ dev_info(dev, "doesn't support host\n"); ++ else ++ goto deinit_phy; ++ } + } + + if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) { + ret = ci_hdrc_gadget_init(ci); +- if (ret) +- dev_info(dev, "doesn't support gadget\n"); ++ if (ret) { ++ if (ret == -ENXIO) ++ dev_info(dev, "doesn't support gadget\n"); ++ else ++ goto deinit_host; ++ } + } + + if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { + dev_err(dev, "no supported roles\n"); + ret = -ENODEV; +- goto deinit_phy; ++ goto deinit_gadget; + } + + if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) { + ret = ci_hdrc_otg_init(ci); + if (ret) { + dev_err(dev, "init otg fails, ret = %d\n", ret); +- goto stop; ++ goto deinit_gadget; + } + } + +@@ -1036,7 +1044,12 @@ static int ci_hdrc_probe(struct platform_device *pdev) + + ci_extcon_unregister(ci); + stop: +- ci_role_destroy(ci); ++ if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) ++ ci_hdrc_otg_destroy(ci); ++deinit_gadget: ++ ci_hdrc_gadget_destroy(ci); ++deinit_host: ++ ci_hdrc_host_destroy(ci); + deinit_phy: + ci_usb_phy_exit(ci); + +diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c +index 2be268d2423d..03a926ebf34b 100644 +--- a/drivers/usb/dwc3/dwc3-keystone.c ++++ b/drivers/usb/dwc3/dwc3-keystone.c +@@ -112,6 +112,10 @@ static int kdwc3_probe(struct platform_device *pdev) + dev->dma_mask = &kdwc3_dma_mask; + + kdwc->clk = devm_clk_get(kdwc->dev, "usb"); ++ if (IS_ERR(kdwc->clk)) { ++ dev_err(kdwc->dev, "unable to get usb clock\n"); ++ return PTR_ERR(kdwc->clk); ++ } + + error = clk_prepare_enable(kdwc->clk); + if (error < 0) { +diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c +index 7afd607ea60f..062cf8a84a59 100644 +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -284,7 +284,6 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match); + static struct platform_driver usb_xhci_driver = { + .probe = xhci_plat_probe, + .remove = xhci_plat_remove, +- .shutdown = usb_hcd_platform_shutdown, + .driver = { + .name = "xhci-hcd", + .pm = DEV_PM_OPS, +diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c +index 091e8ec7a6c0..962bb6376b0c 100644 +--- a/drivers/usb/storage/ene_ub6250.c ++++ b/drivers/usb/storage/ene_ub6250.c +@@ -1953,6 +1953,8 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag) + bcb->CDB[0] = 0xEF; + + result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0); ++ if (us->srb != NULL) ++ scsi_set_resid(us->srb, 0); + info->BIN_FLAG = flag; + kfree(buf); + +@@ -2306,21 +2308,22 @@ static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) + + static int ene_transport(struct scsi_cmnd *srb, struct us_data *us) + { +- int result = 0; ++ int result = USB_STOR_XFER_GOOD; + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + + /*US_DEBUG(usb_stor_show_command(us, srb)); */ + scsi_set_resid(srb, 0); +- if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) { ++ if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) + result = ene_init(us); +- } else { ++ if (result == USB_STOR_XFER_GOOD) { ++ result = USB_STOR_TRANSPORT_ERROR; + if (info->SD_Status.Ready) + result = sd_scsi_irp(us, srb); + + if (info->MS_Status.Ready) + result = ms_scsi_irp(us, srb); + } +- return 0; ++ return result; + } + + static struct scsi_host_template ene_ub6250_host_template; +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index ad2146a9ab2d..675819a1af37 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -173,8 +173,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file) + if (mask) + vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask); + if (mask & POLLERR) { +- if (poll->wqh) +- remove_wait_queue(poll->wqh, &poll->wait); ++ vhost_poll_stop(poll); + ret = -EINVAL; + } + +diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c +index b9c2f81fb6b9..556c39997aab 100644 +--- a/drivers/video/fbdev/vfb.c ++++ b/drivers/video/fbdev/vfb.c +@@ -291,8 +291,23 @@ static int vfb_check_var(struct fb_var_screeninfo *var, + */ + static int vfb_set_par(struct fb_info *info) + { ++ switch (info->var.bits_per_pixel) { ++ case 1: ++ info->fix.visual = FB_VISUAL_MONO01; ++ break; ++ case 8: ++ info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ break; ++ case 16: ++ case 24: ++ case 32: ++ info->fix.visual = FB_VISUAL_TRUECOLOR; ++ break; ++ } ++ + info->fix.line_length = get_line_length(info->var.xres_virtual, + info->var.bits_per_pixel); ++ + return 0; + } + +@@ -525,6 +540,8 @@ static int vfb_probe(struct platform_device *dev) + goto err2; + platform_set_drvdata(dev, info); + ++ vfb_set_par(info); ++ + fb_info(info, "Virtual frame buffer device, using %ldK of video memory\n", + videomemorysize >> 10); + return 0; +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index e767f347f2b1..88bee6703cc0 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -2534,7 +2534,7 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end) + if (!uptodate) { + ClearPageUptodate(page); + SetPageError(page); +- ret = ret < 0 ? ret : -EIO; ++ ret = err < 0 ? err : -EIO; + mapping_set_error(page->mapping, ret); + } + return 0; +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index 744be3c146f5..0141aba9eca6 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -589,7 +589,7 @@ cifs_relock_file(struct cifsFileInfo *cfile) + struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); + int rc = 0; + +- down_read(&cinode->lock_sem); ++ down_read_nested(&cinode->lock_sem, SINGLE_DEPTH_NESTING); + if (cinode->can_cache_brlcks) { + /* can cache locks - no need to relock */ + up_read(&cinode->lock_sem); +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 33b1bc21a120..807e989f436a 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -999,15 +999,19 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, + goto tcon_exit; + } + +- if (rsp->ShareType & SMB2_SHARE_TYPE_DISK) ++ switch (rsp->ShareType) { ++ case SMB2_SHARE_TYPE_DISK: + cifs_dbg(FYI, "connection to disk share\n"); +- else if (rsp->ShareType & SMB2_SHARE_TYPE_PIPE) { ++ break; ++ case SMB2_SHARE_TYPE_PIPE: + tcon->ipc = true; + cifs_dbg(FYI, "connection to pipe share\n"); +- } else if (rsp->ShareType & SMB2_SHARE_TYPE_PRINT) { +- tcon->print = true; ++ break; ++ case SMB2_SHARE_TYPE_PRINT: ++ tcon->ipc = true; + cifs_dbg(FYI, "connection to printer\n"); +- } else { ++ break; ++ default: + cifs_dbg(VFS, "unknown share type %d\n", rsp->ShareType); + rc = -EOPNOTSUPP; + goto tcon_error_exit; +diff --git a/fs/ext4/file.c b/fs/ext4/file.c +index a8b1749d79a8..debf0707789d 100644 +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -460,7 +460,7 @@ static int ext4_find_unwritten_pgoff(struct inode *inode, + int i, num; + unsigned long nr_pages; + +- num = min_t(pgoff_t, end - index, PAGEVEC_SIZE); ++ num = min_t(pgoff_t, end - index, PAGEVEC_SIZE - 1) + 1; + nr_pages = pagevec_lookup(&pvec, inode->i_mapping, index, + (pgoff_t)num); + if (nr_pages == 0) +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 1ba82dc5afa3..d98ff184d94a 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -3874,7 +3874,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, + + err = ext4_mb_load_buddy(sb, group, &e4b); + if (err) { +- ext4_error(sb, "Error loading buddy information for %u", group); ++ ext4_warning(sb, "Error %d loading buddy information for %u", ++ err, group); + put_bh(bitmap_bh); + return 0; + } +@@ -4031,10 +4032,11 @@ repeat: + BUG_ON(pa->pa_type != MB_INODE_PA); + group = ext4_get_group_number(sb, pa->pa_pstart); + +- err = ext4_mb_load_buddy(sb, group, &e4b); ++ err = ext4_mb_load_buddy_gfp(sb, group, &e4b, ++ GFP_NOFS|__GFP_NOFAIL); + if (err) { +- ext4_error(sb, "Error loading buddy information for %u", +- group); ++ ext4_error(sb, "Error %d loading buddy information for %u", ++ err, group); + continue; + } + +@@ -4290,11 +4292,14 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb, + spin_unlock(&lg->lg_prealloc_lock); + + list_for_each_entry_safe(pa, tmp, &discard_list, u.pa_tmp_list) { ++ int err; + + group = ext4_get_group_number(sb, pa->pa_pstart); +- if (ext4_mb_load_buddy(sb, group, &e4b)) { +- ext4_error(sb, "Error loading buddy information for %u", +- group); ++ err = ext4_mb_load_buddy_gfp(sb, group, &e4b, ++ GFP_NOFS|__GFP_NOFAIL); ++ if (err) { ++ ext4_error(sb, "Error %d loading buddy information for %u", ++ err, group); + continue; + } + ext4_lock_group(sb, group); +@@ -5116,8 +5121,8 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, + + ret = ext4_mb_load_buddy(sb, group, &e4b); + if (ret) { +- ext4_error(sb, "Error in loading buddy " +- "information for %u", group); ++ ext4_warning(sb, "Error %d loading buddy information for %u", ++ ret, group); + return ret; + } + bitmap = e4b.bd_bitmap; +diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c +index 5f31ebd96c06..a2edb0049eb5 100644 +--- a/fs/lockd/svc.c ++++ b/fs/lockd/svc.c +@@ -129,6 +129,8 @@ lockd(void *vrqstp) + { + int err = 0; + struct svc_rqst *rqstp = vrqstp; ++ struct net *net = &init_net; ++ struct lockd_net *ln = net_generic(net, lockd_net_id); + + /* try_to_freeze() is called from svc_recv() */ + set_freezable(); +@@ -173,6 +175,8 @@ lockd(void *vrqstp) + if (nlmsvc_ops) + nlmsvc_invalidate_all(); + nlm_shutdown_hosts(); ++ cancel_delayed_work_sync(&ln->grace_period_end); ++ locks_end_grace(&ln->lockd_manager); + return 0; + } + +@@ -267,8 +271,6 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net) + if (ln->nlmsvc_users) { + if (--ln->nlmsvc_users == 0) { + nlm_shutdown_hosts_net(net); +- cancel_delayed_work_sync(&ln->grace_period_end); +- locks_end_grace(&ln->lockd_manager); + svc_shutdown_net(serv, net); + dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net); + } +diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c +index 54313322ee5b..c8e90152b61b 100644 +--- a/fs/nfs/flexfilelayout/flexfilelayout.c ++++ b/fs/nfs/flexfilelayout/flexfilelayout.c +@@ -461,6 +461,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, + goto out_err_free; + + /* fh */ ++ rc = -EIO; + p = xdr_inline_decode(&stream, 4); + if (!p) + goto out_err_free; +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 8ef6f70c9e25..0f397e62de5a 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -3025,6 +3025,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f + .rpc_resp = &res, + }; + int status; ++ int i; + + bitmask[0] = FATTR4_WORD0_SUPPORTED_ATTRS | + FATTR4_WORD0_FH_EXPIRE_TYPE | +@@ -3090,8 +3091,13 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f + server->cache_consistency_bitmask[0] &= FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE; + server->cache_consistency_bitmask[1] &= FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; + server->cache_consistency_bitmask[2] = 0; ++ ++ /* Avoid a regression due to buggy server */ ++ for (i = 0; i < ARRAY_SIZE(res.exclcreat_bitmask); i++) ++ res.exclcreat_bitmask[i] &= res.attr_bitmask[i]; + memcpy(server->exclcreat_bitmask, res.exclcreat_bitmask, + sizeof(server->exclcreat_bitmask)); ++ + server->acl_bitmask = res.acl_bitmask; + server->fh_expire_type = res.fh_expire_type; + } +@@ -7670,6 +7676,12 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf + /* fall through */ + case -NFS4ERR_RETRY_UNCACHED_REP: + return -EAGAIN; ++ case -NFS4ERR_BADSESSION: ++ case -NFS4ERR_DEADSESSION: ++ case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: ++ nfs4_schedule_session_recovery(clp->cl_session, ++ task->tk_status); ++ break; + default: + nfs4_schedule_lease_recovery(clp); + } +@@ -7748,7 +7760,6 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp, + if (status == 0) + status = task->tk_status; + rpc_put_task(task); +- return 0; + out: + dprintk("<-- %s status=%d\n", __func__, status); + return status; +diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c +index 9a0b219ff74d..83fba40396ae 100644 +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1593,13 +1593,14 @@ static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp) + nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot); + } + +-static void nfs4_reclaim_complete(struct nfs_client *clp, ++static int nfs4_reclaim_complete(struct nfs_client *clp, + const struct nfs4_state_recovery_ops *ops, + struct rpc_cred *cred) + { + /* Notify the server we're done reclaiming our state */ + if (ops->reclaim_complete) +- (void)ops->reclaim_complete(clp, cred); ++ return ops->reclaim_complete(clp, cred); ++ return 0; + } + + static void nfs4_clear_reclaim_server(struct nfs_server *server) +@@ -1646,13 +1647,16 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) + { + const struct nfs4_state_recovery_ops *ops; + struct rpc_cred *cred; ++ int err; + + if (!nfs4_state_clear_reclaim_reboot(clp)) + return; + ops = clp->cl_mvops->reboot_recovery_ops; + cred = nfs4_get_clid_cred(clp); +- nfs4_reclaim_complete(clp, ops, cred); ++ err = nfs4_reclaim_complete(clp, ops, cred); + put_rpccred(cred); ++ if (err == -NFS4ERR_CONN_NOT_BOUND_TO_SESSION) ++ set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state); + } + + static void nfs_delegation_clear_all(struct nfs_client *clp) +diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c +index 220b04f04523..985a4cdae06d 100644 +--- a/fs/overlayfs/inode.c ++++ b/fs/overlayfs/inode.c +@@ -272,6 +272,16 @@ ssize_t ovl_getxattr(struct dentry *dentry, const char *name, + return vfs_getxattr(realpath.dentry, name, value, size); + } + ++static bool ovl_can_list(const char *s) ++{ ++ /* List all non-trusted xatts */ ++ if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0) ++ return true; ++ ++ /* Never list trusted.overlay, list other trusted for superuser only */ ++ return !ovl_is_private_xattr(s) && capable(CAP_SYS_ADMIN); ++} ++ + ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) + { + struct path realpath; +@@ -296,7 +306,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) + return -EIO; + + len -= slen; +- if (ovl_is_private_xattr(s)) { ++ if (!ovl_can_list(s)) { + res -= slen; + memmove(s, s + slen, len); + } else { +diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h +index fe052e234906..bb1018882199 100644 +--- a/include/linux/mlx4/qp.h ++++ b/include/linux/mlx4/qp.h +@@ -465,6 +465,7 @@ struct mlx4_update_qp_params { + u16 rate_val; + }; + ++struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn); + int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn, + enum mlx4_update_qp_attr attr, + struct mlx4_update_qp_params *params); +diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h +index a91b67b18a73..5c93f4a89afa 100644 +--- a/include/linux/mlx5/device.h ++++ b/include/linux/mlx5/device.h +@@ -635,8 +635,14 @@ enum { + }; + + enum { +- CQE_RSS_HTYPE_IP = 0x3 << 6, +- CQE_RSS_HTYPE_L4 = 0x3 << 2, ++ CQE_RSS_HTYPE_IP = 0x3 << 2, ++ /* cqe->rss_hash_type[3:2] - IP destination selected for hash ++ * (00 = none, 01 = IPv4, 10 = IPv6, 11 = Reserved) ++ */ ++ CQE_RSS_HTYPE_L4 = 0x3 << 6, ++ /* cqe->rss_hash_type[7:6] - L4 destination selected for hash ++ * (00 = none, 01 = TCP. 10 = UDP, 11 = IPSEC.SPI ++ */ + }; + + enum { +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index b5421f6f155a..a6da214d0584 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -879,10 +879,10 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, + unsigned int headroom); + struct sk_buff *skb_copy_expand(const struct sk_buff *skb, int newheadroom, + int newtailroom, gfp_t priority); +-int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg, +- int offset, int len); +-int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, +- int len); ++int __must_check skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg, ++ int offset, int len); ++int __must_check skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, ++ int offset, int len); + int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer); + int skb_pad(struct sk_buff *skb, int pad); + #define dev_kfree_skb(a) consume_skb(a) +diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h +index b5f3693fe5b6..c05748cc1b20 100644 +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -933,9 +933,9 @@ enum rate_info_flags { + * @RATE_INFO_BW_160: 160 MHz bandwidth + */ + enum rate_info_bw { ++ RATE_INFO_BW_20 = 0, + RATE_INFO_BW_5, + RATE_INFO_BW_10, +- RATE_INFO_BW_20, + RATE_INFO_BW_40, + RATE_INFO_BW_80, + RATE_INFO_BW_160, +diff --git a/include/net/x25.h b/include/net/x25.h +index c383aa4edbf0..6d30a01d281d 100644 +--- a/include/net/x25.h ++++ b/include/net/x25.h +@@ -298,10 +298,10 @@ void x25_check_rbuf(struct sock *); + + /* sysctl_net_x25.c */ + #ifdef CONFIG_SYSCTL +-void x25_register_sysctl(void); ++int x25_register_sysctl(void); + void x25_unregister_sysctl(void); + #else +-static inline void x25_register_sysctl(void) {}; ++static inline int x25_register_sysctl(void) { return 0; }; + static inline void x25_unregister_sysctl(void) {}; + #endif /* CONFIG_SYSCTL */ + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 8f75386e61a7..835ac4d9f349 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -5271,9 +5271,6 @@ static void perf_output_read_one(struct perf_output_handle *handle, + __output_copy(handle, values, n * sizeof(u64)); + } + +-/* +- * XXX PERF_FORMAT_GROUP vs inherited events seems difficult. +- */ + static void perf_output_read_group(struct perf_output_handle *handle, + struct perf_event *event, + u64 enabled, u64 running) +@@ -5318,6 +5315,13 @@ static void perf_output_read_group(struct perf_output_handle *handle, + #define PERF_FORMAT_TOTAL_TIMES (PERF_FORMAT_TOTAL_TIME_ENABLED|\ + PERF_FORMAT_TOTAL_TIME_RUNNING) + ++/* ++ * XXX PERF_SAMPLE_READ vs inherited events seems difficult. ++ * ++ * The problem is that its both hard and excessively expensive to iterate the ++ * child list, not to mention that its impossible to IPI the children running ++ * on another CPU, from interrupt/NMI context. ++ */ + static void perf_output_read(struct perf_output_handle *handle, + struct perf_event *event) + { +@@ -7958,9 +7962,10 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, + local64_set(&hwc->period_left, hwc->sample_period); + + /* +- * we currently do not support PERF_FORMAT_GROUP on inherited events ++ * We currently do not support PERF_SAMPLE_READ on inherited events. ++ * See perf_output_read(). + */ +- if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP)) ++ if (attr->inherit && (attr->sample_type & PERF_SAMPLE_READ)) + goto err_ns; + + if (!has_branch_stack(event)) +diff --git a/kernel/futex.c b/kernel/futex.c +index 1fce19fc824c..a12aa6785361 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -470,6 +470,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) + unsigned long address = (unsigned long)uaddr; + struct mm_struct *mm = current->mm; + struct page *page, *page_head; ++ struct address_space *mapping; + int err, ro = 0; + + /* +@@ -555,7 +556,19 @@ again: + } + #endif + +- lock_page(page_head); ++ /* ++ * The treatment of mapping from this point on is critical. The page ++ * lock protects many things but in this context the page lock ++ * stabilizes mapping, prevents inode freeing in the shared ++ * file-backed region case and guards against movement to swap cache. ++ * ++ * Strictly speaking the page lock is not needed in all cases being ++ * considered here and page lock forces unnecessarily serialization ++ * From this point on, mapping will be re-verified if necessary and ++ * page lock will be acquired only if it is unavoidable ++ */ ++ ++ mapping = READ_ONCE(page_head->mapping); + + /* + * If page_head->mapping is NULL, then it cannot be a PageAnon +@@ -572,18 +585,31 @@ again: + * shmem_writepage move it from filecache to swapcache beneath us: + * an unlikely race, but we do need to retry for page_head->mapping. + */ +- if (!page_head->mapping) { +- int shmem_swizzled = PageSwapCache(page_head); ++ if (unlikely(!mapping)) { ++ int shmem_swizzled; ++ ++ /* ++ * Page lock is required to identify which special case above ++ * applies. If this is really a shmem page then the page lock ++ * will prevent unexpected transitions. ++ */ ++ lock_page(page); ++ shmem_swizzled = PageSwapCache(page) || page->mapping; + unlock_page(page_head); + put_page(page_head); ++ + if (shmem_swizzled) + goto again; ++ + return -EFAULT; + } + + /* + * Private mappings are handled in a simple way. + * ++ * If the futex key is stored on an anonymous page, then the associated ++ * object is the mm which is implicitly pinned by the calling process. ++ * + * NOTE: When userspace waits on a MAP_SHARED mapping, even if + * it's a read-only handle, it's expected that futexes attach to + * the object not the particular process. +@@ -601,16 +627,74 @@ again: + key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */ + key->private.mm = mm; + key->private.address = address; ++ ++ get_futex_key_refs(key); /* implies smp_mb(); (B) */ ++ + } else { ++ struct inode *inode; ++ ++ /* ++ * The associated futex object in this case is the inode and ++ * the page->mapping must be traversed. Ordinarily this should ++ * be stabilised under page lock but it's not strictly ++ * necessary in this case as we just want to pin the inode, not ++ * update the radix tree or anything like that. ++ * ++ * The RCU read lock is taken as the inode is finally freed ++ * under RCU. If the mapping still matches expectations then the ++ * mapping->host can be safely accessed as being a valid inode. ++ */ ++ rcu_read_lock(); ++ ++ if (READ_ONCE(page_head->mapping) != mapping) { ++ rcu_read_unlock(); ++ put_page(page_head); ++ ++ goto again; ++ } ++ ++ inode = READ_ONCE(mapping->host); ++ if (!inode) { ++ rcu_read_unlock(); ++ put_page(page_head); ++ ++ goto again; ++ } ++ ++ /* ++ * Take a reference unless it is about to be freed. Previously ++ * this reference was taken by ihold under the page lock ++ * pinning the inode in place so i_lock was unnecessary. The ++ * only way for this check to fail is if the inode was ++ * truncated in parallel so warn for now if this happens. ++ * ++ * We are not calling into get_futex_key_refs() in file-backed ++ * cases, therefore a successful atomic_inc return below will ++ * guarantee that get_futex_key() will still imply smp_mb(); (B). ++ */ ++ if (WARN_ON_ONCE(!atomic_inc_not_zero(&inode->i_count))) { ++ rcu_read_unlock(); ++ put_page(page_head); ++ ++ goto again; ++ } ++ ++ /* Should be impossible but lets be paranoid for now */ ++ if (WARN_ON_ONCE(inode->i_mapping != mapping)) { ++ err = -EFAULT; ++ rcu_read_unlock(); ++ iput(inode); ++ ++ goto out; ++ } ++ + key->both.offset |= FUT_OFF_INODE; /* inode-based key */ +- key->shared.inode = page_head->mapping->host; ++ key->shared.inode = inode; + key->shared.pgoff = basepage_index(page); ++ rcu_read_unlock(); + } + +- get_futex_key_refs(key); /* implies MB (B) */ +- + out: +- unlock_page(page_head); + put_page(page_head); + return err; + } +diff --git a/kernel/pid.c b/kernel/pid.c +index b17263be9082..5fe7cdb6d05f 100644 +--- a/kernel/pid.c ++++ b/kernel/pid.c +@@ -322,8 +322,10 @@ struct pid *alloc_pid(struct pid_namespace *ns) + } + + if (unlikely(is_child_reaper(pid))) { +- if (pid_ns_prepare_proc(ns)) ++ if (pid_ns_prepare_proc(ns)) { ++ disable_pid_allocation(ns); + goto out_free; ++ } + } + + get_pid_ns(ns); +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 812069b66f47..3b136fb4422c 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -2223,7 +2223,8 @@ void task_numa_work(struct callback_head *work) + return; + + +- down_read(&mm->mmap_sem); ++ if (!down_read_trylock(&mm->mmap_sem)) ++ return; + vma = find_vma(mm, start); + if (!vma) { + reset_ptenuma_scan(p); +diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c +index 89da689b6433..ac9791dd4768 100644 +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + + #include "vlan.h" +@@ -654,8 +655,11 @@ static int vlan_ethtool_get_ts_info(struct net_device *dev, + { + const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); + const struct ethtool_ops *ops = vlan->real_dev->ethtool_ops; ++ struct phy_device *phydev = vlan->real_dev->phydev; + +- if (ops->get_ts_info) { ++ if (phydev && phydev->drv && phydev->drv->ts_info) { ++ return phydev->drv->ts_info(phydev, info); ++ } else if (ops->get_ts_info) { + return ops->get_ts_info(vlan->real_dev, info); + } else { + info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 62edbf1b114e..5d0b1358c754 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -716,6 +716,7 @@ static void hci_set_event_mask_page_2(struct hci_request *req) + { + struct hci_dev *hdev = req->hdev; + u8 events[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ bool changed = false; + + /* If Connectionless Slave Broadcast master role is supported + * enable all necessary events for it. +@@ -725,6 +726,7 @@ static void hci_set_event_mask_page_2(struct hci_request *req) + events[1] |= 0x80; /* Synchronization Train Complete */ + events[2] |= 0x10; /* Slave Page Response Timeout */ + events[2] |= 0x20; /* CSB Channel Map Change */ ++ changed = true; + } + + /* If Connectionless Slave Broadcast slave role is supported +@@ -735,13 +737,24 @@ static void hci_set_event_mask_page_2(struct hci_request *req) + events[2] |= 0x02; /* CSB Receive */ + events[2] |= 0x04; /* CSB Timeout */ + events[2] |= 0x08; /* Truncated Page Complete */ ++ changed = true; + } + + /* Enable Authenticated Payload Timeout Expired event if supported */ +- if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) ++ if (lmp_ping_capable(hdev) || hdev->le_features[0] & HCI_LE_PING) { + events[2] |= 0x80; ++ changed = true; ++ } + +- hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, sizeof(events), events); ++ /* Some Broadcom based controllers indicate support for Set Event ++ * Mask Page 2 command, but then actually do not support it. Since ++ * the default value is all bits set to zero, the command is only ++ * required if the event mask has to be changed. In case no change ++ * to the event mask is needed, skip this command. ++ */ ++ if (changed) ++ hci_req_add(req, HCI_OP_SET_EVENT_MASK_PAGE_2, ++ sizeof(events), events); + } + + static void hci_init3_req(struct hci_request *req, unsigned long opt) +diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c +index bc95e48d5cfb..378c9ed00d40 100644 +--- a/net/ceph/osdmap.c ++++ b/net/ceph/osdmap.c +@@ -295,6 +295,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end) + u32 yes; + struct crush_rule *r; + ++ err = -EINVAL; + ceph_decode_32_safe(p, end, yes, bad); + if (!yes) { + dout("crush_decode NO rule %d off %x %p to %p\n", +diff --git a/net/core/dev.c b/net/core/dev.c +index b2f589012c6b..dc63c37d5301 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -989,7 +989,7 @@ bool dev_valid_name(const char *name) + { + if (*name == '\0') + return false; +- if (strlen(name) >= IFNAMSIZ) ++ if (strnlen(name, IFNAMSIZ) == IFNAMSIZ) + return false; + if (!strcmp(name, ".") || !strcmp(name, "..")) + return false; +@@ -2515,7 +2515,7 @@ __be16 skb_network_protocol(struct sk_buff *skb, int *depth) + if (unlikely(!pskb_may_pull(skb, sizeof(struct ethhdr)))) + return 0; + +- eth = (struct ethhdr *)skb_mac_header(skb); ++ eth = (struct ethhdr *)skb->data; + type = eth->h_proto; + } + +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 253c86b78ff0..33432e64804c 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -1132,10 +1132,6 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, + lladdr = neigh->ha; + } + +- if (new & NUD_CONNECTED) +- neigh->confirmed = jiffies; +- neigh->updated = jiffies; +- + /* If entry was valid and address is not changed, + do not change entry state, if new one is STALE. + */ +@@ -1159,6 +1155,16 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, + } + } + ++ /* Update timestamps only once we know we will make a change to the ++ * neighbour entry. Otherwise we risk to move the locktime window with ++ * noop updates and ignore relevant ARP updates. ++ */ ++ if (new != old || lladdr != neigh->ha) { ++ if (new & NUD_CONNECTED) ++ neigh->confirmed = jiffies; ++ neigh->updated = jiffies; ++ } ++ + if (new != old) { + neigh_del_timer(neigh); + if (new & NUD_PROBE) +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index b5c351d2830b..ccd20669ac00 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -310,6 +310,25 @@ out_undo: + goto out; + } + ++static int __net_init net_defaults_init_net(struct net *net) ++{ ++ net->core.sysctl_somaxconn = SOMAXCONN; ++ return 0; ++} ++ ++static struct pernet_operations net_defaults_ops = { ++ .init = net_defaults_init_net, ++}; ++ ++static __init int net_defaults_init(void) ++{ ++ if (register_pernet_subsys(&net_defaults_ops)) ++ panic("Cannot initialize net default settings"); ++ ++ return 0; ++} ++ ++core_initcall(net_defaults_init); + + #ifdef CONFIG_NET_NS + static struct kmem_cache *net_cachep; +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 284370b61b8c..7d3442594e0d 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -2551,7 +2551,8 @@ void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len) + { + int pos = skb_headlen(skb); + +- skb_shinfo(skb1)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; ++ skb_shinfo(skb1)->tx_flags |= skb_shinfo(skb)->tx_flags & ++ SKBTX_SHARED_FRAG; + if (len < pos) /* Split line is inside header. */ + skb_split_inside_header(skb, skb1, len, pos); + else /* Second chunk has no header, nothing to copy. */ +@@ -3115,8 +3116,8 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, + skb_copy_from_linear_data_offset(head_skb, offset, + skb_put(nskb, hsize), hsize); + +- skb_shinfo(nskb)->tx_flags = skb_shinfo(head_skb)->tx_flags & +- SKBTX_SHARED_FRAG; ++ skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags & ++ SKBTX_SHARED_FRAG; + + while (pos < offset + len) { + if (i >= nfrags) { +@@ -3329,24 +3330,18 @@ void __init skb_init(void) + NULL); + } + +-/** +- * skb_to_sgvec - Fill a scatter-gather list from a socket buffer +- * @skb: Socket buffer containing the buffers to be mapped +- * @sg: The scatter-gather list to map into +- * @offset: The offset into the buffer's contents to start mapping +- * @len: Length of buffer space to be mapped +- * +- * Fill the specified scatter-gather list with mappings/pointers into a +- * region of the buffer space attached to a socket buffer. +- */ + static int +-__skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) ++__skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len, ++ unsigned int recursion_level) + { + int start = skb_headlen(skb); + int i, copy = start - offset; + struct sk_buff *frag_iter; + int elt = 0; + ++ if (unlikely(recursion_level >= 24)) ++ return -EMSGSIZE; ++ + if (copy > 0) { + if (copy > len) + copy = len; +@@ -3365,6 +3360,8 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) + end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]); + if ((copy = end - offset) > 0) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; ++ if (unlikely(elt && sg_is_last(&sg[elt - 1]))) ++ return -EMSGSIZE; + + if (copy > len) + copy = len; +@@ -3379,16 +3376,22 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) + } + + skb_walk_frags(skb, frag_iter) { +- int end; ++ int end, ret; + + WARN_ON(start > offset + len); + + end = start + frag_iter->len; + if ((copy = end - offset) > 0) { ++ if (unlikely(elt && sg_is_last(&sg[elt - 1]))) ++ return -EMSGSIZE; ++ + if (copy > len) + copy = len; +- elt += __skb_to_sgvec(frag_iter, sg+elt, offset - start, +- copy); ++ ret = __skb_to_sgvec(frag_iter, sg+elt, offset - start, ++ copy, recursion_level + 1); ++ if (unlikely(ret < 0)) ++ return ret; ++ elt += ret; + if ((len -= copy) == 0) + return elt; + offset += copy; +@@ -3399,6 +3402,31 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) + return elt; + } + ++/** ++ * skb_to_sgvec - Fill a scatter-gather list from a socket buffer ++ * @skb: Socket buffer containing the buffers to be mapped ++ * @sg: The scatter-gather list to map into ++ * @offset: The offset into the buffer's contents to start mapping ++ * @len: Length of buffer space to be mapped ++ * ++ * Fill the specified scatter-gather list with mappings/pointers into a ++ * region of the buffer space attached to a socket buffer. Returns either ++ * the number of scatterlist items used, or -EMSGSIZE if the contents ++ * could not fit. ++ */ ++int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) ++{ ++ int nsg = __skb_to_sgvec(skb, sg, offset, len, 0); ++ ++ if (nsg <= 0) ++ return nsg; ++ ++ sg_mark_end(&sg[nsg - 1]); ++ ++ return nsg; ++} ++EXPORT_SYMBOL_GPL(skb_to_sgvec); ++ + /* As compared with skb_to_sgvec, skb_to_sgvec_nomark only map skb to given + * sglist without mark the sg which contain last skb data as the end. + * So the caller can mannipulate sg list as will when padding new data after +@@ -3421,19 +3449,11 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) + int skb_to_sgvec_nomark(struct sk_buff *skb, struct scatterlist *sg, + int offset, int len) + { +- return __skb_to_sgvec(skb, sg, offset, len); ++ return __skb_to_sgvec(skb, sg, offset, len, 0); + } + EXPORT_SYMBOL_GPL(skb_to_sgvec_nomark); + +-int skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) +-{ +- int nsg = __skb_to_sgvec(skb, sg, offset, len); + +- sg_mark_end(&sg[nsg - 1]); +- +- return nsg; +-} +-EXPORT_SYMBOL_GPL(skb_to_sgvec); + + /** + * skb_cow_data - Check that a socket buffer's data buffers are writable +@@ -3715,7 +3735,8 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, + return; + + if (tsonly) { +- skb_shinfo(skb)->tx_flags = skb_shinfo(orig_skb)->tx_flags; ++ skb_shinfo(skb)->tx_flags |= skb_shinfo(orig_skb)->tx_flags & ++ SKBTX_ANY_TSTAMP; + skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey; + } + +diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c +index 6578a0a2f708..32898247d8bf 100644 +--- a/net/core/sysctl_net_core.c ++++ b/net/core/sysctl_net_core.c +@@ -429,8 +429,6 @@ static __net_init int sysctl_core_net_init(struct net *net) + { + struct ctl_table *tbl; + +- net->core.sysctl_somaxconn = SOMAXCONN; +- + tbl = netns_core_table; + if (!net_eq(net, &init_net)) { + tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); +diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c +index a548be247e15..47b397264f24 100644 +--- a/net/ieee802154/socket.c ++++ b/net/ieee802154/socket.c +@@ -302,12 +302,12 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) + skb->sk = sk; + skb->protocol = htons(ETH_P_IEEE802154); + +- dev_put(dev); +- + err = dev_queue_xmit(skb); + if (err > 0) + err = net_xmit_errno(err); + ++ dev_put(dev); ++ + return err ?: size; + + out_skb: +@@ -689,12 +689,12 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) + skb->sk = sk; + skb->protocol = htons(ETH_P_IEEE802154); + +- dev_put(dev); +- + err = dev_queue_xmit(skb); + if (err > 0) + err = net_xmit_errno(err); + ++ dev_put(dev); ++ + return err ?: size; + + out_skb: +diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c +index 22377c8ff14b..e8f862358518 100644 +--- a/net/ipv4/ah4.c ++++ b/net/ipv4/ah4.c +@@ -220,7 +220,9 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) + ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.low); + + sg_init_table(sg, nfrags + sglists); +- skb_to_sgvec_nomark(skb, sg, 0, skb->len); ++ err = skb_to_sgvec_nomark(skb, sg, 0, skb->len); ++ if (unlikely(err < 0)) ++ goto out_free; + + if (x->props.flags & XFRM_STATE_ESN) { + /* Attach seqhi sg right after packet payload */ +@@ -393,7 +395,9 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) + skb_push(skb, ihl); + + sg_init_table(sg, nfrags + sglists); +- skb_to_sgvec_nomark(skb, sg, 0, skb->len); ++ err = skb_to_sgvec_nomark(skb, sg, 0, skb->len); ++ if (unlikely(err < 0)) ++ goto out_free; + + if (x->props.flags & XFRM_STATE_ESN) { + /* Attach seqhi sg right after packet payload */ +diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c +index cb5eb649ad5f..bfa79831873f 100644 +--- a/net/ipv4/arp.c ++++ b/net/ipv4/arp.c +@@ -437,7 +437,7 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) + /*unsigned long now; */ + struct net *net = dev_net(dev); + +- rt = ip_route_output(net, sip, tip, 0, 0); ++ rt = ip_route_output(net, sip, tip, 0, l3mdev_master_ifindex_rcu(dev)); + if (IS_ERR(rt)) + return 1; + if (rt->dst.dev != dev) { +@@ -658,6 +658,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb) + unsigned char *arp_ptr; + struct rtable *rt; + unsigned char *sha; ++ unsigned char *tha = NULL; + __be32 sip, tip; + u16 dev_type = dev->type; + int addr_type; +@@ -729,6 +730,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb) + break; + #endif + default: ++ tha = arp_ptr; + arp_ptr += dev->addr_len; + } + memcpy(&tip, arp_ptr, 4); +@@ -839,8 +841,18 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb) + It is possible, that this option should be enabled for some + devices (strip is candidate) + */ +- is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip && +- addr_type == RTN_UNICAST; ++ is_garp = tip == sip && addr_type == RTN_UNICAST; ++ ++ /* Unsolicited ARP _replies_ also require target hwaddr to be ++ * the same as source. ++ */ ++ if (is_garp && arp->ar_op == htons(ARPOP_REPLY)) ++ is_garp = ++ /* IPv4 over IEEE 1394 doesn't provide target ++ * hardware address field in its ARP payload. ++ */ ++ tha && ++ !memcmp(tha, sha, dev->addr_len); + + if (!n && + ((arp->ar_op == htons(ARPOP_REPLY) && +diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c +index 20fb25e3027b..3d8021d55336 100644 +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -268,10 +268,11 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) + esph->spi = x->id.spi; + + sg_init_table(sg, nfrags); +- skb_to_sgvec(skb, sg, +- (unsigned char *)esph - skb->data, +- assoclen + ivlen + clen + alen); +- ++ err = skb_to_sgvec(skb, sg, ++ (unsigned char *)esph - skb->data, ++ assoclen + ivlen + clen + alen); ++ if (unlikely(err < 0)) ++ goto error; + aead_request_set_crypt(req, sg, sg, ivlen + clen, iv); + aead_request_set_ad(req, assoclen); + +@@ -481,7 +482,9 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) + } + + sg_init_table(sg, nfrags); +- skb_to_sgvec(skb, sg, 0, skb->len); ++ err = skb_to_sgvec(skb, sg, 0, skb->len); ++ if (unlikely(err < 0)) ++ goto out; + + aead_request_set_crypt(req, sg, sg, elen + ivlen, iv); + aead_request_set_ad(req, assoclen); +diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c +index 80e2d1b0c08c..3d62feb65932 100644 +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -253,13 +253,14 @@ static struct net_device *__ip_tunnel_create(struct net *net, + struct net_device *dev; + char name[IFNAMSIZ]; + +- if (parms->name[0]) ++ err = -E2BIG; ++ if (parms->name[0]) { ++ if (!dev_valid_name(parms->name)) ++ goto failed; + strlcpy(name, parms->name, IFNAMSIZ); +- else { +- if (strlen(ops->kind) > (IFNAMSIZ - 3)) { +- err = -E2BIG; ++ } else { ++ if (strlen(ops->kind) > (IFNAMSIZ - 3)) + goto failed; +- } + strlcpy(name, ops->kind, IFNAMSIZ); + strncat(name, "%d", 2); + } +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 75433ed6714b..96115d1e0d90 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -117,6 +117,7 @@ int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2; + #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ + #define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ + #define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ ++#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ + + #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) + #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) +@@ -3543,7 +3544,8 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + if (before(ack, prior_snd_una)) { + /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */ + if (before(ack, prior_snd_una - tp->max_window)) { +- tcp_send_challenge_ack(sk, skb); ++ if (!(flag & FLAG_NO_CHALLENGE_ACK)) ++ tcp_send_challenge_ack(sk, skb); + return -1; + } + goto old_ack; +@@ -5832,13 +5834,17 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) + + /* step 5: check the ACK field */ + acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH | +- FLAG_UPDATE_TS_RECENT) > 0; ++ FLAG_UPDATE_TS_RECENT | ++ FLAG_NO_CHALLENGE_ACK) > 0; + ++ if (!acceptable) { ++ if (sk->sk_state == TCP_SYN_RECV) ++ return 1; /* send one RST */ ++ tcp_send_challenge_ack(sk, skb); ++ goto discard; ++ } + switch (sk->sk_state) { + case TCP_SYN_RECV: +- if (!acceptable) +- return 1; +- + if (!tp->srtt_us) + tcp_synack_rtt_meas(sk, req); + +@@ -5907,14 +5913,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) + * our SYNACK so stop the SYNACK timer. + */ + if (req) { +- /* Return RST if ack_seq is invalid. +- * Note that RFC793 only says to generate a +- * DUPACK for it but for TCP Fast Open it seems +- * better to treat this case like TCP_SYN_RECV +- * above. +- */ +- if (!acceptable) +- return 1; + /* We no longer need the request sock. */ + reqsk_fastopen_remove(sk, req, false); + tcp_rearm_rto(sk); +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 92174881844d..0613be57513e 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -957,7 +957,10 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, + INIT_HLIST_NODE(&ifa->addr_lst); + ifa->scope = scope; + ifa->prefix_len = pfxlen; +- ifa->flags = flags | IFA_F_TENTATIVE; ++ ifa->flags = flags; ++ /* No need to add the TENTATIVE flag for addresses with NODAD */ ++ if (!(flags & IFA_F_NODAD)) ++ ifa->flags |= IFA_F_TENTATIVE; + ifa->valid_lft = valid_lft; + ifa->prefered_lft = prefered_lft; + ifa->cstamp = ifa->tstamp = jiffies; +diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c +index 0630a4d5daaa..0edc44cb254e 100644 +--- a/net/ipv6/ah6.c ++++ b/net/ipv6/ah6.c +@@ -423,7 +423,9 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) + ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.low); + + sg_init_table(sg, nfrags + sglists); +- skb_to_sgvec_nomark(skb, sg, 0, skb->len); ++ err = skb_to_sgvec_nomark(skb, sg, 0, skb->len); ++ if (unlikely(err < 0)) ++ goto out_free; + + if (x->props.flags & XFRM_STATE_ESN) { + /* Attach seqhi sg right after packet payload */ +@@ -603,7 +605,9 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) + ip6h->hop_limit = 0; + + sg_init_table(sg, nfrags + sglists); +- skb_to_sgvec_nomark(skb, sg, 0, skb->len); ++ err = skb_to_sgvec_nomark(skb, sg, 0, skb->len); ++ if (unlikely(err < 0)) ++ goto out_free; + + if (x->props.flags & XFRM_STATE_ESN) { + /* Attach seqhi sg right after packet payload */ +diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c +index 111ba55fd512..6a924be66e37 100644 +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -248,9 +248,11 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) + esph->spi = x->id.spi; + + sg_init_table(sg, nfrags); +- skb_to_sgvec(skb, sg, +- (unsigned char *)esph - skb->data, +- assoclen + ivlen + clen + alen); ++ err = skb_to_sgvec(skb, sg, ++ (unsigned char *)esph - skb->data, ++ assoclen + ivlen + clen + alen); ++ if (unlikely(err < 0)) ++ goto error; + + aead_request_set_crypt(req, sg, sg, ivlen + clen, iv); + aead_request_set_ad(req, assoclen); +@@ -423,7 +425,9 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) + } + + sg_init_table(sg, nfrags); +- skb_to_sgvec(skb, sg, 0, skb->len); ++ ret = skb_to_sgvec(skb, sg, 0, skb->len); ++ if (unlikely(ret < 0)) ++ goto out; + + aead_request_set_crypt(req, sg, sg, elen + ivlen, iv); + aead_request_set_ad(req, assoclen); +diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c +index 9ada1095c1cd..b25f4ad28b03 100644 +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -320,11 +320,13 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net, + if (t || !create) + return t; + +- if (parms->name[0]) ++ if (parms->name[0]) { ++ if (!dev_valid_name(parms->name)) ++ return NULL; + strlcpy(name, parms->name, IFNAMSIZ); +- else ++ } else { + strcpy(name, "ip6gre%d"); +- ++ } + dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, + ip6gre_tunnel_setup); + if (!dev) +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 3ef81c387923..bfa710e8b615 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -340,6 +340,10 @@ static int ip6_forward_proxy_check(struct sk_buff *skb) + static inline int ip6_forward_finish(struct net *net, struct sock *sk, + struct sk_buff *skb) + { ++ struct dst_entry *dst = skb_dst(skb); ++ ++ IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); ++ IP6_ADD_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTOCTETS, skb->len); + skb_sender_cpu_clear(skb); + return dst_output(net, sk, skb); + } +@@ -534,8 +538,6 @@ int ip6_forward(struct sk_buff *skb) + + hdr->hop_limit--; + +- IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); +- IP6_ADD_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTOCTETS, skb->len); + return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, + net, NULL, skb, skb->dev, dst->dev, + ip6_forward_finish); +@@ -1276,7 +1278,7 @@ static int __ip6_append_data(struct sock *sk, + unsigned int flags, int dontfrag) + { + struct sk_buff *skb, *skb_prev = NULL; +- unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu; ++ unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu; + int exthdrlen = 0; + int dst_exthdrlen = 0; + int hh_len; +@@ -1312,6 +1314,12 @@ static int __ip6_append_data(struct sock *sk, + sizeof(struct frag_hdr) : 0) + + rt->rt6i_nfheader_len; + ++ /* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit ++ * the first fragment ++ */ ++ if (headersize + transhdrlen > mtu) ++ goto emsgsize; ++ + if (cork->length + length > mtu - headersize && dontfrag && + (sk->sk_protocol == IPPROTO_UDP || + sk->sk_protocol == IPPROTO_RAW)) { +@@ -1327,9 +1335,8 @@ static int __ip6_append_data(struct sock *sk, + + if (cork->length + length > maxnonfragsize - headersize) { + emsgsize: +- ipv6_local_error(sk, EMSGSIZE, fl6, +- mtu - headersize + +- sizeof(struct ipv6hdr)); ++ pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0); ++ ipv6_local_error(sk, EMSGSIZE, fl6, pmtu); + return -EMSGSIZE; + } + +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index 946c2d015b94..e8f21dd520b2 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -286,13 +286,16 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) + struct net_device *dev; + struct ip6_tnl *t; + char name[IFNAMSIZ]; +- int err = -ENOMEM; ++ int err = -E2BIG; + +- if (p->name[0]) ++ if (p->name[0]) { ++ if (!dev_valid_name(p->name)) ++ goto failed; + strlcpy(name, p->name, IFNAMSIZ); +- else ++ } else { + sprintf(name, "ip6tnl%%d"); +- ++ } ++ err = -ENOMEM; + dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, + ip6_tnl_dev_setup); + if (!dev) +diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c +index d7105422bc63..40bb7a5e6d47 100644 +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -212,10 +212,13 @@ static struct ip6_tnl *vti6_tnl_create(struct net *net, struct __ip6_tnl_parm *p + char name[IFNAMSIZ]; + int err; + +- if (p->name[0]) ++ if (p->name[0]) { ++ if (!dev_valid_name(p->name)) ++ goto failed; + strlcpy(name, p->name, IFNAMSIZ); +- else ++ } else { + sprintf(name, "ip6_vti%%d"); ++ } + + dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, vti6_dev_setup); + if (!dev) +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 48db6f5cec2c..99920fcea97c 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -851,6 +851,9 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net, + struct fib6_node *fn; + struct rt6_info *rt; + ++ if (fl6->flowi6_flags & FLOWI_FLAG_SKIP_NH_OIF) ++ flags &= ~RT6_LOOKUP_F_IFACE; ++ + read_lock_bh(&table->tb6_lock); + fn = fib6_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); + restart: +diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c +index bbba435d0639..51f7c32f04d7 100644 +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -244,11 +244,13 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, + if (!create) + goto failed; + +- if (parms->name[0]) ++ if (parms->name[0]) { ++ if (!dev_valid_name(parms->name)) ++ goto failed; + strlcpy(name, parms->name, IFNAMSIZ); +- else ++ } else { + strcpy(name, "sit%d"); +- ++ } + dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, + ipip6_tunnel_setup); + if (!dev) +@@ -690,6 +692,7 @@ static int ipip6_rcv(struct sk_buff *skb) + + if (iptunnel_pull_header(skb, 0, htons(ETH_P_IPV6))) + goto out; ++ iph = ip_hdr(skb); + + err = IP_ECN_decapsulate(iph, skb); + if (unlikely(err)) { +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 6482b001f19a..15150b412930 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -3305,7 +3305,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, + p += pol->sadb_x_policy_len*8; + sec_ctx = (struct sadb_x_sec_ctx *)p; + if (len < pol->sadb_x_policy_len*8 + +- sec_ctx->sadb_x_sec_len) { ++ sec_ctx->sadb_x_sec_len*8) { + *dir = -EINVAL; + goto out; + } +diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c +index fb3248ff8b48..ae3438685caa 100644 +--- a/net/l2tp/l2tp_netlink.c ++++ b/net/l2tp/l2tp_netlink.c +@@ -732,6 +732,8 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl + + if ((session->ifname[0] && + nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) || ++ (session->offset && ++ nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) || + (session->cookie_len && + nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len, + &session->cookie[0])) || +diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c +index bb8edb9ef506..1e698768aca8 100644 +--- a/net/llc/af_llc.c ++++ b/net/llc/af_llc.c +@@ -309,6 +309,8 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) + int rc = -EINVAL; + + dprintk("%s: binding %02X\n", __func__, addr->sllc_sap); ++ ++ lock_sock(sk); + if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))) + goto out; + rc = -EAFNOSUPPORT; +@@ -380,6 +382,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) + out_put: + llc_sap_put(sap); + out: ++ release_sock(sk); + return rc; + } + +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 23095d5e0199..005cd8796505 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -4326,6 +4326,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, + if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) + return -EINVAL; + ++ /* If a reconfig is happening, bail out */ ++ if (local->in_reconfig) ++ return -EBUSY; ++ + if (assoc) { + rcu_read_lock(); + have_sta = sta_info_get(sdata, cbss->bssid); +diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c +index 4ece07c68b3f..c68e020427ab 100644 +--- a/net/netfilter/nf_conntrack_netlink.c ++++ b/net/netfilter/nf_conntrack_netlink.c +@@ -887,8 +887,13 @@ restart: + } + out: + local_bh_enable(); +- if (last) ++ if (last) { ++ /* nf ct hash resize happened, now clear the leftover. */ ++ if ((struct nf_conn *)cb->args[1] == last) ++ cb->args[1] = 0; ++ + nf_ct_put(last); ++ } + + return skb->len; + } +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 48e1608414e6..98fe9691337c 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1054,6 +1054,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, + if (addr->sa_family != AF_NETLINK) + return -EINVAL; + ++ if (alen < sizeof(struct sockaddr_nl)) ++ return -EINVAL; ++ + if ((nladdr->nl_groups || nladdr->nl_pid) && + !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) + return -EPERM; +diff --git a/net/rds/bind.c b/net/rds/bind.c +index b22ea956522b..e29b47193645 100644 +--- a/net/rds/bind.c ++++ b/net/rds/bind.c +@@ -108,6 +108,7 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port) + rs, &addr, (int)ntohs(*port)); + break; + } else { ++ rs->rs_bound_addr = 0; + rds_sock_put(rs); + ret = -ENOMEM; + break; +diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c +index d7a9ab5a9d9c..6c65fb229e50 100644 +--- a/net/rxrpc/rxkad.c ++++ b/net/rxrpc/rxkad.c +@@ -209,7 +209,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, + struct sk_buff *trailer; + unsigned int len; + u16 check; +- int nsg; ++ int nsg, err; + + sp = rxrpc_skb(skb); + +@@ -240,7 +240,9 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call, + len &= ~(call->conn->size_align - 1); + + sg_init_table(sg, nsg); +- skb_to_sgvec(skb, sg, 0, len); ++ err = skb_to_sgvec(skb, sg, 0, len); ++ if (unlikely(err < 0)) ++ return err; + crypto_blkcipher_encrypt_iv(&desc, sg, sg, len); + + _leave(" = 0"); +@@ -336,7 +338,7 @@ static int rxkad_verify_packet_auth(const struct rxrpc_call *call, + struct sk_buff *trailer; + u32 data_size, buf; + u16 check; +- int nsg; ++ int nsg, ret; + + _enter(""); + +@@ -348,7 +350,9 @@ static int rxkad_verify_packet_auth(const struct rxrpc_call *call, + goto nomem; + + sg_init_table(sg, nsg); +- skb_to_sgvec(skb, sg, 0, 8); ++ ret = skb_to_sgvec(skb, sg, 0, 8); ++ if (unlikely(ret < 0)) ++ return ret; + + /* start the decryption afresh */ + memset(&iv, 0, sizeof(iv)); +@@ -411,7 +415,7 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call, + struct sk_buff *trailer; + u32 data_size, buf; + u16 check; +- int nsg; ++ int nsg, ret; + + _enter(",{%d}", skb->len); + +@@ -430,7 +434,12 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call, + } + + sg_init_table(sg, nsg); +- skb_to_sgvec(skb, sg, 0, skb->len); ++ ret = skb_to_sgvec(skb, sg, 0, skb->len); ++ if (unlikely(ret < 0)) { ++ if (sg != _sg) ++ kfree(sg); ++ return ret; ++ } + + /* decrypt from the session key */ + token = call->conn->key->payload.data[0]; +diff --git a/net/sched/act_api.c b/net/sched/act_api.c +index 694a06f1e0d5..f44fea22d69c 100644 +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -101,8 +101,10 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb, + a->order = n_i; + + nest = nla_nest_start(skb, a->order); +- if (nest == NULL) ++ if (nest == NULL) { ++ index--; + goto nla_put_failure; ++ } + err = tcf_action_dump_1(skb, a, 0, 0); + if (err < 0) { + index--; +diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c +index 0bc6f912f870..bd155e59be1c 100644 +--- a/net/sched/act_bpf.c ++++ b/net/sched/act_bpf.c +@@ -249,10 +249,14 @@ static int tcf_bpf_init_from_efd(struct nlattr **tb, struct tcf_bpf_cfg *cfg) + + static void tcf_bpf_cfg_cleanup(const struct tcf_bpf_cfg *cfg) + { +- if (cfg->is_ebpf) +- bpf_prog_put(cfg->filter); +- else +- bpf_prog_destroy(cfg->filter); ++ struct bpf_prog *filter = cfg->filter; ++ ++ if (filter) { ++ if (cfg->is_ebpf) ++ bpf_prog_put(filter); ++ else ++ bpf_prog_destroy(filter); ++ } + + kfree(cfg->bpf_ops); + kfree(cfg->bpf_name); +diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c +index 481806b43de8..edb8514b4e00 100644 +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -723,8 +723,10 @@ static int sctp_v6_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr) + sctp_v6_map_v4(addr); + } + +- if (addr->sa.sa_family == AF_INET) ++ if (addr->sa.sa_family == AF_INET) { ++ memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero)); + return sizeof(struct sockaddr_in); ++ } + return sizeof(struct sockaddr_in6); + } + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index df6a4b2d0728..13c7f42b7040 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -335,11 +335,14 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt, + if (!opt->pf->af_supported(addr->sa.sa_family, opt)) + return NULL; + +- /* V4 mapped address are really of AF_INET family */ +- if (addr->sa.sa_family == AF_INET6 && +- ipv6_addr_v4mapped(&addr->v6.sin6_addr) && +- !opt->pf->af_supported(AF_INET, opt)) +- return NULL; ++ if (addr->sa.sa_family == AF_INET6) { ++ if (len < SIN6_LEN_RFC2133) ++ return NULL; ++ /* V4 mapped address are really of AF_INET family */ ++ if (ipv6_addr_v4mapped(&addr->v6.sin6_addr) && ++ !opt->pf->af_supported(AF_INET, opt)) ++ return NULL; ++ } + + /* If we get this far, af is valid. */ + af = sctp_get_af_specific(addr->sa.sa_family); +@@ -1518,7 +1521,7 @@ static void sctp_close(struct sock *sk, long timeout) + + pr_debug("%s: sk:%p, timeout:%ld\n", __func__, sk, timeout); + +- lock_sock(sk); ++ lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + sk->sk_shutdown = SHUTDOWN_MASK; + sk->sk_state = SCTP_SS_CLOSING; + +@@ -1569,7 +1572,7 @@ static void sctp_close(struct sock *sk, long timeout) + * held and that should be grabbed before socket lock. + */ + spin_lock_bh(&net->sctp.addr_wq_lock); +- bh_lock_sock(sk); ++ bh_lock_sock_nested(sk); + + /* Hold the sock, since sk_common_release() will put sock_put() + * and we have just a little more cleanup. +diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c +index 728d65fbab0c..c9c0976d3bbb 100644 +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -2363,7 +2363,12 @@ static void xs_tcp_setup_socket(struct work_struct *work) + case -EHOSTUNREACH: + case -EADDRINUSE: + case -ENOBUFS: +- /* retry with existing socket, after a delay */ ++ /* ++ * xs_tcp_force_close() wakes tasks with -EIO. ++ * We need to wake them first to ensure the ++ * correct error code. ++ */ ++ xprt_wake_pending_tasks(xprt, status); + xs_tcp_force_close(xprt); + goto out; + } +diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c +index a750f330b8dd..c6ab4da4b8e2 100644 +--- a/net/x25/af_x25.c ++++ b/net/x25/af_x25.c +@@ -1794,32 +1794,40 @@ void x25_kill_by_neigh(struct x25_neigh *nb) + + static int __init x25_init(void) + { +- int rc = proto_register(&x25_proto, 0); ++ int rc; + +- if (rc != 0) ++ rc = proto_register(&x25_proto, 0); ++ if (rc) + goto out; + + rc = sock_register(&x25_family_ops); +- if (rc != 0) ++ if (rc) + goto out_proto; + + dev_add_pack(&x25_packet_type); + + rc = register_netdevice_notifier(&x25_dev_notifier); +- if (rc != 0) ++ if (rc) + goto out_sock; + +- pr_info("Linux Version 0.2\n"); ++ rc = x25_register_sysctl(); ++ if (rc) ++ goto out_dev; + +- x25_register_sysctl(); + rc = x25_proc_init(); +- if (rc != 0) +- goto out_dev; ++ if (rc) ++ goto out_sysctl; ++ ++ pr_info("Linux Version 0.2\n"); ++ + out: + return rc; ++out_sysctl: ++ x25_unregister_sysctl(); + out_dev: + unregister_netdevice_notifier(&x25_dev_notifier); + out_sock: ++ dev_remove_pack(&x25_packet_type); + sock_unregister(AF_X25); + out_proto: + proto_unregister(&x25_proto); +diff --git a/net/x25/sysctl_net_x25.c b/net/x25/sysctl_net_x25.c +index 43239527a205..703d46aae7a2 100644 +--- a/net/x25/sysctl_net_x25.c ++++ b/net/x25/sysctl_net_x25.c +@@ -73,9 +73,12 @@ static struct ctl_table x25_table[] = { + { 0, }, + }; + +-void __init x25_register_sysctl(void) ++int __init x25_register_sysctl(void) + { + x25_table_header = register_net_sysctl(&init_net, "net/x25", x25_table); ++ if (!x25_table_header) ++ return -ENOMEM; ++ return 0; + } + + void x25_unregister_sysctl(void) +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index 34b5b4bcf5cb..62d87f859566 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -1208,6 +1208,8 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig) + x->curlft.add_time = orig->curlft.add_time; + x->km.state = orig->km.state; + x->km.seq = orig->km.seq; ++ x->replay = orig->replay; ++ x->preplay = orig->preplay; + + return x; + +diff --git a/scripts/tags.sh b/scripts/tags.sh +index 262889046703..45e246595d10 100755 +--- a/scripts/tags.sh ++++ b/scripts/tags.sh +@@ -106,6 +106,7 @@ all_compiled_sources() + case "$i" in + *.[cS]) + j=${i/\.[cS]/\.o} ++ j="${j#$tree}" + if [ -e $j ]; then + echo $i + fi +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index 4f690ab0feed..99212ff6a568 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -1942,8 +1942,9 @@ static inline u32 file_to_av(struct file *file) + static inline u32 open_file_to_av(struct file *file) + { + u32 av = file_to_av(file); ++ struct inode *inode = file_inode(file); + +- if (selinux_policycap_openperm) ++ if (selinux_policycap_openperm && inode->i_sb->s_magic != SOCKFS_MAGIC) + av |= FILE__OPEN; + + return av; +@@ -2912,6 +2913,7 @@ static int selinux_inode_permission(struct inode *inode, int mask) + static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) + { + const struct cred *cred = current_cred(); ++ struct inode *inode = d_backing_inode(dentry); + unsigned int ia_valid = iattr->ia_valid; + __u32 av = FILE__WRITE; + +@@ -2927,8 +2929,10 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) + ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) + return dentry_has_perm(cred, dentry, FILE__SETATTR); + +- if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE) +- && !(ia_valid & ATTR_FILE)) ++ if (selinux_policycap_openperm && ++ inode->i_sb->s_magic != SOCKFS_MAGIC && ++ (ia_valid & ATTR_SIZE) && ++ !(ia_valid & ATTR_FILE)) + av |= FILE__OPEN; + + return dentry_has_perm(cred, dentry, av); +diff --git a/sound/soc/intel/atom/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c +index a74c64c7053c..e83da42a8c03 100644 +--- a/sound/soc/intel/atom/sst/sst_stream.c ++++ b/sound/soc/intel/atom/sst/sst_stream.c +@@ -221,7 +221,7 @@ int sst_send_byte_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, + sst_free_block(sst_drv_ctx, block); + out: + test_and_clear_bit(pvt_id, &sst_drv_ctx->pvt_id); +- return 0; ++ return ret; + } + + /* +diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c +index 38d65a3529c4..44d560966e9c 100644 +--- a/sound/soc/intel/boards/cht_bsw_rt5645.c ++++ b/sound/soc/intel/boards/cht_bsw_rt5645.c +@@ -96,6 +96,7 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), ++ SND_SOC_DAPM_MIC("Int Analog Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, + platform_clock_control, SND_SOC_DAPM_POST_PMD), +@@ -106,6 +107,8 @@ static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = { + {"IN1N", NULL, "Headset Mic"}, + {"DMIC L1", NULL, "Int Mic"}, + {"DMIC R1", NULL, "Int Mic"}, ++ {"IN2P", NULL, "Int Analog Mic"}, ++ {"IN2N", NULL, "Int Analog Mic"}, + {"Headphone", NULL, "HPOL"}, + {"Headphone", NULL, "HPOR"}, + {"Ext Spk", NULL, "SPOL"}, +@@ -119,6 +122,9 @@ static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = { + {"Headphone", NULL, "Platform Clock"}, + {"Headset Mic", NULL, "Platform Clock"}, + {"Int Mic", NULL, "Platform Clock"}, ++ {"Int Analog Mic", NULL, "Platform Clock"}, ++ {"Int Analog Mic", NULL, "micbias1"}, ++ {"Int Analog Mic", NULL, "micbias2"}, + {"Ext Spk", NULL, "Platform Clock"}, + }; + +@@ -147,6 +153,7 @@ static const struct snd_kcontrol_new cht_mc_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Int Mic"), ++ SOC_DAPM_PIN_SWITCH("Int Analog Mic"), + SOC_DAPM_PIN_SWITCH("Ext Spk"), + }; + +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +index a001331a53c1..df79d7c846ea 100644 +--- a/sound/soc/sh/rcar/ssi.c ++++ b/sound/soc/sh/rcar/ssi.c +@@ -453,6 +453,13 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + u32 *buf = (u32 *)(runtime->dma_area + + rsnd_dai_pointer_offset(io, 0)); ++ int shift = 0; ++ ++ switch (runtime->sample_bits) { ++ case 32: ++ shift = 8; ++ break; ++ } + + /* + * 8/16/32 data can be assesse to TDR/RDR register +@@ -460,9 +467,9 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, + * see rsnd_ssi_init() + */ + if (rsnd_io_is_play(io)) +- rsnd_mod_write(mod, SSITDR, *buf); ++ rsnd_mod_write(mod, SSITDR, (*buf) << shift); + else +- *buf = rsnd_mod_read(mod, SSIRDR); ++ *buf = (rsnd_mod_read(mod, SSIRDR) >> shift); + + elapsed = rsnd_dai_pointer_update(io, sizeof(*buf)); + } +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index ebe7115c751a..da8afc121118 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -1152,6 +1152,10 @@ static struct syscall_fmt { + { .name = "mlockall", .errmsg = true, + .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, + { .name = "mmap", .hexret = true, ++/* The standard mmap maps to old_mmap on s390x */ ++#if defined(__s390x__) ++ .alias = "old_mmap", ++#endif + .arg_scnprintf = { [0] = SCA_HEX, /* addr */ + [2] = SCA_MMAP_PROT, /* prot */ + [3] = SCA_MMAP_FLAGS, /* flags */ +diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c +index a767a6400c5c..6ea4fcfaab36 100644 +--- a/tools/perf/tests/code-reading.c ++++ b/tools/perf/tests/code-reading.c +@@ -182,6 +182,8 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, + unsigned char buf2[BUFSZ]; + size_t ret_len; + u64 objdump_addr; ++ const char *objdump_name; ++ char decomp_name[KMOD_DECOMP_LEN]; + int ret; + + pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); +@@ -242,9 +244,25 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, + state->done[state->done_cnt++] = al.map->start; + } + ++ objdump_name = al.map->dso->long_name; ++ if (dso__needs_decompress(al.map->dso)) { ++ if (dso__decompress_kmodule_path(al.map->dso, objdump_name, ++ decomp_name, ++ sizeof(decomp_name)) < 0) { ++ pr_debug("decompression failed\n"); ++ return -1; ++ } ++ ++ objdump_name = decomp_name; ++ } ++ + /* Read the object code using objdump */ + objdump_addr = map__rip_2objdump(al.map, al.addr); +- ret = read_via_objdump(al.map->dso->long_name, objdump_addr, buf2, len); ++ ret = read_via_objdump(objdump_name, objdump_addr, buf2, len); ++ ++ if (dso__needs_decompress(al.map->dso)) ++ unlink(objdump_name); ++ + if (ret > 0) { + /* + * The kernel maps are inaccurate - assume objdump is right in +diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c +index 43838003c1a1..304f5d710143 100644 +--- a/tools/perf/util/header.c ++++ b/tools/perf/util/header.c +@@ -1258,8 +1258,16 @@ static int __event_process_build_id(struct build_id_event *bev, + + dso__set_build_id(dso, &bev->build_id); + +- if (!is_kernel_module(filename, cpumode)) +- dso->kernel = dso_type; ++ if (dso_type != DSO_TYPE_USER) { ++ struct kmod_path m = { .name = NULL, }; ++ ++ if (!kmod_path__parse_name(&m, filename) && m.kmod) ++ dso__set_short_name(dso, strdup(m.name), true); ++ else ++ dso->kernel = dso_type; ++ ++ free(m.name); ++ } + + build_id__sprintf(dso->build_id, sizeof(dso->build_id), + sbuild_id); +diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c +index 03875f9154e7..0195b7e8c54a 100644 +--- a/tools/perf/util/probe-event.c ++++ b/tools/perf/util/probe-event.c +@@ -2349,6 +2349,14 @@ static int get_new_event_name(char *buf, size_t len, const char *base, + + out: + free(nbase); ++ ++ /* Final validation */ ++ if (ret >= 0 && !is_c_func_name(buf)) { ++ pr_warning("Internal error: \"%s\" is an invalid event name.\n", ++ buf); ++ ret = -EINVAL; ++ } ++ + return ret; + } + +diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c +index 2dcfe9a7c8d0..60edec383281 100644 +--- a/tools/perf/util/unwind-libdw.c ++++ b/tools/perf/util/unwind-libdw.c +@@ -37,6 +37,14 @@ static int __report_module(struct addr_location *al, u64 ip, + return 0; + + mod = dwfl_addrmodule(ui->dwfl, ip); ++ if (mod) { ++ Dwarf_Addr s; ++ ++ dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL); ++ if (s != al->map->start) ++ mod = 0; ++ } ++ + if (!mod) + mod = dwfl_report_elf(ui->dwfl, dso->short_name, + dso->long_name, -1, al->map->start, +diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c +index 47b1e36c7ea0..9adc9af8b048 100644 +--- a/tools/perf/util/util.c ++++ b/tools/perf/util/util.c +@@ -162,7 +162,7 @@ int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) + + size -= ret; + off_in += ret; +- off_out -= ret; ++ off_out += ret; + } + munmap(ptr, off_in + size); + +diff --git a/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c b/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c +index 42d4c8caad81..de8dc82e2567 100644 +--- a/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c ++++ b/tools/testing/selftests/powerpc/tm/tm-resched-dscr.c +@@ -45,12 +45,12 @@ int test_body(void) + printf("Check DSCR TM context switch: "); + fflush(stdout); + for (;;) { +- rv = 1; + asm __volatile__ ( + /* set a known value into the DSCR */ + "ld 3, %[dscr1];" + "mtspr %[sprn_dscr], 3;" + ++ "li %[rv], 1;" + /* start and suspend a transaction */ + TBEGIN + "beq 1f;" diff --git a/patch/kernel/rk3328-default/04-patch-4.4.128-129.patch b/patch/kernel/rk3328-default/04-patch-4.4.128-129.patch new file mode 100644 index 000000000..2bc7958c1 --- /dev/null +++ b/patch/kernel/rk3328-default/04-patch-4.4.128-129.patch @@ -0,0 +1,3475 @@ +diff --git a/Makefile b/Makefile +index 575459bb47eb..096d7e867b6c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 128 ++SUBLEVEL = 129 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arm/boot/dts/at91sam9g25.dtsi b/arch/arm/boot/dts/at91sam9g25.dtsi +index a7da0dd0c98f..0898213f3bb2 100644 +--- a/arch/arm/boot/dts/at91sam9g25.dtsi ++++ b/arch/arm/boot/dts/at91sam9g25.dtsi +@@ -21,7 +21,7 @@ + atmel,mux-mask = < + /* A B C */ + 0xffffffff 0xffe0399f 0xc000001c /* pioA */ +- 0x0007ffff 0x8000fe3f 0x00000000 /* pioB */ ++ 0x0007ffff 0x00047e3f 0x00000000 /* pioB */ + 0x80000000 0x07c0ffff 0xb83fffff /* pioC */ + 0x003fffff 0x003f8000 0x00000000 /* pioD */ + >; +diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi +index 3daf8d5d7878..fb0d1b252dc8 100644 +--- a/arch/arm/boot/dts/sama5d4.dtsi ++++ b/arch/arm/boot/dts/sama5d4.dtsi +@@ -1354,7 +1354,7 @@ + pinctrl@fc06a000 { + #address-cells = <1>; + #size-cells = <1>; +- compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; ++ compatible = "atmel,sama5d3-pinctrl", "atmel,at91sam9x5-pinctrl", "simple-bus"; + ranges = <0xfc068000 0xfc068000 0x100 + 0xfc06a000 0xfc06a000 0x4000>; + /* WARNING: revisit as pin spec has changed */ +diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h +index c74c32ccc647..4f281768937f 100644 +--- a/arch/mips/include/asm/uaccess.h ++++ b/arch/mips/include/asm/uaccess.h +@@ -1238,6 +1238,13 @@ __clear_user(void __user *addr, __kernel_size_t size) + { + __kernel_size_t res; + ++#ifdef CONFIG_CPU_MICROMIPS ++/* micromips memset / bzero also clobbers t7 & t8 */ ++#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$15", "$24", "$31" ++#else ++#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$31" ++#endif /* CONFIG_CPU_MICROMIPS */ ++ + if (eva_kernel_access()) { + __asm__ __volatile__( + "move\t$4, %1\n\t" +@@ -1247,7 +1254,7 @@ __clear_user(void __user *addr, __kernel_size_t size) + "move\t%0, $6" + : "=r" (res) + : "r" (addr), "r" (size) +- : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"); ++ : bzero_clobbers); + } else { + might_fault(); + __asm__ __volatile__( +@@ -1258,7 +1265,7 @@ __clear_user(void __user *addr, __kernel_size_t size) + "move\t%0, $6" + : "=r" (res) + : "r" (addr), "r" (size) +- : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"); ++ : bzero_clobbers); + } + + return res; +diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S +index 8f0019a2e5c8..2d33cf2185d9 100644 +--- a/arch/mips/lib/memset.S ++++ b/arch/mips/lib/memset.S +@@ -218,7 +218,7 @@ + 1: PTR_ADDIU a0, 1 /* fill bytewise */ + R10KCBARRIER(0(ra)) + bne t1, a0, 1b +- sb a1, -1(a0) ++ EX(sb, a1, -1(a0), .Lsmall_fixup\@) + + 2: jr ra /* done */ + move a2, zero +@@ -249,13 +249,18 @@ + PTR_L t0, TI_TASK($28) + andi a2, STORMASK + LONG_L t0, THREAD_BUADDR(t0) +- LONG_ADDU a2, t1 ++ LONG_ADDU a2, a0 + jr ra + LONG_SUBU a2, t0 + + .Llast_fixup\@: + jr ra +- andi v1, a2, STORMASK ++ nop ++ ++.Lsmall_fixup\@: ++ PTR_SUBU a2, t1, a0 ++ jr ra ++ PTR_ADDIU a2, 1 + + .endm + +diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c +index dba508fe1683..4f7060ec6875 100644 +--- a/arch/parisc/kernel/drivers.c ++++ b/arch/parisc/kernel/drivers.c +@@ -648,6 +648,10 @@ static int match_pci_device(struct device *dev, int index, + (modpath->mod == PCI_FUNC(devfn))); + } + ++ /* index might be out of bounds for bc[] */ ++ if (index >= 6) ++ return 0; ++ + id = PCI_SLOT(pdev->devfn) | (PCI_FUNC(pdev->devfn) << 5); + return (modpath->bc[index] == id); + } +diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h +index 0eca6efc0631..b9e16855a037 100644 +--- a/arch/powerpc/include/asm/barrier.h ++++ b/arch/powerpc/include/asm/barrier.h +@@ -36,7 +36,8 @@ + + #define smp_store_mb(var, value) do { WRITE_ONCE(var, value); mb(); } while (0) + +-#ifdef __SUBARCH_HAS_LWSYNC ++/* The sub-arch has lwsync */ ++#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC) + # define SMPWMB LWSYNC + #else + # define SMPWMB eieio +diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h +index 07a99e638449..bab3461115bb 100644 +--- a/arch/powerpc/include/asm/opal.h ++++ b/arch/powerpc/include/asm/opal.h +@@ -21,6 +21,9 @@ + /* We calculate number of sg entries based on PAGE_SIZE */ + #define SG_ENTRIES_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct opal_sg_entry)) + ++/* Default time to sleep or delay between OPAL_BUSY/OPAL_BUSY_EVENT loops */ ++#define OPAL_BUSY_DELAY_MS 10 ++ + /* /sys/firmware/opal */ + extern struct kobject *opal_kobj; + +diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h +index c50868681f9e..e8d6a842f4bb 100644 +--- a/arch/powerpc/include/asm/synch.h ++++ b/arch/powerpc/include/asm/synch.h +@@ -5,10 +5,6 @@ + #include + #include + +-#if defined(__powerpc64__) || defined(CONFIG_PPC_E500MC) +-#define __SUBARCH_HAS_LWSYNC +-#endif +- + #ifndef __ASSEMBLY__ + extern unsigned int __start___lwsync_fixup, __stop___lwsync_fixup; + extern void do_lwsync_fixups(unsigned long value, void *fixup_start, +diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c +index 98f81800e00c..304f07cfa262 100644 +--- a/arch/powerpc/kernel/eeh_pe.c ++++ b/arch/powerpc/kernel/eeh_pe.c +@@ -788,7 +788,8 @@ static void eeh_restore_bridge_bars(struct eeh_dev *edev) + eeh_ops->write_config(pdn, 15*4, 4, edev->config_space[15]); + + /* PCI Command: 0x4 */ +- eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1]); ++ eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1] | ++ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + + /* Check the PCIe link is ready */ + eeh_bridge_check_link(edev); +diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c +index a18d648d31a6..3af014684872 100644 +--- a/arch/powerpc/lib/feature-fixups.c ++++ b/arch/powerpc/lib/feature-fixups.c +@@ -53,7 +53,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest, + unsigned int *target = (unsigned int *)branch_target(src); + + /* Branch within the section doesn't need translating */ +- if (target < alt_start || target >= alt_end) { ++ if (target < alt_start || target > alt_end) { + instr = translate_branch(dest, src); + if (!instr) + return 1; +diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c b/arch/powerpc/platforms/powernv/opal-nvram.c +index 9db4398ded5d..1bceb95f422d 100644 +--- a/arch/powerpc/platforms/powernv/opal-nvram.c ++++ b/arch/powerpc/platforms/powernv/opal-nvram.c +@@ -11,6 +11,7 @@ + + #define DEBUG + ++#include + #include + #include + #include +@@ -56,9 +57,17 @@ static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) + + while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { + rc = opal_write_nvram(__pa(buf), count, off); +- if (rc == OPAL_BUSY_EVENT) ++ if (rc == OPAL_BUSY_EVENT) { ++ msleep(OPAL_BUSY_DELAY_MS); + opal_poll_events(NULL); ++ } else if (rc == OPAL_BUSY) { ++ msleep(OPAL_BUSY_DELAY_MS); ++ } + } ++ ++ if (rc) ++ return -EIO; ++ + *index += count; + return count; + } +diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c +index b2e5902bd8f4..c670279b33f0 100644 +--- a/arch/s390/hypfs/inode.c ++++ b/arch/s390/hypfs/inode.c +@@ -318,7 +318,7 @@ static void hypfs_kill_super(struct super_block *sb) + + if (sb->s_root) + hypfs_delete_tree(sb->s_root); +- if (sb_info->update_file) ++ if (sb_info && sb_info->update_file) + hypfs_remove(sb_info->update_file); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; +diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c +index 42570d8fb265..e73979236659 100644 +--- a/arch/s390/kernel/ipl.c ++++ b/arch/s390/kernel/ipl.c +@@ -798,6 +798,7 @@ static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb, + /* copy and convert to ebcdic */ + memcpy(ipb->hdr.loadparm, buf, lp_len); + ASCEBC(ipb->hdr.loadparm, LOADPARM_LEN); ++ ipb->hdr.flags |= DIAG308_FLAGS_LP_VALID; + return len; + } + +diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c +index c211153ca69a..56648f4f8b41 100644 +--- a/arch/um/os-Linux/signal.c ++++ b/arch/um/os-Linux/signal.c +@@ -140,7 +140,7 @@ static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = { + + static void hard_handler(int sig, siginfo_t *si, void *p) + { +- struct ucontext *uc = p; ++ ucontext_t *uc = p; + mcontext_t *mc = &uc->uc_mcontext; + unsigned long pending = 1UL << sig; + +diff --git a/arch/x86/um/stub_segv.c b/arch/x86/um/stub_segv.c +index 1518d2805ae8..fd6825537b97 100644 +--- a/arch/x86/um/stub_segv.c ++++ b/arch/x86/um/stub_segv.c +@@ -10,7 +10,7 @@ + void __attribute__ ((__section__ (".__syscall_stub"))) + stub_segv_handler(int sig, siginfo_t *info, void *p) + { +- struct ucontext *uc = p; ++ ucontext_t *uc = p; + + GET_FAULTINFO_FROM_MC(*((struct faultinfo *) STUB_DATA), + &uc->uc_mcontext); +diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c +index b48ecbfc4498..8c5503c0bad7 100644 +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -205,6 +205,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = { + "3570R/370R/470R/450R/510R/4450RV"), + }, + }, ++ { ++ /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */ ++ .callback = video_detect_force_video, ++ .ident = "SAMSUNG 670Z5E", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"), ++ }, ++ }, + { + /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */ + .callback = video_detect_force_video, +diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c +index 4ac63c0e50c7..fd377b956199 100644 +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -1582,7 +1582,7 @@ int regmap_raw_write(struct regmap *map, unsigned int reg, + return -EINVAL; + if (val_len % map->format.val_bytes) + return -EINVAL; +- if (map->max_raw_write && map->max_raw_write > val_len) ++ if (map->max_raw_write && map->max_raw_write < val_len) + return -E2BIG; + + map->lock(map->lock_arg); +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 1dd16f26e77d..e8165ec55e6f 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -1121,11 +1121,15 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) + if (info->lo_encrypt_type) { + unsigned int type = info->lo_encrypt_type; + +- if (type >= MAX_LO_CRYPT) +- return -EINVAL; ++ if (type >= MAX_LO_CRYPT) { ++ err = -EINVAL; ++ goto exit; ++ } + xfer = xfer_funcs[type]; +- if (xfer == NULL) +- return -EINVAL; ++ if (xfer == NULL) { ++ err = -EINVAL; ++ goto exit; ++ } + } else + xfer = NULL; + +diff --git a/drivers/char/random.c b/drivers/char/random.c +index bd9fc2baa6aa..dffd06a3bb76 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -724,7 +724,7 @@ retry: + + static int credit_entropy_bits_safe(struct entropy_store *r, int nbits) + { +- const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1)); ++ const int nbits_max = r->poolinfo->poolwords * 32; + + if (nbits < 0) + return -EINVAL; +diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c +index 7c4b1ffe874f..d56ba46e6b78 100644 +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -891,9 +891,7 @@ static void bcm2835_pll_off(struct clk_hw *hw) + const struct bcm2835_pll_data *data = pll->data; + + spin_lock(&cprman->regs_lock); +- cprman_write(cprman, data->cm_ctrl_reg, +- cprman_read(cprman, data->cm_ctrl_reg) | +- CM_PLL_ANARST); ++ cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST); + cprman_write(cprman, data->a2w_ctrl_reg, + cprman_read(cprman, data->a2w_ctrl_reg) | + A2W_PLL_CTRL_PWRDN); +@@ -929,6 +927,10 @@ static int bcm2835_pll_on(struct clk_hw *hw) + cpu_relax(); + } + ++ cprman_write(cprman, data->a2w_ctrl_reg, ++ cprman_read(cprman, data->a2w_ctrl_reg) | ++ A2W_PLL_CTRL_PRST_DISABLE); ++ + return 0; + } + +diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c +index 8bccf4ecdab6..9ff4ea63932d 100644 +--- a/drivers/clk/mvebu/armada-38x.c ++++ b/drivers/clk/mvebu/armada-38x.c +@@ -46,10 +46,11 @@ static u32 __init armada_38x_get_tclk_freq(void __iomem *sar) + } + + static const u32 armada_38x_cpu_frequencies[] __initconst = { +- 0, 0, 0, 0, +- 1066 * 1000 * 1000, 0, 0, 0, ++ 666 * 1000 * 1000, 0, 800 * 1000 * 1000, 0, ++ 1066 * 1000 * 1000, 0, 1200 * 1000 * 1000, 0, + 1332 * 1000 * 1000, 0, 0, 0, +- 1600 * 1000 * 1000, ++ 1600 * 1000 * 1000, 0, 0, 0, ++ 1866 * 1000 * 1000, 0, 0, 2000 * 1000 * 1000, + }; + + static u32 __init armada_38x_get_cpu_freq(void __iomem *sar) +@@ -75,11 +76,11 @@ static const struct coreclk_ratio armada_38x_coreclk_ratios[] __initconst = { + }; + + static const int armada_38x_cpu_l2_ratios[32][2] __initconst = { +- {0, 1}, {0, 1}, {0, 1}, {0, 1}, +- {1, 2}, {0, 1}, {0, 1}, {0, 1}, ++ {1, 2}, {0, 1}, {1, 2}, {0, 1}, ++ {1, 2}, {0, 1}, {1, 2}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, +- {0, 1}, {0, 1}, {0, 1}, {0, 1}, ++ {1, 2}, {0, 1}, {0, 1}, {1, 2}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, +@@ -90,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst = { + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, +- {0, 1}, {0, 1}, {0, 1}, {0, 1}, ++ {1, 2}, {0, 1}, {0, 1}, {7, 15}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, +diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c +index 66c073fc8afc..82a7c89caae2 100644 +--- a/drivers/dma/at_xdmac.c ++++ b/drivers/dma/at_xdmac.c +@@ -1473,10 +1473,10 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + for (retry = 0; retry < AT_XDMAC_RESIDUE_MAX_RETRIES; retry++) { + check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; + rmb(); +- initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD); +- rmb(); + cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC); + rmb(); ++ initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD); ++ rmb(); + cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; + rmb(); + +diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c +index fb6ad143873f..83aee9e814ba 100644 +--- a/drivers/gpu/drm/radeon/radeon_object.c ++++ b/drivers/gpu/drm/radeon/radeon_object.c +@@ -238,9 +238,10 @@ int radeon_bo_create(struct radeon_device *rdev, + * may be slow + * See https://bugs.freedesktop.org/show_bug.cgi?id=88758 + */ +- ++#ifndef CONFIG_COMPILE_TEST + #warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \ + thanks to write-combining ++#endif + + if (bo->flags & RADEON_GEM_GTT_WC) + DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for " +diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c +index d9007cc37be1..892d0a71d766 100644 +--- a/drivers/gpu/drm/radeon/si_dpm.c ++++ b/drivers/gpu/drm/radeon/si_dpm.c +@@ -5964,9 +5964,9 @@ static void si_set_pcie_lane_width_in_smc(struct radeon_device *rdev, + { + u32 lane_width; + u32 new_lane_width = +- (radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT; ++ ((radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; + u32 current_lane_width = +- (radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT; ++ ((radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; + + if (new_lane_width != current_lane_width) { + radeon_set_pcie_lanes(rdev, new_lane_width); +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index d07fb967f92b..e4541c6bf3d3 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1331,7 +1331,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) + * of implement() working on 8 byte chunks + */ + +- int len = hid_report_len(report) + 7; ++ u32 len = hid_report_len(report) + 7; + + return kmalloc(len, flags); + } +@@ -1396,7 +1396,7 @@ void __hid_request(struct hid_device *hid, struct hid_report *report, + { + char *buf; + int ret; +- int len; ++ u32 len; + + buf = hid_alloc_report_buf(report, GFP_KERNEL); + if (!buf) +@@ -1422,14 +1422,14 @@ out: + } + EXPORT_SYMBOL_GPL(__hid_request); + +-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, ++int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, + int interrupt) + { + struct hid_report_enum *report_enum = hid->report_enum + type; + struct hid_report *report; + struct hid_driver *hdrv; + unsigned int a; +- int rsize, csize = size; ++ u32 rsize, csize = size; + u8 *cdata = data; + int ret = 0; + +@@ -1487,7 +1487,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event); + * + * This is data entry for lower layers. + */ +-int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) ++int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt) + { + struct hid_report_enum *report_enum; + struct hid_driver *hdrv; +diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c +index 53e54855c366..8d74e691ac90 100644 +--- a/drivers/hid/hid-input.c ++++ b/drivers/hid/hid-input.c +@@ -1258,7 +1258,8 @@ static void hidinput_led_worker(struct work_struct *work) + led_work); + struct hid_field *field; + struct hid_report *report; +- int len, ret; ++ int ret; ++ u32 len; + __u8 *buf; + + field = hidinput_get_led_field(hid); +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index f62a9d6601cc..9de379c1b3fd 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -314,7 +314,8 @@ static struct attribute_group mt_attribute_group = { + static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) + { + struct mt_device *td = hid_get_drvdata(hdev); +- int ret, size = hid_report_len(report); ++ int ret; ++ u32 size = hid_report_len(report); + u8 *buf; + + /* +@@ -919,7 +920,7 @@ static void mt_set_input_mode(struct hid_device *hdev) + struct hid_report_enum *re; + struct mt_class *cls = &td->mtclass; + char *buf; +- int report_len; ++ u32 report_len; + + if (td->inputmode < 0) + return; +diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c +index 67cd059a8f46..41a4a2af9db1 100644 +--- a/drivers/hid/hid-rmi.c ++++ b/drivers/hid/hid-rmi.c +@@ -110,8 +110,8 @@ struct rmi_data { + u8 *writeReport; + u8 *readReport; + +- int input_report_size; +- int output_report_size; ++ u32 input_report_size; ++ u32 output_report_size; + + unsigned long flags; + +diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c +index 9c2d7c23f296..c0c4df198725 100644 +--- a/drivers/hid/hidraw.c ++++ b/drivers/hid/hidraw.c +@@ -197,6 +197,11 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t + int ret = 0, len; + unsigned char report_number; + ++ if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { ++ ret = -ENODEV; ++ goto out; ++ } ++ + dev = hidraw_table[minor]->hid; + + if (!dev->ll_driver->raw_request) { +diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c +index 312aa1e33fb2..4c3ed078c6b9 100644 +--- a/drivers/hid/i2c-hid/i2c-hid.c ++++ b/drivers/hid/i2c-hid/i2c-hid.c +@@ -137,10 +137,10 @@ struct i2c_hid { + * register of the HID + * descriptor. */ + unsigned int bufsize; /* i2c buffer size */ +- char *inbuf; /* Input buffer */ +- char *rawbuf; /* Raw Input buffer */ +- char *cmdbuf; /* Command buffer */ +- char *argsbuf; /* Command arguments buffer */ ++ u8 *inbuf; /* Input buffer */ ++ u8 *rawbuf; /* Raw Input buffer */ ++ u8 *cmdbuf; /* Command buffer */ ++ u8 *argsbuf; /* Command arguments buffer */ + + unsigned long flags; /* device flags */ + +@@ -387,7 +387,8 @@ static int i2c_hid_hwreset(struct i2c_client *client) + + static void i2c_hid_get_input(struct i2c_hid *ihid) + { +- int ret, ret_size; ++ int ret; ++ u32 ret_size; + int size = le16_to_cpu(ihid->hdesc.wMaxInputLength); + + if (size > ihid->bufsize) +@@ -412,7 +413,7 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) + return; + } + +- if (ret_size > size) { ++ if ((ret_size > size) || (ret_size <= 2)) { + dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", + __func__, size, ret_size); + return; +diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c +index a629f7c130f0..ac63e562071f 100644 +--- a/drivers/hwmon/ina2xx.c ++++ b/drivers/hwmon/ina2xx.c +@@ -447,6 +447,7 @@ static int ina2xx_probe(struct i2c_client *client, + + /* set the device type */ + data->config = &ina2xx_config[id->driver_data]; ++ mutex_init(&data->config_lock); + + if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) { + struct ina2xx_platform_data *pdata = dev_get_platdata(dev); +@@ -473,8 +474,6 @@ static int ina2xx_probe(struct i2c_client *client, + return -ENODEV; + } + +- mutex_init(&data->config_lock); +- + data->groups[group++] = &ina2xx_group; + if (id->driver_data == ina226) + data->groups[group++] = &ina226_group; +diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c +index 960fcb613198..ea3bc9bb1b7a 100644 +--- a/drivers/infiniband/core/ucma.c ++++ b/drivers/infiniband/core/ucma.c +@@ -1230,6 +1230,9 @@ static int ucma_set_ib_path(struct ucma_context *ctx, + if (!optlen) + return -EINVAL; + ++ if (!ctx->cm_id->device) ++ return -EINVAL; ++ + memset(&sa_path, 0, sizeof(sa_path)); + + ib_sa_unpack_path(path_data->path_rec, &sa_path); +diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c +index 9a99cee2665a..4fd2892613dd 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.c ++++ b/drivers/infiniband/ulp/srp/ib_srp.c +@@ -2581,9 +2581,11 @@ static int srp_abort(struct scsi_cmnd *scmnd) + ret = FAST_IO_FAIL; + else + ret = FAILED; +- srp_free_req(ch, req, scmnd, 0); +- scmnd->result = DID_ABORT << 16; +- scmnd->scsi_done(scmnd); ++ if (ret == SUCCESS) { ++ srp_free_req(ch, req, scmnd, 0); ++ scmnd->result = DID_ABORT << 16; ++ scmnd->scsi_done(scmnd); ++ } + + return ret; + } +@@ -3309,12 +3311,10 @@ static ssize_t srp_create_target(struct device *dev, + num_online_nodes()); + const int ch_end = ((node_idx + 1) * target->ch_count / + num_online_nodes()); +- const int cv_start = (node_idx * ibdev->num_comp_vectors / +- num_online_nodes() + target->comp_vector) +- % ibdev->num_comp_vectors; +- const int cv_end = ((node_idx + 1) * ibdev->num_comp_vectors / +- num_online_nodes() + target->comp_vector) +- % ibdev->num_comp_vectors; ++ const int cv_start = node_idx * ibdev->num_comp_vectors / ++ num_online_nodes(); ++ const int cv_end = (node_idx + 1) * ibdev->num_comp_vectors / ++ num_online_nodes(); + int cpu_idx = 0; + + for_each_online_cpu(cpu) { +diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c +index a7d516f973dd..10068a481e22 100644 +--- a/drivers/iommu/intel-svm.c ++++ b/drivers/iommu/intel-svm.c +@@ -389,6 +389,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ + pasid_max - 1, GFP_KERNEL); + if (ret < 0) { + kfree(svm); ++ kfree(sdev); + goto out; + } + svm->pasid = ret; +diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +index 943f90e392a7..e0ae2f34623a 100644 +--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c ++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +@@ -101,7 +101,7 @@ static int get_v4l2_window32(struct v4l2_window __user *kp, + static int put_v4l2_window32(struct v4l2_window __user *kp, + struct v4l2_window32 __user *up) + { +- struct v4l2_clip __user *kclips = kp->clips; ++ struct v4l2_clip __user *kclips; + struct v4l2_clip32 __user *uclips; + compat_caddr_t p; + u32 clipcount; +@@ -116,6 +116,8 @@ static int put_v4l2_window32(struct v4l2_window __user *kp, + if (!clipcount) + return 0; + ++ if (get_user(kclips, &kp->clips)) ++ return -EFAULT; + if (get_user(p, &up->clips)) + return -EFAULT; + uclips = compat_ptr(p); +diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c +index 76e8bce6f46e..ad572a0f2124 100644 +--- a/drivers/mmc/host/jz4740_mmc.c ++++ b/drivers/mmc/host/jz4740_mmc.c +@@ -368,9 +368,9 @@ static void jz4740_mmc_set_irq_enabled(struct jz4740_mmc_host *host, + host->irq_mask &= ~irq; + else + host->irq_mask |= irq; +- spin_unlock_irqrestore(&host->lock, flags); + + writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK); ++ spin_unlock_irqrestore(&host->lock, flags); + } + + static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host, +diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c +index b2fb0528c092..07ad86759d92 100644 +--- a/drivers/mtd/ubi/block.c ++++ b/drivers/mtd/ubi/block.c +@@ -244,7 +244,7 @@ static int ubiblock_open(struct block_device *bdev, fmode_t mode) + * in any case. + */ + if (mode & FMODE_WRITE) { +- ret = -EPERM; ++ ret = -EROFS; + goto out_unlock; + } + +diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c +index 27de0463226e..a2e6c7848b0a 100644 +--- a/drivers/mtd/ubi/build.c ++++ b/drivers/mtd/ubi/build.c +@@ -889,6 +889,17 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, + return -EINVAL; + } + ++ /* ++ * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes. ++ * MLC NAND is different and needs special care, otherwise UBI or UBIFS ++ * will die soon and you will lose all your data. ++ */ ++ if (mtd->type == MTD_MLCNANDFLASH) { ++ pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n", ++ mtd->index); ++ return -EINVAL; ++ } ++ + if (ubi_num == UBI_DEV_NUM_AUTO) { + /* Search for an empty slot in the @ubi_devices array */ + for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) +diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c +index 30d3999dddba..ed62f1efe6eb 100644 +--- a/drivers/mtd/ubi/fastmap-wl.c ++++ b/drivers/mtd/ubi/fastmap-wl.c +@@ -360,7 +360,6 @@ static void ubi_fastmap_close(struct ubi_device *ubi) + { + int i; + +- flush_work(&ubi->fm_work); + return_unused_pool_pebs(ubi, &ubi->fm_pool); + return_unused_pool_pebs(ubi, &ubi->fm_wl_pool); + +diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c +index 27ed25252aac..cfd81eb1b532 100644 +--- a/drivers/net/slip/slhc.c ++++ b/drivers/net/slip/slhc.c +@@ -509,6 +509,10 @@ slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize) + if(x < 0 || x > comp->rslot_limit) + goto bad; + ++ /* Check if the cstate is initialized */ ++ if (!comp->rstate[x].initialized) ++ goto bad; ++ + comp->flags &=~ SLF_TOSS; + comp->recv_current = x; + } else { +@@ -673,6 +677,7 @@ slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) + if (cs->cs_tcp.doff > 5) + memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); + cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; ++ cs->initialized = true; + /* Put headers back on packet + * Neither header checksum is recalculated + */ +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index f9343bee1de3..6578127db847 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -704,6 +704,12 @@ static const struct usb_device_id products[] = { + USB_CDC_SUBCLASS_ETHERNET, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&wwan_info, ++}, { ++ /* Cinterion AHS3 modem by GEMALTO */ ++ USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0055, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, ++ USB_CDC_PROTO_NONE), ++ .driver_info = (unsigned long)&wwan_info, + }, { + /* Telit modules */ + USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM, +diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c +index ebdee8f01f65..a6d429950cb0 100644 +--- a/drivers/net/usb/lan78xx.c ++++ b/drivers/net/usb/lan78xx.c +@@ -618,7 +618,8 @@ static int lan78xx_read_otp(struct lan78xx_net *dev, u32 offset, + offset += 0x100; + else + ret = -EINVAL; +- ret = lan78xx_read_raw_otp(dev, offset, length, data); ++ if (!ret) ++ ret = lan78xx_read_raw_otp(dev, offset, length, data); + } + + return ret; +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +index b7f72f9c7988..b3691712df61 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +@@ -1454,6 +1454,7 @@ static int rtl8187_probe(struct usb_interface *intf, + goto err_free_dev; + } + mutex_init(&priv->io_mutex); ++ mutex_init(&priv->conf_mutex); + + SET_IEEE80211_DEV(dev, &intf->dev); + usb_set_intfdata(intf, dev); +@@ -1627,7 +1628,6 @@ static int rtl8187_probe(struct usb_interface *intf, + printk(KERN_ERR "rtl8187: Cannot register device\n"); + goto err_free_dmabuf; + } +- mutex_init(&priv->conf_mutex); + skb_queue_head_init(&priv->b_tx_status.queue); + + wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n", +diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c +index 0b8d2655985f..fee4c01fbdfd 100644 +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -2024,7 +2024,10 @@ static void netback_changed(struct xenbus_device *dev, + case XenbusStateInitialised: + case XenbusStateReconfiguring: + case XenbusStateReconfigured: ++ break; ++ + case XenbusStateUnknown: ++ wake_up_all(&module_unload_q); + break; + + case XenbusStateInitWait: +@@ -2155,7 +2158,9 @@ static int xennet_remove(struct xenbus_device *dev) + xenbus_switch_state(dev, XenbusStateClosing); + wait_event(module_unload_q, + xenbus_read_driver_state(dev->otherend) == +- XenbusStateClosing); ++ XenbusStateClosing || ++ xenbus_read_driver_state(dev->otherend) == ++ XenbusStateUnknown); + + xenbus_switch_state(dev, XenbusStateClosed); + wait_event(module_unload_q, +diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c +index 0b3e0bfa7be5..572ca192cb1f 100644 +--- a/drivers/pci/hotplug/acpiphp_glue.c ++++ b/drivers/pci/hotplug/acpiphp_glue.c +@@ -587,6 +587,7 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) + { + unsigned long long sta = 0; + struct acpiphp_func *func; ++ u32 dvid; + + list_for_each_entry(func, &slot->funcs, sibling) { + if (func->flags & FUNC_HAS_STA) { +@@ -597,19 +598,27 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) + if (ACPI_SUCCESS(status) && sta) + break; + } else { +- u32 dvid; +- +- pci_bus_read_config_dword(slot->bus, +- PCI_DEVFN(slot->device, +- func->function), +- PCI_VENDOR_ID, &dvid); +- if (dvid != 0xffffffff) { ++ if (pci_bus_read_dev_vendor_id(slot->bus, ++ PCI_DEVFN(slot->device, func->function), ++ &dvid, 0)) { + sta = ACPI_STA_ALL; + break; + } + } + } + ++ if (!sta) { ++ /* ++ * Check for the slot itself since it may be that the ++ * ACPI slot is a device below PCIe upstream port so in ++ * that case it may not even be reachable yet. ++ */ ++ if (pci_bus_read_dev_vendor_id(slot->bus, ++ PCI_DEVFN(slot->device, 0), &dvid, 0)) { ++ sta = ACPI_STA_ALL; ++ } ++ } ++ + return (unsigned int)sta; + } + +diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c +index 4bb5262f7aee..742ca57ece8c 100644 +--- a/drivers/s390/cio/qdio_main.c ++++ b/drivers/s390/cio/qdio_main.c +@@ -126,7 +126,7 @@ static inline int qdio_check_ccq(struct qdio_q *q, unsigned int ccq) + static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state, + int start, int count, int auto_ack) + { +- int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0; ++ int rc, tmp_count = count, tmp_start = start, nr = q->nr; + unsigned int ccq = 0; + + qperf_inc(q, eqbs); +@@ -149,14 +149,7 @@ again: + qperf_inc(q, eqbs_partial); + DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x", + tmp_count); +- /* +- * Retry once, if that fails bail out and process the +- * extracted buffers before trying again. +- */ +- if (!retried++) +- goto again; +- else +- return count - tmp_count; ++ return count - tmp_count; + } + + DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); +@@ -212,7 +205,10 @@ again: + return 0; + } + +-/* returns number of examined buffers and their common state in *state */ ++/* ++ * Returns number of examined buffers and their common state in *state. ++ * Requested number of buffers-to-examine must be > 0. ++ */ + static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr, + unsigned char *state, unsigned int count, + int auto_ack, int merge_pending) +@@ -223,17 +219,23 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr, + if (is_qebsm(q)) + return qdio_do_eqbs(q, state, bufnr, count, auto_ack); + +- for (i = 0; i < count; i++) { +- if (!__state) { +- __state = q->slsb.val[bufnr]; +- if (merge_pending && __state == SLSB_P_OUTPUT_PENDING) +- __state = SLSB_P_OUTPUT_EMPTY; +- } else if (merge_pending) { +- if ((q->slsb.val[bufnr] & __state) != __state) +- break; +- } else if (q->slsb.val[bufnr] != __state) +- break; ++ /* get initial state: */ ++ __state = q->slsb.val[bufnr]; ++ if (merge_pending && __state == SLSB_P_OUTPUT_PENDING) ++ __state = SLSB_P_OUTPUT_EMPTY; ++ ++ for (i = 1; i < count; i++) { + bufnr = next_buf(bufnr); ++ ++ /* merge PENDING into EMPTY: */ ++ if (merge_pending && ++ q->slsb.val[bufnr] == SLSB_P_OUTPUT_PENDING && ++ __state == SLSB_P_OUTPUT_EMPTY) ++ continue; ++ ++ /* stop if next state differs from initial state: */ ++ if (q->slsb.val[bufnr] != __state) ++ break; + } + *state = __state; + return i; +diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c +index c5547bd711db..6a8300108148 100644 +--- a/drivers/thermal/imx_thermal.c ++++ b/drivers/thermal/imx_thermal.c +@@ -589,6 +589,9 @@ static int imx_thermal_probe(struct platform_device *pdev) + regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); + regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); + ++ data->irq_enabled = true; ++ data->mode = THERMAL_DEVICE_ENABLED; ++ + ret = devm_request_threaded_irq(&pdev->dev, data->irq, + imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread, + 0, "imx_thermal", data); +@@ -600,9 +603,6 @@ static int imx_thermal_probe(struct platform_device *pdev) + return ret; + } + +- data->irq_enabled = true; +- data->mode = THERMAL_DEVICE_ENABLED; +- + return 0; + } + +diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c +index 20a41f7de76f..6713fd1958e7 100644 +--- a/drivers/thunderbolt/nhi.c ++++ b/drivers/thunderbolt/nhi.c +@@ -627,6 +627,7 @@ static const struct dev_pm_ops nhi_pm_ops = { + * we just disable hotplug, the + * pci-tunnels stay alive. + */ ++ .thaw_noirq = nhi_resume_noirq, + .restore_noirq = nhi_resume_noirq, + }; + +diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c +index 41dda25da049..190e5dc15738 100644 +--- a/drivers/tty/n_tty.c ++++ b/drivers/tty/n_tty.c +@@ -2238,6 +2238,12 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, + } + if (tty_hung_up_p(file)) + break; ++ /* ++ * Abort readers for ttys which never actually ++ * get hung up. See __tty_hangup(). ++ */ ++ if (test_bit(TTY_HUPPING, &tty->flags)) ++ break; + if (!timeout) + break; + if (file->f_flags & O_NONBLOCK) { +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index a638c1738547..89fd20382ce4 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -702,6 +702,14 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) + return; + } + ++ /* ++ * Some console devices aren't actually hung up for technical and ++ * historical reasons, which can lead to indefinite interruptible ++ * sleep in n_tty_read(). The following explicitly tells ++ * n_tty_read() to abort readers. ++ */ ++ set_bit(TTY_HUPPING, &tty->flags); ++ + /* inuse_filps is protected by the single tty lock, + this really needs to change if we want to flush the + workqueue with the lock held */ +@@ -757,6 +765,7 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) + * can't yet guarantee all that. + */ + set_bit(TTY_HUPPED, &tty->flags); ++ clear_bit(TTY_HUPPING, &tty->flags); + tty_unlock(tty); + + if (f) +diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c +index 358ca8dd784f..a5240b4d7ab9 100644 +--- a/drivers/usb/core/generic.c ++++ b/drivers/usb/core/generic.c +@@ -208,8 +208,13 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) + if (!udev->parent) + rc = hcd_bus_suspend(udev, msg); + +- /* Non-root devices don't need to do anything for FREEZE or PRETHAW */ +- else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) ++ /* ++ * Non-root USB2 devices don't need to do anything for FREEZE ++ * or PRETHAW. USB3 devices don't support global suspend and ++ * needs to be selectively suspended. ++ */ ++ else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) ++ && (udev->speed < USB_SPEED_SUPER)) + rc = 0; + else + rc = usb_port_suspend(udev, msg); +diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c +index d2c0c1a8d979..68230adf2449 100644 +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -167,7 +167,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, + ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); + if (ret) { + dev_err(dev, "couldn't add resources to dwc3 device\n"); +- return ret; ++ goto err; + } + + pci_set_drvdata(pci, dwc3); +diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c +index 10d30afe4a3c..a0d1417362cd 100644 +--- a/drivers/usb/musb/musb_gadget_ep0.c ++++ b/drivers/usb/musb/musb_gadget_ep0.c +@@ -114,15 +114,19 @@ static int service_tx_status_request( + } + + is_in = epnum & USB_DIR_IN; +- if (is_in) { +- epnum &= 0x0f; ++ epnum &= 0x0f; ++ if (epnum >= MUSB_C_NUM_EPS) { ++ handled = -EINVAL; ++ break; ++ } ++ ++ if (is_in) + ep = &musb->endpoints[epnum].ep_in; +- } else { ++ else + ep = &musb->endpoints[epnum].ep_out; +- } + regs = musb->endpoints[epnum].regs; + +- if (epnum >= MUSB_C_NUM_EPS || !ep->desc) { ++ if (!ep->desc) { + handled = -EINVAL; + break; + } +diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c +index fe2b470d7ec6..c55c632a3b24 100644 +--- a/drivers/vfio/pci/vfio_pci_config.c ++++ b/drivers/vfio/pci/vfio_pci_config.c +@@ -752,6 +752,62 @@ static int __init init_pci_cap_pcix_perm(struct perm_bits *perm) + return 0; + } + ++static int vfio_exp_config_write(struct vfio_pci_device *vdev, int pos, ++ int count, struct perm_bits *perm, ++ int offset, __le32 val) ++{ ++ __le16 *ctrl = (__le16 *)(vdev->vconfig + pos - ++ offset + PCI_EXP_DEVCTL); ++ int readrq = le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ; ++ ++ count = vfio_default_config_write(vdev, pos, count, perm, offset, val); ++ if (count < 0) ++ return count; ++ ++ /* ++ * The FLR bit is virtualized, if set and the device supports PCIe ++ * FLR, issue a reset_function. Regardless, clear the bit, the spec ++ * requires it to be always read as zero. NB, reset_function might ++ * not use a PCIe FLR, we don't have that level of granularity. ++ */ ++ if (*ctrl & cpu_to_le16(PCI_EXP_DEVCTL_BCR_FLR)) { ++ u32 cap; ++ int ret; ++ ++ *ctrl &= ~cpu_to_le16(PCI_EXP_DEVCTL_BCR_FLR); ++ ++ ret = pci_user_read_config_dword(vdev->pdev, ++ pos - offset + PCI_EXP_DEVCAP, ++ &cap); ++ ++ if (!ret && (cap & PCI_EXP_DEVCAP_FLR)) ++ pci_try_reset_function(vdev->pdev); ++ } ++ ++ /* ++ * MPS is virtualized to the user, writes do not change the physical ++ * register since determining a proper MPS value requires a system wide ++ * device view. The MRRS is largely independent of MPS, but since the ++ * user does not have that system-wide view, they might set a safe, but ++ * inefficiently low value. Here we allow writes through to hardware, ++ * but we set the floor to the physical device MPS setting, so that ++ * we can at least use full TLPs, as defined by the MPS value. ++ * ++ * NB, if any devices actually depend on an artificially low MRRS ++ * setting, this will need to be revisited, perhaps with a quirk ++ * though pcie_set_readrq(). ++ */ ++ if (readrq != (le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ)) { ++ readrq = 128 << ++ ((le16_to_cpu(*ctrl) & PCI_EXP_DEVCTL_READRQ) >> 12); ++ readrq = max(readrq, pcie_get_mps(vdev->pdev)); ++ ++ pcie_set_readrq(vdev->pdev, readrq); ++ } ++ ++ return count; ++} ++ + /* Permissions for PCI Express capability */ + static int __init init_pci_cap_exp_perm(struct perm_bits *perm) + { +@@ -759,26 +815,67 @@ static int __init init_pci_cap_exp_perm(struct perm_bits *perm) + if (alloc_perm_bits(perm, PCI_CAP_EXP_ENDPOINT_SIZEOF_V2)) + return -ENOMEM; + ++ perm->writefn = vfio_exp_config_write; ++ + p_setb(perm, PCI_CAP_LIST_NEXT, (u8)ALL_VIRT, NO_WRITE); + + /* +- * Allow writes to device control fields (includes FLR!) +- * but not to devctl_phantom which could confuse IOMMU +- * or to the ARI bit in devctl2 which is set at probe time ++ * Allow writes to device control fields, except devctl_phantom, ++ * which could confuse IOMMU, MPS, which can break communication ++ * with other physical devices, and the ARI bit in devctl2, which ++ * is set at probe time. FLR and MRRS get virtualized via our ++ * writefn. + */ +- p_setw(perm, PCI_EXP_DEVCTL, NO_VIRT, ~PCI_EXP_DEVCTL_PHANTOM); ++ p_setw(perm, PCI_EXP_DEVCTL, ++ PCI_EXP_DEVCTL_BCR_FLR | PCI_EXP_DEVCTL_PAYLOAD | ++ PCI_EXP_DEVCTL_READRQ, ~PCI_EXP_DEVCTL_PHANTOM); + p_setw(perm, PCI_EXP_DEVCTL2, NO_VIRT, ~PCI_EXP_DEVCTL2_ARI); + return 0; + } + ++static int vfio_af_config_write(struct vfio_pci_device *vdev, int pos, ++ int count, struct perm_bits *perm, ++ int offset, __le32 val) ++{ ++ u8 *ctrl = vdev->vconfig + pos - offset + PCI_AF_CTRL; ++ ++ count = vfio_default_config_write(vdev, pos, count, perm, offset, val); ++ if (count < 0) ++ return count; ++ ++ /* ++ * The FLR bit is virtualized, if set and the device supports AF ++ * FLR, issue a reset_function. Regardless, clear the bit, the spec ++ * requires it to be always read as zero. NB, reset_function might ++ * not use an AF FLR, we don't have that level of granularity. ++ */ ++ if (*ctrl & PCI_AF_CTRL_FLR) { ++ u8 cap; ++ int ret; ++ ++ *ctrl &= ~PCI_AF_CTRL_FLR; ++ ++ ret = pci_user_read_config_byte(vdev->pdev, ++ pos - offset + PCI_AF_CAP, ++ &cap); ++ ++ if (!ret && (cap & PCI_AF_CAP_FLR) && (cap & PCI_AF_CAP_TP)) ++ pci_try_reset_function(vdev->pdev); ++ } ++ ++ return count; ++} ++ + /* Permissions for Advanced Function capability */ + static int __init init_pci_cap_af_perm(struct perm_bits *perm) + { + if (alloc_perm_bits(perm, pci_cap_length[PCI_CAP_ID_AF])) + return -ENOMEM; + ++ perm->writefn = vfio_af_config_write; ++ + p_setb(perm, PCI_CAP_LIST_NEXT, (u8)ALL_VIRT, NO_WRITE); +- p_setb(perm, PCI_AF_CTRL, NO_VIRT, PCI_AF_CTRL_FLR); ++ p_setb(perm, PCI_AF_CTRL, PCI_AF_CTRL_FLR, PCI_AF_CTRL_FLR); + return 0; + } + +diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c +index 016bd9355190..aa93df5833dc 100644 +--- a/drivers/watchdog/f71808e_wdt.c ++++ b/drivers/watchdog/f71808e_wdt.c +@@ -450,7 +450,7 @@ static bool watchdog_is_running(void) + + is_running = (superio_inb(watchdog.sioaddr, SIO_REG_ENABLE) & BIT(0)) + && (superio_inb(watchdog.sioaddr, F71808FG_REG_WDT_CONF) +- & F71808FG_FLAG_WD_EN); ++ & BIT(F71808FG_FLAG_WD_EN)); + + superio_exit(watchdog.sioaddr); + +diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c +index 7a54c6a867c8..500098cdb960 100644 +--- a/fs/autofs4/root.c ++++ b/fs/autofs4/root.c +@@ -746,7 +746,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, umode_t m + + autofs4_del_active(dentry); + +- inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555); ++ inode = autofs4_get_inode(dir->i_sb, S_IFDIR | mode); + if (!inode) + return -ENOMEM; + d_add(dentry, inode); +diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c +index f97110461c19..78c51ce913db 100644 +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -242,8 +242,6 @@ static int ext4_init_block_bitmap(struct super_block *sb, + */ + ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group), + sb->s_blocksize * 8, bh->b_data); +- ext4_block_bitmap_csum_set(sb, block_group, gdp, bh); +- ext4_group_desc_csum_set(sb, block_group, gdp); + return 0; + } + +@@ -447,6 +445,7 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) + err = ext4_init_block_bitmap(sb, bh, block_group, desc); + set_bitmap_uptodate(bh); + set_buffer_uptodate(bh); ++ set_buffer_verified(bh); + ext4_unlock_group(sb, block_group); + unlock_buffer(bh); + if (err) { +diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c +index 5388207d2832..e10c12f59c58 100644 +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -63,44 +63,6 @@ void ext4_mark_bitmap_end(int start_bit, int end_bit, char *bitmap) + memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); + } + +-/* Initializes an uninitialized inode bitmap */ +-static int ext4_init_inode_bitmap(struct super_block *sb, +- struct buffer_head *bh, +- ext4_group_t block_group, +- struct ext4_group_desc *gdp) +-{ +- struct ext4_group_info *grp; +- struct ext4_sb_info *sbi = EXT4_SB(sb); +- J_ASSERT_BH(bh, buffer_locked(bh)); +- +- /* If checksum is bad mark all blocks and inodes use to prevent +- * allocation, essentially implementing a per-group read-only flag. */ +- if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { +- grp = ext4_get_group_info(sb, block_group); +- if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) +- percpu_counter_sub(&sbi->s_freeclusters_counter, +- grp->bb_free); +- set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); +- if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { +- int count; +- count = ext4_free_inodes_count(sb, gdp); +- percpu_counter_sub(&sbi->s_freeinodes_counter, +- count); +- } +- set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); +- return -EFSBADCRC; +- } +- +- memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); +- ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8, +- bh->b_data); +- ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh, +- EXT4_INODES_PER_GROUP(sb) / 8); +- ext4_group_desc_csum_set(sb, block_group, gdp); +- +- return 0; +-} +- + void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate) + { + if (uptodate) { +@@ -184,17 +146,14 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) + + ext4_lock_group(sb, block_group); + if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { +- err = ext4_init_inode_bitmap(sb, bh, block_group, desc); ++ memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); ++ ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), ++ sb->s_blocksize * 8, bh->b_data); + set_bitmap_uptodate(bh); + set_buffer_uptodate(bh); + set_buffer_verified(bh); + ext4_unlock_group(sb, block_group); + unlock_buffer(bh); +- if (err) { +- ext4_error(sb, "Failed to init inode bitmap for group " +- "%u: %d", block_group, err); +- goto out; +- } + return bh; + } + ext4_unlock_group(sb, block_group); +diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c +index dad8e7bdf0a6..3006b81c107f 100644 +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -376,7 +376,7 @@ out: + static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode, + unsigned int len) + { +- int ret, size; ++ int ret, size, no_expand; + struct ext4_inode_info *ei = EXT4_I(inode); + + if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) +@@ -386,15 +386,14 @@ static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode, + if (size < len) + return -ENOSPC; + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + + if (ei->i_inline_off) + ret = ext4_update_inline_data(handle, inode, len); + else + ret = ext4_create_inline_data(handle, inode, len); + +- up_write(&EXT4_I(inode)->xattr_sem); +- ++ ext4_write_unlock_xattr(inode, &no_expand); + return ret; + } + +@@ -523,7 +522,7 @@ static int ext4_convert_inline_data_to_extent(struct address_space *mapping, + struct inode *inode, + unsigned flags) + { +- int ret, needed_blocks; ++ int ret, needed_blocks, no_expand; + handle_t *handle = NULL; + int retries = 0, sem_held = 0; + struct page *page = NULL; +@@ -563,7 +562,7 @@ retry: + goto out; + } + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + sem_held = 1; + /* If some one has already done this for us, just exit. */ + if (!ext4_has_inline_data(inode)) { +@@ -599,7 +598,7 @@ retry: + page_cache_release(page); + page = NULL; + ext4_orphan_add(handle, inode); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + sem_held = 0; + ext4_journal_stop(handle); + handle = NULL; +@@ -625,7 +624,7 @@ out: + page_cache_release(page); + } + if (sem_held) +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + if (handle) + ext4_journal_stop(handle); + brelse(iloc.bh); +@@ -718,7 +717,7 @@ convert: + int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, + unsigned copied, struct page *page) + { +- int ret; ++ int ret, no_expand; + void *kaddr; + struct ext4_iloc iloc; + +@@ -736,7 +735,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, + goto out; + } + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + BUG_ON(!ext4_has_inline_data(inode)); + + kaddr = kmap_atomic(page); +@@ -746,7 +745,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len, + /* clear page dirty so that writepages wouldn't work for us. */ + ClearPageDirty(page); + +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + brelse(iloc.bh); + out: + return copied; +@@ -757,7 +756,7 @@ ext4_journalled_write_inline_data(struct inode *inode, + unsigned len, + struct page *page) + { +- int ret; ++ int ret, no_expand; + void *kaddr; + struct ext4_iloc iloc; + +@@ -767,11 +766,11 @@ ext4_journalled_write_inline_data(struct inode *inode, + return NULL; + } + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + kaddr = kmap_atomic(page); + ext4_write_inline_data(inode, &iloc, kaddr, 0, len); + kunmap_atomic(kaddr); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + + return iloc.bh; + } +@@ -1255,7 +1254,7 @@ out: + int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname, + struct dentry *dentry, struct inode *inode) + { +- int ret, inline_size; ++ int ret, inline_size, no_expand; + void *inline_start; + struct ext4_iloc iloc; + struct inode *dir = d_inode(dentry->d_parent); +@@ -1264,7 +1263,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname, + if (ret) + return ret; + +- down_write(&EXT4_I(dir)->xattr_sem); ++ ext4_write_lock_xattr(dir, &no_expand); + if (!ext4_has_inline_data(dir)) + goto out; + +@@ -1310,7 +1309,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname, + + out: + ext4_mark_inode_dirty(handle, dir); +- up_write(&EXT4_I(dir)->xattr_sem); ++ ext4_write_unlock_xattr(dir, &no_expand); + brelse(iloc.bh); + return ret; + } +@@ -1670,7 +1669,7 @@ int ext4_delete_inline_entry(handle_t *handle, + struct buffer_head *bh, + int *has_inline_data) + { +- int err, inline_size; ++ int err, inline_size, no_expand; + struct ext4_iloc iloc; + void *inline_start; + +@@ -1678,7 +1677,7 @@ int ext4_delete_inline_entry(handle_t *handle, + if (err) + return err; + +- down_write(&EXT4_I(dir)->xattr_sem); ++ ext4_write_lock_xattr(dir, &no_expand); + if (!ext4_has_inline_data(dir)) { + *has_inline_data = 0; + goto out; +@@ -1713,7 +1712,7 @@ int ext4_delete_inline_entry(handle_t *handle, + + ext4_show_inline_dir(dir, iloc.bh, inline_start, inline_size); + out: +- up_write(&EXT4_I(dir)->xattr_sem); ++ ext4_write_unlock_xattr(dir, &no_expand); + brelse(iloc.bh); + if (err != -ENOENT) + ext4_std_error(dir->i_sb, err); +@@ -1812,11 +1811,11 @@ out: + + int ext4_destroy_inline_data(handle_t *handle, struct inode *inode) + { +- int ret; ++ int ret, no_expand; + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + ret = ext4_destroy_inline_data_nolock(handle, inode); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + + return ret; + } +@@ -1901,7 +1900,7 @@ out: + void ext4_inline_data_truncate(struct inode *inode, int *has_inline) + { + handle_t *handle; +- int inline_size, value_len, needed_blocks; ++ int inline_size, value_len, needed_blocks, no_expand; + size_t i_size; + void *value = NULL; + struct ext4_xattr_ibody_find is = { +@@ -1918,7 +1917,7 @@ void ext4_inline_data_truncate(struct inode *inode, int *has_inline) + if (IS_ERR(handle)) + return; + +- down_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_lock_xattr(inode, &no_expand); + if (!ext4_has_inline_data(inode)) { + *has_inline = 0; + ext4_journal_stop(handle); +@@ -1976,7 +1975,7 @@ out_error: + up_write(&EXT4_I(inode)->i_data_sem); + out: + brelse(is.iloc.bh); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + kfree(value); + if (inode->i_nlink) + ext4_orphan_del(handle, inode); +@@ -1992,7 +1991,7 @@ out: + + int ext4_convert_inline_data(struct inode *inode) + { +- int error, needed_blocks; ++ int error, needed_blocks, no_expand; + handle_t *handle; + struct ext4_iloc iloc; + +@@ -2014,15 +2013,10 @@ int ext4_convert_inline_data(struct inode *inode) + goto out_free; + } + +- down_write(&EXT4_I(inode)->xattr_sem); +- if (!ext4_has_inline_data(inode)) { +- up_write(&EXT4_I(inode)->xattr_sem); +- goto out; +- } +- +- error = ext4_convert_inline_data_nolock(handle, inode, &iloc); +- up_write(&EXT4_I(inode)->xattr_sem); +-out: ++ ext4_write_lock_xattr(inode, &no_expand); ++ if (ext4_has_inline_data(inode)) ++ error = ext4_convert_inline_data_nolock(handle, inode, &iloc); ++ ext4_write_unlock_xattr(inode, &no_expand); + ext4_journal_stop(handle); + out_free: + brelse(iloc.bh); +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index f0cabc8c96cb..56ce7fd0f0d0 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -1515,6 +1515,8 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd, + BUG_ON(!PageLocked(page)); + BUG_ON(PageWriteback(page)); + if (invalidate) { ++ if (page_mapped(page)) ++ clear_page_dirty_for_io(page); + block_invalidatepage(page, 0, PAGE_CACHE_SIZE); + ClearPageUptodate(page); + } +@@ -3256,29 +3258,29 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter, + * case, we allocate an io_end structure to hook to the iocb. + */ + iocb->private = NULL; +- ext4_inode_aio_set(inode, NULL); +- if (!is_sync_kiocb(iocb)) { +- io_end = ext4_init_io_end(inode, GFP_NOFS); +- if (!io_end) { +- ret = -ENOMEM; +- goto retake_lock; +- } +- /* +- * Grab reference for DIO. Will be dropped in ext4_end_io_dio() +- */ +- iocb->private = ext4_get_io_end(io_end); +- /* +- * we save the io structure for current async direct +- * IO, so that later ext4_map_blocks() could flag the +- * io structure whether there is a unwritten extents +- * needs to be converted when IO is completed. +- */ +- ext4_inode_aio_set(inode, io_end); +- } +- + if (overwrite) { + get_block_func = ext4_get_block_write_nolock; + } else { ++ ext4_inode_aio_set(inode, NULL); ++ if (!is_sync_kiocb(iocb)) { ++ io_end = ext4_init_io_end(inode, GFP_NOFS); ++ if (!io_end) { ++ ret = -ENOMEM; ++ goto retake_lock; ++ } ++ /* ++ * Grab reference for DIO. Will be dropped in ++ * ext4_end_io_dio() ++ */ ++ iocb->private = ext4_get_io_end(io_end); ++ /* ++ * we save the io structure for current async direct ++ * IO, so that later ext4_map_blocks() could flag the ++ * io structure whether there is a unwritten extents ++ * needs to be converted when IO is completed. ++ */ ++ ext4_inode_aio_set(inode, io_end); ++ } + get_block_func = ext4_get_block_write; + dio_flags = DIO_LOCKING; + } +@@ -4231,6 +4233,12 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) + goto bad_inode; + raw_inode = ext4_raw_inode(&iloc); + ++ if ((ino == EXT4_ROOT_INO) && (raw_inode->i_links_count == 0)) { ++ EXT4_ERROR_INODE(inode, "root inode unallocated"); ++ ret = -EFSCORRUPTED; ++ goto bad_inode; ++ } ++ + if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { + ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); + if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 742455292dfe..0e0438b5ddbe 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2131,6 +2131,8 @@ static int ext4_check_descriptors(struct super_block *sb, + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Block bitmap for group %u overlaps " + "superblock", i); ++ if (!(sb->s_flags & MS_RDONLY)) ++ return 0; + } + if (block_bitmap < first_block || block_bitmap > last_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " +@@ -2143,6 +2145,8 @@ static int ext4_check_descriptors(struct super_block *sb, + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode bitmap for group %u overlaps " + "superblock", i); ++ if (!(sb->s_flags & MS_RDONLY)) ++ return 0; + } + if (inode_bitmap < first_block || inode_bitmap > last_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " +@@ -2155,6 +2159,8 @@ static int ext4_check_descriptors(struct super_block *sb, + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode table for group %u overlaps " + "superblock", i); ++ if (!(sb->s_flags & MS_RDONLY)) ++ return 0; + } + if (inode_table < first_block || + inode_table + sbi->s_itb_per_group - 1 > last_block) { +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index 8d661b3c47b6..c7cad05aed27 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1117,16 +1117,14 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, + struct ext4_xattr_block_find bs = { + .s = { .not_found = -ENODATA, }, + }; +- unsigned long no_expand; ++ int no_expand; + int error; + + if (!name) + return -EINVAL; + if (strlen(name) > 255) + return -ERANGE; +- down_write(&EXT4_I(inode)->xattr_sem); +- no_expand = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND); +- ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ ext4_write_lock_xattr(inode, &no_expand); + + error = ext4_reserve_inode_write(handle, inode, &is.iloc); + if (error) +@@ -1187,7 +1185,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, + ext4_xattr_update_super_block(handle, inode->i_sb); + inode->i_ctime = ext4_current_time(inode); + if (!value) +- ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ no_expand = 0; + error = ext4_mark_iloc_dirty(handle, inode, &is.iloc); + /* + * The bh is consumed by ext4_mark_iloc_dirty, even with +@@ -1201,9 +1199,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, + cleanup: + brelse(is.iloc.bh); + brelse(bs.bh); +- if (no_expand == 0) +- ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + return error; + } + +@@ -1287,12 +1283,11 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, + int error = 0, tried_min_extra_isize = 0; + int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); + int isize_diff; /* How much do we need to grow i_extra_isize */ ++ int no_expand; ++ ++ if (ext4_write_trylock_xattr(inode, &no_expand) == 0) ++ return 0; + +- down_write(&EXT4_I(inode)->xattr_sem); +- /* +- * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty +- */ +- ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); + retry: + isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize; + if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) +@@ -1486,8 +1481,7 @@ retry: + } + brelse(bh); + out: +- ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); +- up_write(&EXT4_I(inode)->xattr_sem); ++ ext4_write_unlock_xattr(inode, &no_expand); + return 0; + + cleanup: +@@ -1499,10 +1493,10 @@ cleanup: + kfree(bs); + brelse(bh); + /* +- * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode +- * size expansion failed. ++ * Inode size expansion failed; don't try again + */ +- up_write(&EXT4_I(inode)->xattr_sem); ++ no_expand = 1; ++ ext4_write_unlock_xattr(inode, &no_expand); + return error; + } + +diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h +index ddc0957760ba..c000ed398555 100644 +--- a/fs/ext4/xattr.h ++++ b/fs/ext4/xattr.h +@@ -101,6 +101,38 @@ extern const struct xattr_handler ext4_xattr_security_handler; + + #define EXT4_XATTR_NAME_ENCRYPTION_CONTEXT "c" + ++/* ++ * The EXT4_STATE_NO_EXPAND is overloaded and used for two purposes. ++ * The first is to signal that there the inline xattrs and data are ++ * taking up so much space that we might as well not keep trying to ++ * expand it. The second is that xattr_sem is taken for writing, so ++ * we shouldn't try to recurse into the inode expansion. For this ++ * second case, we need to make sure that we take save and restore the ++ * NO_EXPAND state flag appropriately. ++ */ ++static inline void ext4_write_lock_xattr(struct inode *inode, int *save) ++{ ++ down_write(&EXT4_I(inode)->xattr_sem); ++ *save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); ++} ++ ++static inline int ext4_write_trylock_xattr(struct inode *inode, int *save) ++{ ++ if (down_write_trylock(&EXT4_I(inode)->xattr_sem) == 0) ++ return 0; ++ *save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ return 1; ++} ++ ++static inline void ext4_write_unlock_xattr(struct inode *inode, int *save) ++{ ++ if (*save == 0) ++ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); ++ up_write(&EXT4_I(inode)->xattr_sem); ++} ++ + extern ssize_t ext4_listxattr(struct dentry *, char *, size_t); + + extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t); +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index 22b30249fbcb..0fe667875852 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -747,11 +747,12 @@ int inode_congested(struct inode *inode, int cong_bits) + */ + if (inode && inode_to_wb_is_valid(inode)) { + struct bdi_writeback *wb; +- bool locked, congested; ++ struct wb_lock_cookie lock_cookie = {}; ++ bool congested; + +- wb = unlocked_inode_to_wb_begin(inode, &locked); ++ wb = unlocked_inode_to_wb_begin(inode, &lock_cookie); + congested = wb_congested(wb, cong_bits); +- unlocked_inode_to_wb_end(inode, locked); ++ unlocked_inode_to_wb_end(inode, &lock_cookie); + return congested; + } + +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index 624a57a9c4aa..4759df4eb8ce 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -914,7 +914,7 @@ out: + } + + /* +- * This is a variaon of __jbd2_update_log_tail which checks for validity of ++ * This is a variation of __jbd2_update_log_tail which checks for validity of + * provided log tail and locks j_checkpoint_mutex. So it is safe against races + * with other threads updating log tail. + */ +@@ -1384,6 +1384,9 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid, + journal_superblock_t *sb = journal->j_superblock; + int ret; + ++ if (is_journal_aborted(journal)) ++ return -EIO; ++ + BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); + jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n", + tail_block, tail_tid); +diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c +index d86c5e3176a1..600da1a4df29 100644 +--- a/fs/jffs2/super.c ++++ b/fs/jffs2/super.c +@@ -345,7 +345,7 @@ static void jffs2_put_super (struct super_block *sb) + static void jffs2_kill_sb(struct super_block *sb) + { + struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); +- if (!(sb->s_flags & MS_RDONLY)) ++ if (c && !(sb->s_flags & MS_RDONLY)) + jffs2_stop_garbage_collect_thread(c); + kill_mtd_super(sb); + kfree(c); +diff --git a/fs/namei.c b/fs/namei.c +index 0fcad42e4d3e..de57dd59d95f 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -219,9 +219,10 @@ getname_kernel(const char * filename) + if (len <= EMBEDDED_NAME_MAX) { + result->name = (char *)result->iname; + } else if (len <= PATH_MAX) { ++ const size_t size = offsetof(struct filename, iname[1]); + struct filename *tmp; + +- tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); ++ tmp = kmalloc(size, GFP_KERNEL); + if (unlikely(!tmp)) { + __putname(result); + return ERR_PTR(-ENOMEM); +diff --git a/fs/namespace.c b/fs/namespace.c +index ec4078d16eb7..a879560ea144 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -1018,7 +1018,8 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, + goto out_free; + } + +- mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED); ++ mnt->mnt.mnt_flags = old->mnt.mnt_flags; ++ mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL); + /* Don't allow unprivileged users to change mount flags */ + if (flag & CL_UNPRIVILEGED) { + mnt->mnt.mnt_flags |= MNT_LOCK_ATIME; +diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c +index e0e5f7c3c99f..8a459b179183 100644 +--- a/fs/notify/fanotify/fanotify.c ++++ b/fs/notify/fanotify/fanotify.c +@@ -92,7 +92,7 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark, + u32 event_mask, + void *data, int data_type) + { +- __u32 marks_mask, marks_ignored_mask; ++ __u32 marks_mask = 0, marks_ignored_mask = 0; + struct path *path = data; + + pr_debug("%s: inode_mark=%p vfsmnt_mark=%p mask=%x data=%p" +@@ -108,24 +108,20 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark, + !d_can_lookup(path->dentry)) + return false; + +- if (inode_mark && vfsmnt_mark) { +- marks_mask = (vfsmnt_mark->mask | inode_mark->mask); +- marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask); +- } else if (inode_mark) { +- /* +- * if the event is for a child and this inode doesn't care about +- * events on the child, don't send it! +- */ +- if ((event_mask & FS_EVENT_ON_CHILD) && +- !(inode_mark->mask & FS_EVENT_ON_CHILD)) +- return false; +- marks_mask = inode_mark->mask; +- marks_ignored_mask = inode_mark->ignored_mask; +- } else if (vfsmnt_mark) { +- marks_mask = vfsmnt_mark->mask; +- marks_ignored_mask = vfsmnt_mark->ignored_mask; +- } else { +- BUG(); ++ /* ++ * if the event is for a child and this inode doesn't care about ++ * events on the child, don't send it! ++ */ ++ if (inode_mark && ++ (!(event_mask & FS_EVENT_ON_CHILD) || ++ (inode_mark->mask & FS_EVENT_ON_CHILD))) { ++ marks_mask |= inode_mark->mask; ++ marks_ignored_mask |= inode_mark->ignored_mask; ++ } ++ ++ if (vfsmnt_mark) { ++ marks_mask |= vfsmnt_mark->mask; ++ marks_ignored_mask |= vfsmnt_mark->ignored_mask; + } + + if (d_is_dir(path->dentry) && +diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c +index a72097b625ef..00985f9db9f7 100644 +--- a/fs/reiserfs/journal.c ++++ b/fs/reiserfs/journal.c +@@ -2643,7 +2643,7 @@ static int journal_init_dev(struct super_block *super, + if (IS_ERR(journal->j_dev_bd)) { + result = PTR_ERR(journal->j_dev_bd); + journal->j_dev_bd = NULL; +- reiserfs_warning(super, ++ reiserfs_warning(super, "sh-457", + "journal_init_dev: Cannot open '%s': %i", + jdev_name, result); + return result; +diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c +index 1fd90c079537..0bb6de356451 100644 +--- a/fs/ubifs/super.c ++++ b/fs/ubifs/super.c +@@ -1728,8 +1728,11 @@ static void ubifs_remount_ro(struct ubifs_info *c) + + dbg_save_space_info(c); + +- for (i = 0; i < c->jhead_cnt; i++) +- ubifs_wbuf_sync(&c->jheads[i].wbuf); ++ for (i = 0; i < c->jhead_cnt; i++) { ++ err = ubifs_wbuf_sync(&c->jheads[i].wbuf); ++ if (err) ++ ubifs_ro_mode(c, err); ++ } + + c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); + c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); +@@ -1795,8 +1798,11 @@ static void ubifs_put_super(struct super_block *sb) + int err; + + /* Synchronize write-buffers */ +- for (i = 0; i < c->jhead_cnt; i++) +- ubifs_wbuf_sync(&c->jheads[i].wbuf); ++ for (i = 0; i < c->jhead_cnt; i++) { ++ err = ubifs_wbuf_sync(&c->jheads[i].wbuf); ++ if (err) ++ ubifs_ro_mode(c, err); ++ } + + /* + * We are being cleanly unmounted which means the +diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h +index 140c29635069..a307c37c2e6c 100644 +--- a/include/linux/backing-dev-defs.h ++++ b/include/linux/backing-dev-defs.h +@@ -191,6 +191,11 @@ static inline void set_bdi_congested(struct backing_dev_info *bdi, int sync) + set_wb_congested(bdi->wb.congested, sync); + } + ++struct wb_lock_cookie { ++ bool locked; ++ unsigned long flags; ++}; ++ + #ifdef CONFIG_CGROUP_WRITEBACK + + /** +diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h +index 89d3de3e096b..361274ce5815 100644 +--- a/include/linux/backing-dev.h ++++ b/include/linux/backing-dev.h +@@ -366,7 +366,7 @@ static inline struct bdi_writeback *inode_to_wb(struct inode *inode) + /** + * unlocked_inode_to_wb_begin - begin unlocked inode wb access transaction + * @inode: target inode +- * @lockedp: temp bool output param, to be passed to the end function ++ * @cookie: output param, to be passed to the end function + * + * The caller wants to access the wb associated with @inode but isn't + * holding inode->i_lock, mapping->tree_lock or wb->list_lock. This +@@ -374,12 +374,12 @@ static inline struct bdi_writeback *inode_to_wb(struct inode *inode) + * association doesn't change until the transaction is finished with + * unlocked_inode_to_wb_end(). + * +- * The caller must call unlocked_inode_to_wb_end() with *@lockdep +- * afterwards and can't sleep during transaction. IRQ may or may not be +- * disabled on return. ++ * The caller must call unlocked_inode_to_wb_end() with *@cookie afterwards and ++ * can't sleep during the transaction. IRQs may or may not be disabled on ++ * return. + */ + static inline struct bdi_writeback * +-unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp) ++unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie) + { + rcu_read_lock(); + +@@ -387,10 +387,10 @@ unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp) + * Paired with store_release in inode_switch_wb_work_fn() and + * ensures that we see the new wb if we see cleared I_WB_SWITCH. + */ +- *lockedp = smp_load_acquire(&inode->i_state) & I_WB_SWITCH; ++ cookie->locked = smp_load_acquire(&inode->i_state) & I_WB_SWITCH; + +- if (unlikely(*lockedp)) +- spin_lock_irq(&inode->i_mapping->tree_lock); ++ if (unlikely(cookie->locked)) ++ spin_lock_irqsave(&inode->i_mapping->tree_lock, cookie->flags); + + /* + * Protected by either !I_WB_SWITCH + rcu_read_lock() or tree_lock. +@@ -402,12 +402,14 @@ unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp) + /** + * unlocked_inode_to_wb_end - end inode wb access transaction + * @inode: target inode +- * @locked: *@lockedp from unlocked_inode_to_wb_begin() ++ * @cookie: @cookie from unlocked_inode_to_wb_begin() + */ +-static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked) ++static inline void unlocked_inode_to_wb_end(struct inode *inode, ++ struct wb_lock_cookie *cookie) + { +- if (unlikely(locked)) +- spin_unlock_irq(&inode->i_mapping->tree_lock); ++ if (unlikely(cookie->locked)) ++ spin_unlock_irqrestore(&inode->i_mapping->tree_lock, ++ cookie->flags); + + rcu_read_unlock(); + } +@@ -454,12 +456,13 @@ static inline struct bdi_writeback *inode_to_wb(struct inode *inode) + } + + static inline struct bdi_writeback * +-unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp) ++unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie) + { + return inode_to_wb(inode); + } + +-static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked) ++static inline void unlocked_inode_to_wb_end(struct inode *inode, ++ struct wb_lock_cookie *cookie) + { + } + +diff --git a/include/linux/hid.h b/include/linux/hid.h +index 251a1d382e23..fd86687f8119 100644 +--- a/include/linux/hid.h ++++ b/include/linux/hid.h +@@ -793,7 +793,7 @@ extern int hidinput_connect(struct hid_device *hid, unsigned int force); + extern void hidinput_disconnect(struct hid_device *); + + int hid_set_field(struct hid_field *, unsigned, __s32); +-int hid_input_report(struct hid_device *, int type, u8 *, int, int); ++int hid_input_report(struct hid_device *, int type, u8 *, u32, int); + int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); + struct hid_field *hidinput_get_led_field(struct hid_device *hid); + unsigned int hidinput_count_leds(struct hid_device *hid); +@@ -1098,13 +1098,13 @@ static inline void hid_hw_wait(struct hid_device *hdev) + * + * @report: the report we want to know the length + */ +-static inline int hid_report_len(struct hid_report *report) ++static inline u32 hid_report_len(struct hid_report *report) + { + /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ + return ((report->size - 1) >> 3) + 1 + (report->id > 0); + } + +-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, ++int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, + int interrupt); + + /* HID quirks API */ +diff --git a/include/linux/mm.h b/include/linux/mm.h +index 55f950afb60d..a100946607a5 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -225,10 +225,14 @@ extern pgprot_t protection_map[16]; + * ->fault function. The vma's ->fault is responsible for returning a bitmask + * of VM_FAULT_xxx flags that give details about how the fault was handled. + * ++ * MM layer fills up gfp_mask for page allocations but fault handler might ++ * alter it if its implementation requires a different allocation context. ++ * + * pgoff should be used in favour of virtual_address, if possible. + */ + struct vm_fault { + unsigned int flags; /* FAULT_FLAG_xxx flags */ ++ gfp_t gfp_mask; /* gfp mask to be used for allocations */ + pgoff_t pgoff; /* Logical page offset based on vma */ + void __user *virtual_address; /* Faulting virtual address */ + +diff --git a/include/linux/tty.h b/include/linux/tty.h +index a1042afff99a..d67ceb3f5958 100644 +--- a/include/linux/tty.h ++++ b/include/linux/tty.h +@@ -342,6 +342,7 @@ struct tty_file_private { + #define TTY_PTY_LOCK 16 /* pty private */ + #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ + #define TTY_HUPPED 18 /* Post driver->hangup() */ ++#define TTY_HUPPING 19 /* Hangup in progress */ + #define TTY_LDISC_HALTED 22 /* Line discipline is halted */ + + #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) +diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h +index 8716d5942b65..8fcf8908a694 100644 +--- a/include/net/slhc_vj.h ++++ b/include/net/slhc_vj.h +@@ -127,6 +127,7 @@ typedef __u32 int32; + */ + struct cstate { + byte_t cs_this; /* connection id number (xmit) */ ++ bool initialized; /* true if initialized */ + struct cstate *next; /* next in ring (xmit) */ + struct iphdr cs_ip; /* ip/tcp hdr from most recent packet */ + struct tcphdr cs_tcp; +diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h +index 760c969d885d..12bbf8c81112 100644 +--- a/include/sound/pcm_oss.h ++++ b/include/sound/pcm_oss.h +@@ -57,6 +57,7 @@ struct snd_pcm_oss_runtime { + char *buffer; /* vmallocated period */ + size_t buffer_used; /* used length from period buffer */ + struct mutex params_lock; ++ atomic_t rw_ref; /* concurrent read/write accesses */ + #ifdef CONFIG_SND_PCM_OSS_PLUGINS + struct snd_pcm_plugin *plugin_first; + struct snd_pcm_plugin *plugin_last; +diff --git a/ipc/shm.c b/ipc/shm.c +index 4982a4e7f009..a492dd81cf56 100644 +--- a/ipc/shm.c ++++ b/ipc/shm.c +@@ -198,6 +198,12 @@ static int __shm_open(struct vm_area_struct *vma) + if (IS_ERR(shp)) + return PTR_ERR(shp); + ++ if (shp->shm_file != sfd->file) { ++ /* ID was reused */ ++ shm_unlock(shp); ++ return -EINVAL; ++ } ++ + shp->shm_atim = get_seconds(); + shp->shm_lprid = task_tgid_vnr(current); + shp->shm_nattch++; +@@ -414,8 +420,9 @@ static int shm_mmap(struct file *file, struct vm_area_struct *vma) + int ret; + + /* +- * In case of remap_file_pages() emulation, the file can represent +- * removed IPC ID: propogate shm_lock() error to caller. ++ * In case of remap_file_pages() emulation, the file can represent an ++ * IPC ID that was removed, and possibly even reused by another shm ++ * segment already. Propagate this case as an error to caller. + */ + ret =__shm_open(vma); + if (ret) +@@ -439,6 +446,7 @@ static int shm_release(struct inode *ino, struct file *file) + struct shm_file_data *sfd = shm_file_data(file); + + put_ipc_ns(sfd->ns); ++ fput(sfd->file); + shm_file_data(file) = NULL; + kfree(sfd); + return 0; +@@ -1198,7 +1206,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, + file->f_mapping = shp->shm_file->f_mapping; + sfd->id = shp->shm_perm.id; + sfd->ns = get_ipc_ns(ns); +- sfd->file = shp->shm_file; ++ /* ++ * We need to take a reference to the real shm file to prevent the ++ * pointer from becoming stale in cases where the lifetime of the outer ++ * file extends beyond that of the shm segment. It's not usually ++ * possible, but it can happen during remap_file_pages() emulation as ++ * that unmaps the memory, then does ->mmap() via file reference only. ++ * We'll deny the ->mmap() if the shm segment was since removed, but to ++ * detect shm ID reuse we need to compare the file pointers. ++ */ ++ sfd->file = get_file(shp->shm_file); + sfd->vm_ops = NULL; + + err = security_mmap_file(file, prot, flags); +diff --git a/kernel/resource.c b/kernel/resource.c +index a4a94e700fb9..41718cd8cab5 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -611,7 +611,8 @@ static int __find_resource(struct resource *root, struct resource *old, + alloc.start = constraint->alignf(constraint->alignf_data, &avail, + size, constraint->align); + alloc.end = alloc.start + size - 1; +- if (resource_contains(&avail, &alloc)) { ++ if (alloc.start <= alloc.end && ++ resource_contains(&avail, &alloc)) { + new->start = alloc.start; + new->end = alloc.end; + return 0; +diff --git a/mm/filemap.c b/mm/filemap.c +index 69f75c77c098..b15f1d8bba43 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -571,7 +571,7 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask) + VM_BUG_ON_PAGE(!PageLocked(new), new); + VM_BUG_ON_PAGE(new->mapping, new); + +- error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM); ++ error = radix_tree_preload(gfp_mask & GFP_RECLAIM_MASK); + if (!error) { + struct address_space *mapping = old->mapping; + void (*freepage)(struct page *); +@@ -630,7 +630,7 @@ static int __add_to_page_cache_locked(struct page *page, + return error; + } + +- error = radix_tree_maybe_preload(gfp_mask & ~__GFP_HIGHMEM); ++ error = radix_tree_maybe_preload(gfp_mask & GFP_RECLAIM_MASK); + if (error) { + if (!huge) + mem_cgroup_cancel_charge(page, memcg); +@@ -1192,8 +1192,7 @@ no_page: + if (fgp_flags & FGP_ACCESSED) + __SetPageReferenced(page); + +- err = add_to_page_cache_lru(page, mapping, offset, +- gfp_mask & GFP_RECLAIM_MASK); ++ err = add_to_page_cache_lru(page, mapping, offset, gfp_mask); + if (unlikely(err)) { + page_cache_release(page); + page = NULL; +@@ -1827,19 +1826,18 @@ EXPORT_SYMBOL(generic_file_read_iter); + * This adds the requested page to the page cache if it isn't already there, + * and schedules an I/O to read in its contents from disk. + */ +-static int page_cache_read(struct file *file, pgoff_t offset) ++static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask) + { + struct address_space *mapping = file->f_mapping; + struct page *page; + int ret; + + do { +- page = page_cache_alloc_cold(mapping); ++ page = __page_cache_alloc(gfp_mask|__GFP_COLD); + if (!page) + return -ENOMEM; + +- ret = add_to_page_cache_lru(page, mapping, offset, +- mapping_gfp_constraint(mapping, GFP_KERNEL)); ++ ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask); + if (ret == 0) + ret = mapping->a_ops->readpage(file, page); + else if (ret == -EEXIST) +@@ -2020,7 +2018,7 @@ no_cached_page: + * We're only likely to ever get here if MADV_RANDOM is in + * effect. + */ +- error = page_cache_read(file, offset); ++ error = page_cache_read(file, offset, vmf->gfp_mask); + + /* + * The page we want has now been added to the page cache. +diff --git a/mm/memory.c b/mm/memory.c +index 31ca97f7ebbc..177cb7d111a9 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -1990,6 +1990,20 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo + copy_user_highpage(dst, src, va, vma); + } + ++static gfp_t __get_fault_gfp_mask(struct vm_area_struct *vma) ++{ ++ struct file *vm_file = vma->vm_file; ++ ++ if (vm_file) ++ return mapping_gfp_mask(vm_file->f_mapping) | __GFP_FS | __GFP_IO; ++ ++ /* ++ * Special mappings (e.g. VDSO) do not have any file so fake ++ * a default GFP_KERNEL for them. ++ */ ++ return GFP_KERNEL; ++} ++ + /* + * Notify the address space that the page is about to become writable so that + * it can prohibit this or wait for the page to get into an appropriate state. +@@ -2005,6 +2019,7 @@ static int do_page_mkwrite(struct vm_area_struct *vma, struct page *page, + vmf.virtual_address = (void __user *)(address & PAGE_MASK); + vmf.pgoff = page->index; + vmf.flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE; ++ vmf.gfp_mask = __get_fault_gfp_mask(vma); + vmf.page = page; + vmf.cow_page = NULL; + +@@ -2770,6 +2785,7 @@ static int __do_fault(struct vm_area_struct *vma, unsigned long address, + vmf.pgoff = pgoff; + vmf.flags = flags; + vmf.page = NULL; ++ vmf.gfp_mask = __get_fault_gfp_mask(vma); + vmf.cow_page = cow_page; + + ret = vma->vm_ops->fault(vma, &vmf); +@@ -2936,6 +2952,7 @@ static void do_fault_around(struct vm_area_struct *vma, unsigned long address, + vmf.pgoff = pgoff; + vmf.max_pgoff = max_pgoff; + vmf.flags = flags; ++ vmf.gfp_mask = __get_fault_gfp_mask(vma); + vma->vm_ops->map_pages(vma, &vmf); + } + +diff --git a/mm/page-writeback.c b/mm/page-writeback.c +index 6d0dbde4503b..3309dbda7ffa 100644 +--- a/mm/page-writeback.c ++++ b/mm/page-writeback.c +@@ -2510,13 +2510,13 @@ void account_page_redirty(struct page *page) + if (mapping && mapping_cap_account_dirty(mapping)) { + struct inode *inode = mapping->host; + struct bdi_writeback *wb; +- bool locked; ++ struct wb_lock_cookie cookie = {}; + +- wb = unlocked_inode_to_wb_begin(inode, &locked); ++ wb = unlocked_inode_to_wb_begin(inode, &cookie); + current->nr_dirtied--; + dec_zone_page_state(page, NR_DIRTIED); + dec_wb_stat(wb, WB_DIRTIED); +- unlocked_inode_to_wb_end(inode, locked); ++ unlocked_inode_to_wb_end(inode, &cookie); + } + } + EXPORT_SYMBOL(account_page_redirty); +@@ -2622,15 +2622,15 @@ void cancel_dirty_page(struct page *page) + struct inode *inode = mapping->host; + struct bdi_writeback *wb; + struct mem_cgroup *memcg; +- bool locked; ++ struct wb_lock_cookie cookie = {}; + + memcg = mem_cgroup_begin_page_stat(page); +- wb = unlocked_inode_to_wb_begin(inode, &locked); ++ wb = unlocked_inode_to_wb_begin(inode, &cookie); + + if (TestClearPageDirty(page)) + account_page_cleaned(page, mapping, memcg, wb); + +- unlocked_inode_to_wb_end(inode, locked); ++ unlocked_inode_to_wb_end(inode, &cookie); + mem_cgroup_end_page_stat(memcg); + } else { + ClearPageDirty(page); +@@ -2663,7 +2663,7 @@ int clear_page_dirty_for_io(struct page *page) + struct inode *inode = mapping->host; + struct bdi_writeback *wb; + struct mem_cgroup *memcg; +- bool locked; ++ struct wb_lock_cookie cookie = {}; + + /* + * Yes, Virginia, this is indeed insane. +@@ -2701,14 +2701,14 @@ int clear_page_dirty_for_io(struct page *page) + * exclusion. + */ + memcg = mem_cgroup_begin_page_stat(page); +- wb = unlocked_inode_to_wb_begin(inode, &locked); ++ wb = unlocked_inode_to_wb_begin(inode, &cookie); + if (TestClearPageDirty(page)) { + mem_cgroup_dec_page_stat(memcg, MEM_CGROUP_STAT_DIRTY); + dec_zone_page_state(page, NR_FILE_DIRTY); + dec_wb_stat(wb, WB_RECLAIMABLE); + ret = 1; + } +- unlocked_inode_to_wb_end(inode, locked); ++ unlocked_inode_to_wb_end(inode, &cookie); + mem_cgroup_end_page_stat(memcg); + return ret; + } +diff --git a/mm/slab.c b/mm/slab.c +index 4765c97ce690..fa49c01225a7 100644 +--- a/mm/slab.c ++++ b/mm/slab.c +@@ -3915,7 +3915,8 @@ next: + next_reap_node(); + out: + /* Set up the next iteration */ +- schedule_delayed_work(work, round_jiffies_relative(REAPTIMEOUT_AC)); ++ schedule_delayed_work_on(smp_processor_id(), work, ++ round_jiffies_relative(REAPTIMEOUT_AC)); + } + + #ifdef CONFIG_SLABINFO +diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c +index d81186d34558..9103dd15511c 100644 +--- a/net/sunrpc/rpc_pipe.c ++++ b/net/sunrpc/rpc_pipe.c +@@ -1375,6 +1375,7 @@ rpc_gssd_dummy_depopulate(struct dentry *pipe_dentry) + struct dentry *clnt_dir = pipe_dentry->d_parent; + struct dentry *gssd_dir = clnt_dir->d_parent; + ++ dget(pipe_dentry); + __rpc_rmpipe(d_inode(clnt_dir), pipe_dentry); + __rpc_depopulate(clnt_dir, gssd_dummy_info_file, 0, 1); + __rpc_depopulate(gssd_dir, gssd_dummy_clnt_dir, 0, 1); +diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c +index 6cd8aec146f2..07feb35f1935 100644 +--- a/sound/core/oss/pcm_oss.c ++++ b/sound/core/oss/pcm_oss.c +@@ -833,8 +833,25 @@ static int choose_rate(struct snd_pcm_substream *substream, + return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); + } + +-static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, +- bool trylock) ++/* parameter locking: returns immediately if tried during streaming */ ++static int lock_params(struct snd_pcm_runtime *runtime) ++{ ++ if (mutex_lock_interruptible(&runtime->oss.params_lock)) ++ return -ERESTARTSYS; ++ if (atomic_read(&runtime->oss.rw_ref)) { ++ mutex_unlock(&runtime->oss.params_lock); ++ return -EBUSY; ++ } ++ return 0; ++} ++ ++static void unlock_params(struct snd_pcm_runtime *runtime) ++{ ++ mutex_unlock(&runtime->oss.params_lock); ++} ++ ++/* call with params_lock held */ ++static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) + { + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_pcm_hw_params *params, *sparams; +@@ -848,12 +865,9 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, + struct snd_mask sformat_mask; + struct snd_mask mask; + +- if (trylock) { +- if (!(mutex_trylock(&runtime->oss.params_lock))) +- return -EAGAIN; +- } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) +- return -EINTR; +- sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL); ++ if (!runtime->oss.params) ++ return 0; ++ sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); + params = kmalloc(sizeof(*params), GFP_KERNEL); + sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); + if (!sw_params || !params || !sparams) { +@@ -991,7 +1005,6 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, + goto failure; + } + +- memset(sw_params, 0, sizeof(*sw_params)); + if (runtime->oss.trigger) { + sw_params->start_threshold = 1; + } else { +@@ -1079,6 +1092,23 @@ failure: + kfree(sw_params); + kfree(params); + kfree(sparams); ++ return err; ++} ++ ++/* this one takes the lock by itself */ ++static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, ++ bool trylock) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ int err; ++ ++ if (trylock) { ++ if (!(mutex_trylock(&runtime->oss.params_lock))) ++ return -EAGAIN; ++ } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) ++ return -ERESTARTSYS; ++ ++ err = snd_pcm_oss_change_params_locked(substream); + mutex_unlock(&runtime->oss.params_lock); + return err; + } +@@ -1107,6 +1137,10 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil + return 0; + } + ++/* call with params_lock held */ ++/* NOTE: this always call PREPARE unconditionally no matter whether ++ * runtime->oss.prepare is set or not ++ */ + static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream) + { + int err; +@@ -1131,14 +1165,35 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream) + struct snd_pcm_runtime *runtime; + int err; + +- if (substream == NULL) +- return 0; + runtime = substream->runtime; + if (runtime->oss.params) { + err = snd_pcm_oss_change_params(substream, false); + if (err < 0) + return err; + } ++ if (runtime->oss.prepare) { ++ if (mutex_lock_interruptible(&runtime->oss.params_lock)) ++ return -ERESTARTSYS; ++ err = snd_pcm_oss_prepare(substream); ++ mutex_unlock(&runtime->oss.params_lock); ++ if (err < 0) ++ return err; ++ } ++ return 0; ++} ++ ++/* call with params_lock held */ ++static int snd_pcm_oss_make_ready_locked(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime; ++ int err; ++ ++ runtime = substream->runtime; ++ if (runtime->oss.params) { ++ err = snd_pcm_oss_change_params_locked(substream); ++ if (err < 0) ++ return err; ++ } + if (runtime->oss.prepare) { + err = snd_pcm_oss_prepare(substream); + if (err < 0) +@@ -1367,13 +1422,15 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha + if (atomic_read(&substream->mmap_count)) + return -ENXIO; + +- if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) +- return tmp; ++ atomic_inc(&runtime->oss.rw_ref); + while (bytes > 0) { + if (mutex_lock_interruptible(&runtime->oss.params_lock)) { + tmp = -ERESTARTSYS; + break; + } ++ tmp = snd_pcm_oss_make_ready_locked(substream); ++ if (tmp < 0) ++ goto err; + if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { + tmp = bytes; + if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes) +@@ -1429,6 +1486,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha + } + tmp = 0; + } ++ atomic_dec(&runtime->oss.rw_ref); + return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; + } + +@@ -1474,13 +1532,15 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use + if (atomic_read(&substream->mmap_count)) + return -ENXIO; + +- if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) +- return tmp; ++ atomic_inc(&runtime->oss.rw_ref); + while (bytes > 0) { + if (mutex_lock_interruptible(&runtime->oss.params_lock)) { + tmp = -ERESTARTSYS; + break; + } ++ tmp = snd_pcm_oss_make_ready_locked(substream); ++ if (tmp < 0) ++ goto err; + if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { + if (runtime->oss.buffer_used == 0) { + tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1); +@@ -1521,6 +1581,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use + } + tmp = 0; + } ++ atomic_dec(&runtime->oss.rw_ref); + return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; + } + +@@ -1536,10 +1597,12 @@ static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file) + continue; + runtime = substream->runtime; + snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); ++ mutex_lock(&runtime->oss.params_lock); + runtime->oss.prepare = 1; + runtime->oss.buffer_used = 0; + runtime->oss.prev_hw_ptr_period = 0; + runtime->oss.period_ptr = 0; ++ mutex_unlock(&runtime->oss.params_lock); + } + return 0; + } +@@ -1625,9 +1688,13 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) + goto __direct; + if ((err = snd_pcm_oss_make_ready(substream)) < 0) + return err; ++ atomic_inc(&runtime->oss.rw_ref); ++ if (mutex_lock_interruptible(&runtime->oss.params_lock)) { ++ atomic_dec(&runtime->oss.rw_ref); ++ return -ERESTARTSYS; ++ } + format = snd_pcm_oss_format_from(runtime->oss.format); + width = snd_pcm_format_physical_width(format); +- mutex_lock(&runtime->oss.params_lock); + if (runtime->oss.buffer_used > 0) { + #ifdef OSS_DEBUG + pcm_dbg(substream->pcm, "sync: buffer_used\n"); +@@ -1637,10 +1704,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) + runtime->oss.buffer + runtime->oss.buffer_used, + size); + err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes); +- if (err < 0) { +- mutex_unlock(&runtime->oss.params_lock); +- return err; +- } ++ if (err < 0) ++ goto unlock; + } else if (runtime->oss.period_ptr > 0) { + #ifdef OSS_DEBUG + pcm_dbg(substream->pcm, "sync: period_ptr\n"); +@@ -1650,10 +1715,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) + runtime->oss.buffer, + size * 8 / width); + err = snd_pcm_oss_sync1(substream, size); +- if (err < 0) { +- mutex_unlock(&runtime->oss.params_lock); +- return err; +- } ++ if (err < 0) ++ goto unlock; + } + /* + * The ALSA's period might be a bit large than OSS one. +@@ -1684,7 +1747,11 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) + snd_pcm_lib_writev(substream, buffers, size); + } + } ++unlock: + mutex_unlock(&runtime->oss.params_lock); ++ atomic_dec(&runtime->oss.rw_ref); ++ if (err < 0) ++ return err; + /* + * finish sync: drain the buffer + */ +@@ -1695,7 +1762,9 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) + substream->f_flags = saved_f_flags; + if (err < 0) + return err; ++ mutex_lock(&runtime->oss.params_lock); + runtime->oss.prepare = 1; ++ mutex_unlock(&runtime->oss.params_lock); + } + + substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; +@@ -1706,8 +1775,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) + err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); + if (err < 0) + return err; ++ mutex_lock(&runtime->oss.params_lock); + runtime->oss.buffer_used = 0; + runtime->oss.prepare = 1; ++ mutex_unlock(&runtime->oss.params_lock); + } + return 0; + } +@@ -1719,6 +1790,8 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate) + for (idx = 1; idx >= 0; --idx) { + struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; + struct snd_pcm_runtime *runtime; ++ int err; ++ + if (substream == NULL) + continue; + runtime = substream->runtime; +@@ -1726,10 +1799,14 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate) + rate = 1000; + else if (rate > 192000) + rate = 192000; ++ err = lock_params(runtime); ++ if (err < 0) ++ return err; + if (runtime->oss.rate != rate) { + runtime->oss.params = 1; + runtime->oss.rate = rate; + } ++ unlock_params(runtime); + } + return snd_pcm_oss_get_rate(pcm_oss_file); + } +@@ -1754,13 +1831,19 @@ static int snd_pcm_oss_set_channels(struct snd_pcm_oss_file *pcm_oss_file, unsig + for (idx = 1; idx >= 0; --idx) { + struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; + struct snd_pcm_runtime *runtime; ++ int err; ++ + if (substream == NULL) + continue; + runtime = substream->runtime; ++ err = lock_params(runtime); ++ if (err < 0) ++ return err; + if (runtime->oss.channels != channels) { + runtime->oss.params = 1; + runtime->oss.channels = channels; + } ++ unlock_params(runtime); + } + return snd_pcm_oss_get_channels(pcm_oss_file); + } +@@ -1833,6 +1916,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) + static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) + { + int formats, idx; ++ int err; + + if (format != AFMT_QUERY) { + formats = snd_pcm_oss_get_formats(pcm_oss_file); +@@ -1846,10 +1930,14 @@ static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int for + if (substream == NULL) + continue; + runtime = substream->runtime; ++ err = lock_params(runtime); ++ if (err < 0) ++ return err; + if (runtime->oss.format != format) { + runtime->oss.params = 1; + runtime->oss.format = format; + } ++ unlock_params(runtime); + } + } + return snd_pcm_oss_get_format(pcm_oss_file); +@@ -1869,8 +1957,6 @@ static int snd_pcm_oss_set_subdivide1(struct snd_pcm_substream *substream, int s + { + struct snd_pcm_runtime *runtime; + +- if (substream == NULL) +- return 0; + runtime = substream->runtime; + if (subdivide == 0) { + subdivide = runtime->oss.subdivision; +@@ -1894,9 +1980,17 @@ static int snd_pcm_oss_set_subdivide(struct snd_pcm_oss_file *pcm_oss_file, int + + for (idx = 1; idx >= 0; --idx) { + struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; ++ struct snd_pcm_runtime *runtime; ++ + if (substream == NULL) + continue; +- if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0) ++ runtime = substream->runtime; ++ err = lock_params(runtime); ++ if (err < 0) ++ return err; ++ err = snd_pcm_oss_set_subdivide1(substream, subdivide); ++ unlock_params(runtime); ++ if (err < 0) + return err; + } + return err; +@@ -1906,8 +2000,6 @@ static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsign + { + struct snd_pcm_runtime *runtime; + +- if (substream == NULL) +- return 0; + runtime = substream->runtime; + if (runtime->oss.subdivision || runtime->oss.fragshift) + return -EINVAL; +@@ -1927,9 +2019,17 @@ static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsig + + for (idx = 1; idx >= 0; --idx) { + struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; ++ struct snd_pcm_runtime *runtime; ++ + if (substream == NULL) + continue; +- if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0) ++ runtime = substream->runtime; ++ err = lock_params(runtime); ++ if (err < 0) ++ return err; ++ err = snd_pcm_oss_set_fragment1(substream, val); ++ unlock_params(runtime); ++ if (err < 0) + return err; + } + return err; +@@ -2013,6 +2113,9 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr + } + if (psubstream) { + runtime = psubstream->runtime; ++ cmd = 0; ++ if (mutex_lock_interruptible(&runtime->oss.params_lock)) ++ return -ERESTARTSYS; + if (trigger & PCM_ENABLE_OUTPUT) { + if (runtime->oss.trigger) + goto _skip1; +@@ -2030,13 +2133,19 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr + cmd = SNDRV_PCM_IOCTL_DROP; + runtime->oss.prepare = 1; + } +- err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL); +- if (err < 0) +- return err; +- } + _skip1: ++ mutex_unlock(&runtime->oss.params_lock); ++ if (cmd) { ++ err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL); ++ if (err < 0) ++ return err; ++ } ++ } + if (csubstream) { + runtime = csubstream->runtime; ++ cmd = 0; ++ if (mutex_lock_interruptible(&runtime->oss.params_lock)) ++ return -ERESTARTSYS; + if (trigger & PCM_ENABLE_INPUT) { + if (runtime->oss.trigger) + goto _skip2; +@@ -2051,11 +2160,14 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr + cmd = SNDRV_PCM_IOCTL_DROP; + runtime->oss.prepare = 1; + } +- err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL); +- if (err < 0) +- return err; +- } + _skip2: ++ mutex_unlock(&runtime->oss.params_lock); ++ if (cmd) { ++ err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL); ++ if (err < 0) ++ return err; ++ } ++ } + return 0; + } + +@@ -2307,6 +2419,7 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, + runtime->oss.maxfrags = 0; + runtime->oss.subdivision = 0; + substream->pcm_release = snd_pcm_oss_release_substream; ++ atomic_set(&runtime->oss.rw_ref, 0); + } + + static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) +diff --git a/sound/core/pcm.c b/sound/core/pcm.c +index 074363b63cc4..6bda8f6c5f84 100644 +--- a/sound/core/pcm.c ++++ b/sound/core/pcm.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -1025,8 +1026,13 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) + snd_free_pages((void*)runtime->control, + PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))); + kfree(runtime->hw_constraints.rules); +- kfree(runtime); ++ /* Avoid concurrent access to runtime via PCM timer interface */ ++ if (substream->timer) ++ spin_lock_irq(&substream->timer->lock); + substream->runtime = NULL; ++ if (substream->timer) ++ spin_unlock_irq(&substream->timer->lock); ++ kfree(runtime); + put_pid(substream->pid); + substream->pid = NULL; + substream->pstr->substream_opened--; +diff --git a/sound/core/rawmidi_compat.c b/sound/core/rawmidi_compat.c +index 09a89094dcf7..4e304a24924a 100644 +--- a/sound/core/rawmidi_compat.c ++++ b/sound/core/rawmidi_compat.c +@@ -36,8 +36,6 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile, + struct snd_rawmidi_params params; + unsigned int val; + +- if (rfile->output == NULL) +- return -EINVAL; + if (get_user(params.stream, &src->stream) || + get_user(params.buffer_size, &src->buffer_size) || + get_user(params.avail_min, &src->avail_min) || +@@ -46,8 +44,12 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile, + params.no_active_sensing = val; + switch (params.stream) { + case SNDRV_RAWMIDI_STREAM_OUTPUT: ++ if (!rfile->output) ++ return -EINVAL; + return snd_rawmidi_output_params(rfile->output, ¶ms); + case SNDRV_RAWMIDI_STREAM_INPUT: ++ if (!rfile->input) ++ return -EINVAL; + return snd_rawmidi_input_params(rfile->input, ¶ms); + } + return -EINVAL; +@@ -67,16 +69,18 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile, + int err; + struct snd_rawmidi_status status; + +- if (rfile->output == NULL) +- return -EINVAL; + if (get_user(status.stream, &src->stream)) + return -EFAULT; + + switch (status.stream) { + case SNDRV_RAWMIDI_STREAM_OUTPUT: ++ if (!rfile->output) ++ return -EINVAL; + err = snd_rawmidi_output_status(rfile->output, &status); + break; + case SNDRV_RAWMIDI_STREAM_INPUT: ++ if (!rfile->input) ++ return -EINVAL; + err = snd_rawmidi_input_status(rfile->input, &status); + break; + default: +@@ -113,16 +117,18 @@ static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile, + int err; + struct snd_rawmidi_status status; + +- if (rfile->output == NULL) +- return -EINVAL; + if (get_user(status.stream, &src->stream)) + return -EFAULT; + + switch (status.stream) { + case SNDRV_RAWMIDI_STREAM_OUTPUT: ++ if (!rfile->output) ++ return -EINVAL; + err = snd_rawmidi_output_status(rfile->output, &status); + break; + case SNDRV_RAWMIDI_STREAM_INPUT: ++ if (!rfile->input) ++ return -EINVAL; + err = snd_rawmidi_input_status(rfile->input, &status); + break; + default: +diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c +index fbd00821e326..3be91696ac35 100644 +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -1549,7 +1549,8 @@ static void azx_check_snoop_available(struct azx *chip) + */ + u8 val; + pci_read_config_byte(chip->pci, 0x42, &val); +- if (!(val & 0x80) && chip->pci->revision == 0x30) ++ if (!(val & 0x80) && (chip->pci->revision == 0x30 || ++ chip->pci->revision == 0x20)) + snoop = false; + } + +diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c +index 4452fea0b118..bd4998f577a0 100644 +--- a/sound/soc/codecs/ssm2602.c ++++ b/sound/soc/codecs/ssm2602.c +@@ -54,10 +54,17 @@ struct ssm2602_priv { + * using 2 wire for device control, so we cache them instead. + * There is no point in caching the reset register + */ +-static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = { +- 0x0097, 0x0097, 0x0079, 0x0079, +- 0x000a, 0x0008, 0x009f, 0x000a, +- 0x0000, 0x0000 ++static const struct reg_default ssm2602_reg[SSM2602_CACHEREGNUM] = { ++ { .reg = 0x00, .def = 0x0097 }, ++ { .reg = 0x01, .def = 0x0097 }, ++ { .reg = 0x02, .def = 0x0079 }, ++ { .reg = 0x03, .def = 0x0079 }, ++ { .reg = 0x04, .def = 0x000a }, ++ { .reg = 0x05, .def = 0x0008 }, ++ { .reg = 0x06, .def = 0x009f }, ++ { .reg = 0x07, .def = 0x000a }, ++ { .reg = 0x08, .def = 0x0000 }, ++ { .reg = 0x09, .def = 0x0000 } + }; + + +@@ -618,8 +625,8 @@ const struct regmap_config ssm2602_regmap_config = { + .volatile_reg = ssm2602_register_volatile, + + .cache_type = REGCACHE_RBTREE, +- .reg_defaults_raw = ssm2602_reg, +- .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg), ++ .reg_defaults = ssm2602_reg, ++ .num_reg_defaults = ARRAY_SIZE(ssm2602_reg), + }; + EXPORT_SYMBOL_GPL(ssm2602_regmap_config); + +diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c +index cebea9b7f769..6a9be1df7851 100644 +--- a/sound/usb/line6/midi.c ++++ b/sound/usb/line6/midi.c +@@ -125,7 +125,7 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data, + } + + usb_fill_int_urb(urb, line6->usbdev, +- usb_sndbulkpipe(line6->usbdev, ++ usb_sndintpipe(line6->usbdev, + line6->properties->ep_ctrl_w), + transfer_buffer, length, midi_sent, line6, + line6->interval); +diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c +index 6ea4fcfaab36..a767a6400c5c 100644 +--- a/tools/perf/tests/code-reading.c ++++ b/tools/perf/tests/code-reading.c +@@ -182,8 +182,6 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, + unsigned char buf2[BUFSZ]; + size_t ret_len; + u64 objdump_addr; +- const char *objdump_name; +- char decomp_name[KMOD_DECOMP_LEN]; + int ret; + + pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); +@@ -244,25 +242,9 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, + state->done[state->done_cnt++] = al.map->start; + } + +- objdump_name = al.map->dso->long_name; +- if (dso__needs_decompress(al.map->dso)) { +- if (dso__decompress_kmodule_path(al.map->dso, objdump_name, +- decomp_name, +- sizeof(decomp_name)) < 0) { +- pr_debug("decompression failed\n"); +- return -1; +- } +- +- objdump_name = decomp_name; +- } +- + /* Read the object code using objdump */ + objdump_addr = map__rip_2objdump(al.map, al.addr); +- ret = read_via_objdump(objdump_name, objdump_addr, buf2, len); +- +- if (dso__needs_decompress(al.map->dso)) +- unlink(objdump_name); +- ++ ret = read_via_objdump(al.map->dso->long_name, objdump_addr, buf2, len); + if (ret > 0) { + /* + * The kernel maps are inaccurate - assume objdump is right in +diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +index eeeae0629ad3..0b540b84f8b7 100644 +--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c ++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +@@ -1270,6 +1270,7 @@ static int intel_pt_overflow(struct intel_pt_decoder *decoder) + intel_pt_clear_tx_flags(decoder); + decoder->have_tma = false; + decoder->cbr = 0; ++ decoder->timestamp_insn_cnt = 0; + decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC; + decoder->overflow = true; + return -EOVERFLOW; +@@ -1492,6 +1493,7 @@ static int intel_pt_walk_fup_tip(struct intel_pt_decoder *decoder) + case INTEL_PT_PSBEND: + intel_pt_log("ERROR: Missing TIP after FUP\n"); + decoder->pkt_state = INTEL_PT_STATE_ERR3; ++ decoder->pkt_step = 0; + return -ENOENT; + + case INTEL_PT_OVF: +@@ -2152,14 +2154,6 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder) + return &decoder->state; + } + +-static bool intel_pt_at_psb(unsigned char *buf, size_t len) +-{ +- if (len < INTEL_PT_PSB_LEN) +- return false; +- return memmem(buf, INTEL_PT_PSB_LEN, INTEL_PT_PSB_STR, +- INTEL_PT_PSB_LEN); +-} +- + /** + * intel_pt_next_psb - move buffer pointer to the start of the next PSB packet. + * @buf: pointer to buffer pointer +@@ -2248,6 +2242,7 @@ static unsigned char *intel_pt_last_psb(unsigned char *buf, size_t len) + * @buf: buffer + * @len: size of buffer + * @tsc: TSC value returned ++ * @rem: returns remaining size when TSC is found + * + * Find a TSC packet in @buf and return the TSC value. This function assumes + * that @buf starts at a PSB and that PSB+ will contain TSC and so stops if a +@@ -2255,7 +2250,8 @@ static unsigned char *intel_pt_last_psb(unsigned char *buf, size_t len) + * + * Return: %true if TSC is found, false otherwise. + */ +-static bool intel_pt_next_tsc(unsigned char *buf, size_t len, uint64_t *tsc) ++static bool intel_pt_next_tsc(unsigned char *buf, size_t len, uint64_t *tsc, ++ size_t *rem) + { + struct intel_pt_pkt packet; + int ret; +@@ -2266,6 +2262,7 @@ static bool intel_pt_next_tsc(unsigned char *buf, size_t len, uint64_t *tsc) + return false; + if (packet.type == INTEL_PT_TSC) { + *tsc = packet.payload; ++ *rem = len; + return true; + } + if (packet.type == INTEL_PT_PSBEND) +@@ -2316,6 +2313,8 @@ static int intel_pt_tsc_cmp(uint64_t tsc1, uint64_t tsc2) + * @len_a: size of first buffer + * @buf_b: second buffer + * @len_b: size of second buffer ++ * @consecutive: returns true if there is data in buf_b that is consecutive ++ * to buf_a + * + * If the trace contains TSC we can look at the last TSC of @buf_a and the + * first TSC of @buf_b in order to determine if the buffers overlap, and then +@@ -2328,33 +2327,41 @@ static int intel_pt_tsc_cmp(uint64_t tsc1, uint64_t tsc2) + static unsigned char *intel_pt_find_overlap_tsc(unsigned char *buf_a, + size_t len_a, + unsigned char *buf_b, +- size_t len_b) ++ size_t len_b, bool *consecutive) + { + uint64_t tsc_a, tsc_b; + unsigned char *p; +- size_t len; ++ size_t len, rem_a, rem_b; + + p = intel_pt_last_psb(buf_a, len_a); + if (!p) + return buf_b; /* No PSB in buf_a => no overlap */ + + len = len_a - (p - buf_a); +- if (!intel_pt_next_tsc(p, len, &tsc_a)) { ++ if (!intel_pt_next_tsc(p, len, &tsc_a, &rem_a)) { + /* The last PSB+ in buf_a is incomplete, so go back one more */ + len_a -= len; + p = intel_pt_last_psb(buf_a, len_a); + if (!p) + return buf_b; /* No full PSB+ => assume no overlap */ + len = len_a - (p - buf_a); +- if (!intel_pt_next_tsc(p, len, &tsc_a)) ++ if (!intel_pt_next_tsc(p, len, &tsc_a, &rem_a)) + return buf_b; /* No TSC in buf_a => assume no overlap */ + } + + while (1) { + /* Ignore PSB+ with no TSC */ +- if (intel_pt_next_tsc(buf_b, len_b, &tsc_b) && +- intel_pt_tsc_cmp(tsc_a, tsc_b) < 0) +- return buf_b; /* tsc_a < tsc_b => no overlap */ ++ if (intel_pt_next_tsc(buf_b, len_b, &tsc_b, &rem_b)) { ++ int cmp = intel_pt_tsc_cmp(tsc_a, tsc_b); ++ ++ /* Same TSC, so buffers are consecutive */ ++ if (!cmp && rem_b >= rem_a) { ++ *consecutive = true; ++ return buf_b + len_b - (rem_b - rem_a); ++ } ++ if (cmp < 0) ++ return buf_b; /* tsc_a < tsc_b => no overlap */ ++ } + + if (!intel_pt_step_psb(&buf_b, &len_b)) + return buf_b + len_b; /* No PSB in buf_b => no data */ +@@ -2368,6 +2375,8 @@ static unsigned char *intel_pt_find_overlap_tsc(unsigned char *buf_a, + * @buf_b: second buffer + * @len_b: size of second buffer + * @have_tsc: can use TSC packets to detect overlap ++ * @consecutive: returns true if there is data in buf_b that is consecutive ++ * to buf_a + * + * When trace samples or snapshots are recorded there is the possibility that + * the data overlaps. Note that, for the purposes of decoding, data is only +@@ -2378,7 +2387,7 @@ static unsigned char *intel_pt_find_overlap_tsc(unsigned char *buf_a, + */ + unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a, + unsigned char *buf_b, size_t len_b, +- bool have_tsc) ++ bool have_tsc, bool *consecutive) + { + unsigned char *found; + +@@ -2390,7 +2399,8 @@ unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a, + return buf_b; /* No overlap */ + + if (have_tsc) { +- found = intel_pt_find_overlap_tsc(buf_a, len_a, buf_b, len_b); ++ found = intel_pt_find_overlap_tsc(buf_a, len_a, buf_b, len_b, ++ consecutive); + if (found) + return found; + } +@@ -2405,28 +2415,16 @@ unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a, + } + + /* Now len_b >= len_a */ +- if (len_b > len_a) { +- /* The leftover buffer 'b' must start at a PSB */ +- while (!intel_pt_at_psb(buf_b + len_a, len_b - len_a)) { +- if (!intel_pt_step_psb(&buf_a, &len_a)) +- return buf_b; /* No overlap */ +- } +- } +- + while (1) { + /* Potential overlap so check the bytes */ + found = memmem(buf_a, len_a, buf_b, len_a); +- if (found) ++ if (found) { ++ *consecutive = true; + return buf_b + len_a; ++ } + + /* Try again at next PSB in buffer 'a' */ + if (!intel_pt_step_psb(&buf_a, &len_a)) + return buf_b; /* No overlap */ +- +- /* The leftover buffer 'b' must start at a PSB */ +- while (!intel_pt_at_psb(buf_b + len_a, len_b - len_a)) { +- if (!intel_pt_step_psb(&buf_a, &len_a)) +- return buf_b; /* No overlap */ +- } + } + } +diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h +index 02c38fec1c37..89a3eda6a318 100644 +--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h ++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h +@@ -102,7 +102,7 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder); + + unsigned char *intel_pt_find_overlap(unsigned char *buf_a, size_t len_a, + unsigned char *buf_b, size_t len_b, +- bool have_tsc); ++ bool have_tsc, bool *consecutive); + + int intel_pt__strerror(int code, char *buf, size_t buflen); + +diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c +index 89927b5beebf..3693cb26ec66 100644 +--- a/tools/perf/util/intel-pt.c ++++ b/tools/perf/util/intel-pt.c +@@ -125,6 +125,7 @@ struct intel_pt_queue { + bool stop; + bool step_through_buffers; + bool use_buffer_pid_tid; ++ bool sync_switch; + pid_t pid, tid; + int cpu; + int switch_state; +@@ -188,14 +189,17 @@ static void intel_pt_dump_event(struct intel_pt *pt, unsigned char *buf, + static int intel_pt_do_fix_overlap(struct intel_pt *pt, struct auxtrace_buffer *a, + struct auxtrace_buffer *b) + { ++ bool consecutive = false; + void *start; + + start = intel_pt_find_overlap(a->data, a->size, b->data, b->size, +- pt->have_tsc); ++ pt->have_tsc, &consecutive); + if (!start) + return -EINVAL; + b->use_size = b->data + b->size - start; + b->use_data = start; ++ if (b->use_size && consecutive) ++ b->consecutive = true; + return 0; + } + +@@ -849,10 +853,12 @@ static int intel_pt_setup_queue(struct intel_pt *pt, + if (pt->timeless_decoding || !pt->have_sched_switch) + ptq->use_buffer_pid_tid = true; + } ++ ++ ptq->sync_switch = pt->sync_switch; + } + + if (!ptq->on_heap && +- (!pt->sync_switch || ++ (!ptq->sync_switch || + ptq->switch_state != INTEL_PT_SS_EXPECTING_SWITCH_EVENT)) { + const struct intel_pt_state *state; + int ret; +@@ -1235,7 +1241,7 @@ static int intel_pt_sample(struct intel_pt_queue *ptq) + if (pt->synth_opts.last_branch) + intel_pt_update_last_branch_rb(ptq); + +- if (!pt->sync_switch) ++ if (!ptq->sync_switch) + return 0; + + if (intel_pt_is_switch_ip(ptq, state->to_ip)) { +@@ -1316,6 +1322,21 @@ static u64 intel_pt_switch_ip(struct intel_pt *pt, u64 *ptss_ip) + return switch_ip; + } + ++static void intel_pt_enable_sync_switch(struct intel_pt *pt) ++{ ++ unsigned int i; ++ ++ pt->sync_switch = true; ++ ++ for (i = 0; i < pt->queues.nr_queues; i++) { ++ struct auxtrace_queue *queue = &pt->queues.queue_array[i]; ++ struct intel_pt_queue *ptq = queue->priv; ++ ++ if (ptq) ++ ptq->sync_switch = true; ++ } ++} ++ + static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp) + { + const struct intel_pt_state *state = ptq->state; +@@ -1332,7 +1353,7 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp) + if (pt->switch_ip) { + intel_pt_log("switch_ip: %"PRIx64" ptss_ip: %"PRIx64"\n", + pt->switch_ip, pt->ptss_ip); +- pt->sync_switch = true; ++ intel_pt_enable_sync_switch(pt); + } + } + } +@@ -1348,9 +1369,9 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp) + if (state->err) { + if (state->err == INTEL_PT_ERR_NODATA) + return 1; +- if (pt->sync_switch && ++ if (ptq->sync_switch && + state->from_ip >= pt->kernel_start) { +- pt->sync_switch = false; ++ ptq->sync_switch = false; + intel_pt_next_tid(pt, ptq); + } + if (pt->synth_opts.errors) { +@@ -1376,7 +1397,7 @@ static int intel_pt_run_decoder(struct intel_pt_queue *ptq, u64 *timestamp) + state->timestamp, state->est_timestamp); + ptq->timestamp = state->est_timestamp; + /* Use estimated TSC in unknown switch state */ +- } else if (pt->sync_switch && ++ } else if (ptq->sync_switch && + ptq->switch_state == INTEL_PT_SS_UNKNOWN && + intel_pt_is_switch_ip(ptq, state->to_ip) && + ptq->next_tid == -1) { +@@ -1523,7 +1544,7 @@ static int intel_pt_sync_switch(struct intel_pt *pt, int cpu, pid_t tid, + return 1; + + ptq = intel_pt_cpu_to_ptq(pt, cpu); +- if (!ptq) ++ if (!ptq || !ptq->sync_switch) + return 1; + + switch (ptq->switch_state) { diff --git a/patch/kernel/rk3328-default/04-patch-4.4.129-130.patch b/patch/kernel/rk3328-default/04-patch-4.4.129-130.patch new file mode 100644 index 000000000..0f5058403 --- /dev/null +++ b/patch/kernel/rk3328-default/04-patch-4.4.129-130.patch @@ -0,0 +1,2698 @@ +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index f53ef1ac3122..4df6bd7d01ed 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -2402,6 +2402,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + + noalign [KNL,ARM] + ++ noaltinstr [S390] Disables alternative instructions patching ++ (CPU alternatives feature). ++ + noapic [SMP,APIC] Tells the kernel to not make use of any + IOAPICs that may be present in the system. + +diff --git a/Makefile b/Makefile +index 096d7e867b6c..151477d4d5e5 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 129 ++SUBLEVEL = 130 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig +index 2ee95ece0498..9bdaeb38a768 100644 +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -111,6 +111,7 @@ config S390 + select GENERIC_CLOCKEVENTS + select GENERIC_CPU_AUTOPROBE + select GENERIC_CPU_DEVICES if !SMP ++ select GENERIC_CPU_VULNERABILITIES + select GENERIC_FIND_FIRST_BIT + select GENERIC_SMP_IDLE_THREAD + select GENERIC_TIME_VSYSCALL +@@ -705,6 +706,51 @@ config SECCOMP + + If unsure, say Y. + ++config KERNEL_NOBP ++ def_bool n ++ prompt "Enable modified branch prediction for the kernel by default" ++ help ++ If this option is selected the kernel will switch to a modified ++ branch prediction mode if the firmware interface is available. ++ The modified branch prediction mode improves the behaviour in ++ regard to speculative execution. ++ ++ With the option enabled the kernel parameter "nobp=0" or "nospec" ++ can be used to run the kernel in the normal branch prediction mode. ++ ++ With the option disabled the modified branch prediction mode is ++ enabled with the "nobp=1" kernel parameter. ++ ++ If unsure, say N. ++ ++config EXPOLINE ++ def_bool n ++ prompt "Avoid speculative indirect branches in the kernel" ++ help ++ Compile the kernel with the expoline compiler options to guard ++ against kernel-to-user data leaks by avoiding speculative indirect ++ branches. ++ Requires a compiler with -mindirect-branch=thunk support for full ++ protection. The kernel may run slower. ++ ++ If unsure, say N. ++ ++choice ++ prompt "Expoline default" ++ depends on EXPOLINE ++ default EXPOLINE_FULL ++ ++config EXPOLINE_OFF ++ bool "spectre_v2=off" ++ ++config EXPOLINE_AUTO ++ bool "spectre_v2=auto" ++ ++config EXPOLINE_FULL ++ bool "spectre_v2=on" ++ ++endchoice ++ + endmenu + + menu "Power Management" +@@ -754,6 +800,7 @@ config PFAULT + config SHARED_KERNEL + bool "VM shared kernel support" + depends on !JUMP_LABEL ++ depends on !ALTERNATIVES + help + Select this option, if you want to share the text segment of the + Linux kernel between different VM guests. This reduces memory +diff --git a/arch/s390/Makefile b/arch/s390/Makefile +index e8d4423e4f85..d924f9b6dc73 100644 +--- a/arch/s390/Makefile ++++ b/arch/s390/Makefile +@@ -77,6 +77,16 @@ ifeq ($(call cc-option-yn,-mwarn-dynamicstack),y) + cflags-$(CONFIG_WARN_DYNAMIC_STACK) += -mwarn-dynamicstack + endif + ++ifdef CONFIG_EXPOLINE ++ ifeq ($(call cc-option-yn,$(CC_FLAGS_MARCH) -mindirect-branch=thunk),y) ++ CC_FLAGS_EXPOLINE := -mindirect-branch=thunk ++ CC_FLAGS_EXPOLINE += -mfunction-return=thunk ++ CC_FLAGS_EXPOLINE += -mindirect-branch-table ++ export CC_FLAGS_EXPOLINE ++ cflags-y += $(CC_FLAGS_EXPOLINE) -DCC_USING_EXPOLINE ++ endif ++endif ++ + ifdef CONFIG_FUNCTION_TRACER + # make use of hotpatch feature if the compiler supports it + cc_hotpatch := -mhotpatch=0,3 +diff --git a/arch/s390/include/asm/alternative.h b/arch/s390/include/asm/alternative.h +new file mode 100644 +index 000000000000..a72002056b54 +--- /dev/null ++++ b/arch/s390/include/asm/alternative.h +@@ -0,0 +1,149 @@ ++#ifndef _ASM_S390_ALTERNATIVE_H ++#define _ASM_S390_ALTERNATIVE_H ++ ++#ifndef __ASSEMBLY__ ++ ++#include ++#include ++#include ++ ++struct alt_instr { ++ s32 instr_offset; /* original instruction */ ++ s32 repl_offset; /* offset to replacement instruction */ ++ u16 facility; /* facility bit set for replacement */ ++ u8 instrlen; /* length of original instruction */ ++ u8 replacementlen; /* length of new instruction */ ++} __packed; ++ ++void apply_alternative_instructions(void); ++void apply_alternatives(struct alt_instr *start, struct alt_instr *end); ++ ++/* ++ * |661: |662: |6620 |663: ++ * +-----------+---------------------+ ++ * | oldinstr | oldinstr_padding | ++ * | +----------+----------+ ++ * | | | | ++ * | | >6 bytes |6/4/2 nops| ++ * | |6 bytes jg-----------> ++ * +-----------+---------------------+ ++ * ^^ static padding ^^ ++ * ++ * .altinstr_replacement section ++ * +---------------------+-----------+ ++ * |6641: |6651: ++ * | alternative instr 1 | ++ * +-----------+---------+- - - - - -+ ++ * |6642: |6652: | ++ * | alternative instr 2 | padding ++ * +---------------------+- - - - - -+ ++ * ^ runtime ^ ++ * ++ * .altinstructions section ++ * +---------------------------------+ ++ * | alt_instr entries for each | ++ * | alternative instr | ++ * +---------------------------------+ ++ */ ++ ++#define b_altinstr(num) "664"#num ++#define e_altinstr(num) "665"#num ++ ++#define e_oldinstr_pad_end "663" ++#define oldinstr_len "662b-661b" ++#define oldinstr_total_len e_oldinstr_pad_end"b-661b" ++#define altinstr_len(num) e_altinstr(num)"b-"b_altinstr(num)"b" ++#define oldinstr_pad_len(num) \ ++ "-(((" altinstr_len(num) ")-(" oldinstr_len ")) > 0) * " \ ++ "((" altinstr_len(num) ")-(" oldinstr_len "))" ++ ++#define INSTR_LEN_SANITY_CHECK(len) \ ++ ".if " len " > 254\n" \ ++ "\t.error \"cpu alternatives does not support instructions " \ ++ "blocks > 254 bytes\"\n" \ ++ ".endif\n" \ ++ ".if (" len ") %% 2\n" \ ++ "\t.error \"cpu alternatives instructions length is odd\"\n" \ ++ ".endif\n" ++ ++#define OLDINSTR_PADDING(oldinstr, num) \ ++ ".if " oldinstr_pad_len(num) " > 6\n" \ ++ "\tjg " e_oldinstr_pad_end "f\n" \ ++ "6620:\n" \ ++ "\t.fill (" oldinstr_pad_len(num) " - (6620b-662b)) / 2, 2, 0x0700\n" \ ++ ".else\n" \ ++ "\t.fill " oldinstr_pad_len(num) " / 6, 6, 0xc0040000\n" \ ++ "\t.fill " oldinstr_pad_len(num) " %% 6 / 4, 4, 0x47000000\n" \ ++ "\t.fill " oldinstr_pad_len(num) " %% 6 %% 4 / 2, 2, 0x0700\n" \ ++ ".endif\n" ++ ++#define OLDINSTR(oldinstr, num) \ ++ "661:\n\t" oldinstr "\n662:\n" \ ++ OLDINSTR_PADDING(oldinstr, num) \ ++ e_oldinstr_pad_end ":\n" \ ++ INSTR_LEN_SANITY_CHECK(oldinstr_len) ++ ++#define OLDINSTR_2(oldinstr, num1, num2) \ ++ "661:\n\t" oldinstr "\n662:\n" \ ++ ".if " altinstr_len(num1) " < " altinstr_len(num2) "\n" \ ++ OLDINSTR_PADDING(oldinstr, num2) \ ++ ".else\n" \ ++ OLDINSTR_PADDING(oldinstr, num1) \ ++ ".endif\n" \ ++ e_oldinstr_pad_end ":\n" \ ++ INSTR_LEN_SANITY_CHECK(oldinstr_len) ++ ++#define ALTINSTR_ENTRY(facility, num) \ ++ "\t.long 661b - .\n" /* old instruction */ \ ++ "\t.long " b_altinstr(num)"b - .\n" /* alt instruction */ \ ++ "\t.word " __stringify(facility) "\n" /* facility bit */ \ ++ "\t.byte " oldinstr_total_len "\n" /* source len */ \ ++ "\t.byte " altinstr_len(num) "\n" /* alt instruction len */ ++ ++#define ALTINSTR_REPLACEMENT(altinstr, num) /* replacement */ \ ++ b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n" \ ++ INSTR_LEN_SANITY_CHECK(altinstr_len(num)) ++ ++/* alternative assembly primitive: */ ++#define ALTERNATIVE(oldinstr, altinstr, facility) \ ++ ".pushsection .altinstr_replacement, \"ax\"\n" \ ++ ALTINSTR_REPLACEMENT(altinstr, 1) \ ++ ".popsection\n" \ ++ OLDINSTR(oldinstr, 1) \ ++ ".pushsection .altinstructions,\"a\"\n" \ ++ ALTINSTR_ENTRY(facility, 1) \ ++ ".popsection\n" ++ ++#define ALTERNATIVE_2(oldinstr, altinstr1, facility1, altinstr2, facility2)\ ++ ".pushsection .altinstr_replacement, \"ax\"\n" \ ++ ALTINSTR_REPLACEMENT(altinstr1, 1) \ ++ ALTINSTR_REPLACEMENT(altinstr2, 2) \ ++ ".popsection\n" \ ++ OLDINSTR_2(oldinstr, 1, 2) \ ++ ".pushsection .altinstructions,\"a\"\n" \ ++ ALTINSTR_ENTRY(facility1, 1) \ ++ ALTINSTR_ENTRY(facility2, 2) \ ++ ".popsection\n" ++ ++/* ++ * Alternative instructions for different CPU types or capabilities. ++ * ++ * This allows to use optimized instructions even on generic binary ++ * kernels. ++ * ++ * oldinstr is padded with jump and nops at compile time if altinstr is ++ * longer. altinstr is padded with jump and nops at run-time during patching. ++ * ++ * For non barrier like inlines please define new variants ++ * without volatile and memory clobber. ++ */ ++#define alternative(oldinstr, altinstr, facility) \ ++ asm volatile(ALTERNATIVE(oldinstr, altinstr, facility) : : : "memory") ++ ++#define alternative_2(oldinstr, altinstr1, facility1, altinstr2, facility2) \ ++ asm volatile(ALTERNATIVE_2(oldinstr, altinstr1, facility1, \ ++ altinstr2, facility2) ::: "memory") ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _ASM_S390_ALTERNATIVE_H */ +diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h +index d68e11e0df5e..e903b28e7358 100644 +--- a/arch/s390/include/asm/barrier.h ++++ b/arch/s390/include/asm/barrier.h +@@ -53,4 +53,28 @@ do { \ + ___p1; \ + }) + ++/** ++ * array_index_mask_nospec - generate a mask for array_idx() that is ++ * ~0UL when the bounds check succeeds and 0 otherwise ++ * @index: array element index ++ * @size: number of elements in array ++ */ ++#define array_index_mask_nospec array_index_mask_nospec ++static inline unsigned long array_index_mask_nospec(unsigned long index, ++ unsigned long size) ++{ ++ unsigned long mask; ++ ++ if (__builtin_constant_p(size) && size > 0) { ++ asm(" clgr %2,%1\n" ++ " slbgr %0,%0\n" ++ :"=d" (mask) : "d" (size-1), "d" (index) :"cc"); ++ return mask; ++ } ++ asm(" clgr %1,%2\n" ++ " slbgr %0,%0\n" ++ :"=d" (mask) : "d" (size), "d" (index) :"cc"); ++ return ~mask; ++} ++ + #endif /* __ASM_BARRIER_H */ +diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h +index 0aa6a7ed95a3..155fcc7bcba6 100644 +--- a/arch/s390/include/asm/facility.h ++++ b/arch/s390/include/asm/facility.h +@@ -13,6 +13,24 @@ + + #define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */ + ++static inline void __set_facility(unsigned long nr, void *facilities) ++{ ++ unsigned char *ptr = (unsigned char *) facilities; ++ ++ if (nr >= MAX_FACILITY_BIT) ++ return; ++ ptr[nr >> 3] |= 0x80 >> (nr & 7); ++} ++ ++static inline void __clear_facility(unsigned long nr, void *facilities) ++{ ++ unsigned char *ptr = (unsigned char *) facilities; ++ ++ if (nr >= MAX_FACILITY_BIT) ++ return; ++ ptr[nr >> 3] &= ~(0x80 >> (nr & 7)); ++} ++ + static inline int __test_facility(unsigned long nr, void *facilities) + { + unsigned char *ptr; +diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h +index e9a983f40a24..7d9c5917da2b 100644 +--- a/arch/s390/include/asm/kvm_host.h ++++ b/arch/s390/include/asm/kvm_host.h +@@ -136,7 +136,8 @@ struct kvm_s390_sie_block { + __u16 ipa; /* 0x0056 */ + __u32 ipb; /* 0x0058 */ + __u32 scaoh; /* 0x005c */ +- __u8 reserved60; /* 0x0060 */ ++#define FPF_BPBC 0x20 ++ __u8 fpf; /* 0x0060 */ + __u8 ecb; /* 0x0061 */ + __u8 ecb2; /* 0x0062 */ + #define ECB3_AES 0x04 +diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h +index afe1cfebf1a4..8520c23e419b 100644 +--- a/arch/s390/include/asm/lowcore.h ++++ b/arch/s390/include/asm/lowcore.h +@@ -155,7 +155,9 @@ struct _lowcore { + /* Per cpu primary space access list */ + __u32 paste[16]; /* 0x0400 */ + +- __u8 pad_0x04c0[0x0e00-0x0440]; /* 0x0440 */ ++ /* br %r1 trampoline */ ++ __u16 br_r1_trampoline; /* 0x0440 */ ++ __u8 pad_0x0442[0x0e00-0x0442]; /* 0x0442 */ + + /* + * 0xe00 contains the address of the IPL Parameter Information +@@ -170,7 +172,8 @@ struct _lowcore { + __u8 pad_0x0e20[0x0f00-0x0e20]; /* 0x0e20 */ + + /* Extended facility list */ +- __u64 stfle_fac_list[32]; /* 0x0f00 */ ++ __u64 stfle_fac_list[16]; /* 0x0f00 */ ++ __u64 alt_stfle_fac_list[16]; /* 0x0f80 */ + __u8 pad_0x1000[0x11b0-0x1000]; /* 0x1000 */ + + /* Pointer to vector register save area */ +diff --git a/arch/s390/include/asm/nospec-branch.h b/arch/s390/include/asm/nospec-branch.h +new file mode 100644 +index 000000000000..b4bd8c41e9d3 +--- /dev/null ++++ b/arch/s390/include/asm/nospec-branch.h +@@ -0,0 +1,17 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef _ASM_S390_EXPOLINE_H ++#define _ASM_S390_EXPOLINE_H ++ ++#ifndef __ASSEMBLY__ ++ ++#include ++ ++extern int nospec_disable; ++ ++void nospec_init_branches(void); ++void nospec_auto_detect(void); ++void nospec_revert(s32 *start, s32 *end); ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* _ASM_S390_EXPOLINE_H */ +diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h +index c61ed7890cef..f915a0f1b0fc 100644 +--- a/arch/s390/include/asm/processor.h ++++ b/arch/s390/include/asm/processor.h +@@ -69,6 +69,7 @@ extern void s390_adjust_jiffies(void); + extern const struct seq_operations cpuinfo_op; + extern int sysctl_ieee_emulation_warnings; + extern void execve_tail(void); ++extern void __bpon(void); + + /* + * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. +@@ -315,6 +316,9 @@ extern void memcpy_absolute(void *, void *, size_t); + memcpy_absolute(&(dest), &__tmp, sizeof(__tmp)); \ + } + ++extern int s390_isolate_bp(void); ++extern int s390_isolate_bp_guest(void); ++ + #endif /* __ASSEMBLY__ */ + + #endif /* __ASM_S390_PROCESSOR_H */ +diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h +index 692b9247c019..b2504163c8fa 100644 +--- a/arch/s390/include/asm/thread_info.h ++++ b/arch/s390/include/asm/thread_info.h +@@ -78,6 +78,8 @@ void arch_release_task_struct(struct task_struct *tsk); + #define TIF_SECCOMP 5 /* secure computing */ + #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ + #define TIF_UPROBE 7 /* breakpointed or single-stepping */ ++#define TIF_ISOLATE_BP 8 /* Run process with isolated BP */ ++#define TIF_ISOLATE_BP_GUEST 9 /* Run KVM guests with isolated BP */ + #define TIF_31BIT 16 /* 32bit process */ + #define TIF_MEMDIE 17 /* is terminating due to OOM killer */ + #define TIF_RESTORE_SIGMASK 18 /* restore signal mask in do_signal() */ +@@ -93,6 +95,8 @@ void arch_release_task_struct(struct task_struct *tsk); + #define _TIF_SECCOMP _BITUL(TIF_SECCOMP) + #define _TIF_SYSCALL_TRACEPOINT _BITUL(TIF_SYSCALL_TRACEPOINT) + #define _TIF_UPROBE _BITUL(TIF_UPROBE) ++#define _TIF_ISOLATE_BP _BITUL(TIF_ISOLATE_BP) ++#define _TIF_ISOLATE_BP_GUEST _BITUL(TIF_ISOLATE_BP_GUEST) + #define _TIF_31BIT _BITUL(TIF_31BIT) + #define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP) + +diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h +index ef1a5fcc6c66..beb508a9e72c 100644 +--- a/arch/s390/include/uapi/asm/kvm.h ++++ b/arch/s390/include/uapi/asm/kvm.h +@@ -151,6 +151,7 @@ struct kvm_guest_debug_arch { + #define KVM_SYNC_ARCH0 (1UL << 4) + #define KVM_SYNC_PFAULT (1UL << 5) + #define KVM_SYNC_VRS (1UL << 6) ++#define KVM_SYNC_BPBC (1UL << 10) + /* definition of registers in kvm_run */ + struct kvm_sync_regs { + __u64 prefix; /* prefix register */ +@@ -168,6 +169,8 @@ struct kvm_sync_regs { + __u64 vrs[32][2]; /* vector registers */ + __u8 reserved[512]; /* for future vector expansion */ + __u32 fpc; /* only valid with vector registers */ ++ __u8 bpbc : 1; /* bp mode */ ++ __u8 reserved2 : 7; + }; + + #define KVM_REG_S390_TODPR (KVM_REG_S390 | KVM_REG_SIZE_U32 | 0x1) +diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile +index dc167a23b920..8ccfbf22ecbb 100644 +--- a/arch/s390/kernel/Makefile ++++ b/arch/s390/kernel/Makefile +@@ -44,10 +44,13 @@ obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o + obj-y += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o + obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o + obj-y += runtime_instr.o cache.o dumpstack.o +-obj-y += entry.o reipl.o relocate_kernel.o ++obj-y += entry.o reipl.o relocate_kernel.o alternative.o ++obj-y += nospec-branch.o + + extra-y += head.o head64.o vmlinux.lds + ++CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE) ++ + obj-$(CONFIG_MODULES) += s390_ksyms.o module.o + obj-$(CONFIG_SMP) += smp.o + obj-$(CONFIG_SCHED_BOOK) += topology.o +diff --git a/arch/s390/kernel/alternative.c b/arch/s390/kernel/alternative.c +new file mode 100644 +index 000000000000..b57b293998dc +--- /dev/null ++++ b/arch/s390/kernel/alternative.c +@@ -0,0 +1,112 @@ ++#include ++#include ++#include ++#include ++ ++#define MAX_PATCH_LEN (255 - 1) ++ ++static int __initdata_or_module alt_instr_disabled; ++ ++static int __init disable_alternative_instructions(char *str) ++{ ++ alt_instr_disabled = 1; ++ return 0; ++} ++ ++early_param("noaltinstr", disable_alternative_instructions); ++ ++struct brcl_insn { ++ u16 opc; ++ s32 disp; ++} __packed; ++ ++static u16 __initdata_or_module nop16 = 0x0700; ++static u32 __initdata_or_module nop32 = 0x47000000; ++static struct brcl_insn __initdata_or_module nop48 = { ++ 0xc004, 0 ++}; ++ ++static const void *nops[] __initdata_or_module = { ++ &nop16, ++ &nop32, ++ &nop48 ++}; ++ ++static void __init_or_module add_jump_padding(void *insns, unsigned int len) ++{ ++ struct brcl_insn brcl = { ++ 0xc0f4, ++ len / 2 ++ }; ++ ++ memcpy(insns, &brcl, sizeof(brcl)); ++ insns += sizeof(brcl); ++ len -= sizeof(brcl); ++ ++ while (len > 0) { ++ memcpy(insns, &nop16, 2); ++ insns += 2; ++ len -= 2; ++ } ++} ++ ++static void __init_or_module add_padding(void *insns, unsigned int len) ++{ ++ if (len > 6) ++ add_jump_padding(insns, len); ++ else if (len >= 2) ++ memcpy(insns, nops[len / 2 - 1], len); ++} ++ ++static void __init_or_module __apply_alternatives(struct alt_instr *start, ++ struct alt_instr *end) ++{ ++ struct alt_instr *a; ++ u8 *instr, *replacement; ++ u8 insnbuf[MAX_PATCH_LEN]; ++ ++ /* ++ * The scan order should be from start to end. A later scanned ++ * alternative code can overwrite previously scanned alternative code. ++ */ ++ for (a = start; a < end; a++) { ++ int insnbuf_sz = 0; ++ ++ instr = (u8 *)&a->instr_offset + a->instr_offset; ++ replacement = (u8 *)&a->repl_offset + a->repl_offset; ++ ++ if (!__test_facility(a->facility, ++ S390_lowcore.alt_stfle_fac_list)) ++ continue; ++ ++ if (unlikely(a->instrlen % 2 || a->replacementlen % 2)) { ++ WARN_ONCE(1, "cpu alternatives instructions length is " ++ "odd, skipping patching\n"); ++ continue; ++ } ++ ++ memcpy(insnbuf, replacement, a->replacementlen); ++ insnbuf_sz = a->replacementlen; ++ ++ if (a->instrlen > a->replacementlen) { ++ add_padding(insnbuf + a->replacementlen, ++ a->instrlen - a->replacementlen); ++ insnbuf_sz += a->instrlen - a->replacementlen; ++ } ++ ++ s390_kernel_write(instr, insnbuf, insnbuf_sz); ++ } ++} ++ ++void __init_or_module apply_alternatives(struct alt_instr *start, ++ struct alt_instr *end) ++{ ++ if (!alt_instr_disabled) ++ __apply_alternatives(start, end); ++} ++ ++extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; ++void __init apply_alternative_instructions(void) ++{ ++ apply_alternatives(__alt_instructions, __alt_instructions_end); ++} +diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c +index ee7b8e7ca4f8..8eccead675d4 100644 +--- a/arch/s390/kernel/early.c ++++ b/arch/s390/kernel/early.c +@@ -279,6 +279,11 @@ static noinline __init void setup_facility_list(void) + { + stfle(S390_lowcore.stfle_fac_list, + ARRAY_SIZE(S390_lowcore.stfle_fac_list)); ++ memcpy(S390_lowcore.alt_stfle_fac_list, ++ S390_lowcore.stfle_fac_list, ++ sizeof(S390_lowcore.alt_stfle_fac_list)); ++ if (!IS_ENABLED(CONFIG_KERNEL_NOBP)) ++ __clear_facility(82, S390_lowcore.alt_stfle_fac_list); + } + + static __init void detect_diag9c(void) +diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S +index 4612ed7ec2e5..c63730326215 100644 +--- a/arch/s390/kernel/entry.S ++++ b/arch/s390/kernel/entry.S +@@ -104,6 +104,7 @@ _PIF_WORK = (_PIF_PER_TRAP) + j 3f + 1: LAST_BREAK %r14 + UPDATE_VTIME %r14,%r15,\timer ++ BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP + 2: lg %r15,__LC_ASYNC_STACK # load async stack + 3: la %r11,STACK_FRAME_OVERHEAD(%r15) + .endm +@@ -162,8 +163,137 @@ _PIF_WORK = (_PIF_PER_TRAP) + tm off+\addr, \mask + .endm + ++ .macro BPOFF ++ .pushsection .altinstr_replacement, "ax" ++660: .long 0xb2e8c000 ++ .popsection ++661: .long 0x47000000 ++ .pushsection .altinstructions, "a" ++ .long 661b - . ++ .long 660b - . ++ .word 82 ++ .byte 4 ++ .byte 4 ++ .popsection ++ .endm ++ ++ .macro BPON ++ .pushsection .altinstr_replacement, "ax" ++662: .long 0xb2e8d000 ++ .popsection ++663: .long 0x47000000 ++ .pushsection .altinstructions, "a" ++ .long 663b - . ++ .long 662b - . ++ .word 82 ++ .byte 4 ++ .byte 4 ++ .popsection ++ .endm ++ ++ .macro BPENTER tif_ptr,tif_mask ++ .pushsection .altinstr_replacement, "ax" ++662: .word 0xc004, 0x0000, 0x0000 # 6 byte nop ++ .word 0xc004, 0x0000, 0x0000 # 6 byte nop ++ .popsection ++664: TSTMSK \tif_ptr,\tif_mask ++ jz . + 8 ++ .long 0xb2e8d000 ++ .pushsection .altinstructions, "a" ++ .long 664b - . ++ .long 662b - . ++ .word 82 ++ .byte 12 ++ .byte 12 ++ .popsection ++ .endm ++ ++ .macro BPEXIT tif_ptr,tif_mask ++ TSTMSK \tif_ptr,\tif_mask ++ .pushsection .altinstr_replacement, "ax" ++662: jnz . + 8 ++ .long 0xb2e8d000 ++ .popsection ++664: jz . + 8 ++ .long 0xb2e8c000 ++ .pushsection .altinstructions, "a" ++ .long 664b - . ++ .long 662b - . ++ .word 82 ++ .byte 8 ++ .byte 8 ++ .popsection ++ .endm ++ ++#ifdef CONFIG_EXPOLINE ++ ++ .macro GEN_BR_THUNK name,reg,tmp ++ .section .text.\name,"axG",@progbits,\name,comdat ++ .globl \name ++ .hidden \name ++ .type \name,@function ++\name: ++ .cfi_startproc ++#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES ++ exrl 0,0f ++#else ++ larl \tmp,0f ++ ex 0,0(\tmp) ++#endif ++ j . ++0: br \reg ++ .cfi_endproc ++ .endm ++ ++ GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1 ++ GEN_BR_THUNK __s390x_indirect_jump_r1use_r14,%r14,%r1 ++ GEN_BR_THUNK __s390x_indirect_jump_r11use_r14,%r14,%r11 ++ ++ .macro BASR_R14_R9 ++0: brasl %r14,__s390x_indirect_jump_r1use_r9 ++ .pushsection .s390_indirect_branches,"a",@progbits ++ .long 0b-. ++ .popsection ++ .endm ++ ++ .macro BR_R1USE_R14 ++0: jg __s390x_indirect_jump_r1use_r14 ++ .pushsection .s390_indirect_branches,"a",@progbits ++ .long 0b-. ++ .popsection ++ .endm ++ ++ .macro BR_R11USE_R14 ++0: jg __s390x_indirect_jump_r11use_r14 ++ .pushsection .s390_indirect_branches,"a",@progbits ++ .long 0b-. ++ .popsection ++ .endm ++ ++#else /* CONFIG_EXPOLINE */ ++ ++ .macro BASR_R14_R9 ++ basr %r14,%r9 ++ .endm ++ ++ .macro BR_R1USE_R14 ++ br %r14 ++ .endm ++ ++ .macro BR_R11USE_R14 ++ br %r14 ++ .endm ++ ++#endif /* CONFIG_EXPOLINE */ ++ ++ + .section .kprobes.text, "ax" + ++ENTRY(__bpon) ++ .globl __bpon ++ BPON ++ BR_R1USE_R14 ++ + /* + * Scheduler resume function, called by switch_to + * gpr2 = (task_struct *) prev +@@ -190,9 +320,9 @@ ENTRY(__switch_to) + mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next + lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task + TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP +- bzr %r14 ++ jz 0f + .insn s,0xb2800000,__LC_LPP # set program parameter +- br %r14 ++0: BR_R1USE_R14 + + .L__critical_start: + +@@ -204,9 +334,11 @@ ENTRY(__switch_to) + */ + ENTRY(sie64a) + stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers ++ lg %r12,__LC_CURRENT + stg %r2,__SF_EMPTY(%r15) # save control block pointer + stg %r3,__SF_EMPTY+8(%r15) # save guest register save area + xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # reason code = 0 ++ mvc __SF_EMPTY+24(8,%r15),__TI_flags(%r12) # copy thread flags + TSTMSK __LC_CPU_FLAGS,_CIF_FPU # load guest fp/vx registers ? + jno .Lsie_load_guest_gprs + brasl %r14,load_fpu_regs # load guest fp/vx regs +@@ -223,7 +355,11 @@ ENTRY(sie64a) + jnz .Lsie_skip + TSTMSK __LC_CPU_FLAGS,_CIF_FPU + jo .Lsie_skip # exit if fp/vx regs changed ++ BPEXIT __SF_EMPTY+24(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) + sie 0(%r14) ++.Lsie_exit: ++ BPOFF ++ BPENTER __SF_EMPTY+24(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) + .Lsie_skip: + ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE + lctlg %c1,%c1,__LC_USER_ASCE # load primary asce +@@ -244,9 +380,15 @@ ENTRY(sie64a) + sie_exit: + lg %r14,__SF_EMPTY+8(%r15) # load guest register save area + stmg %r0,%r13,0(%r14) # save guest gprs 0-13 ++ xgr %r0,%r0 # clear guest registers to ++ xgr %r1,%r1 # prevent speculative use ++ xgr %r2,%r2 ++ xgr %r3,%r3 ++ xgr %r4,%r4 ++ xgr %r5,%r5 + lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers + lg %r2,__SF_EMPTY+16(%r15) # return exit reason code +- br %r14 ++ BR_R1USE_R14 + .Lsie_fault: + lghi %r14,-EFAULT + stg %r14,__SF_EMPTY+16(%r15) # set exit reason code +@@ -267,6 +409,7 @@ ENTRY(system_call) + stpt __LC_SYNC_ENTER_TIMER + .Lsysc_stmg: + stmg %r8,%r15,__LC_SAVE_AREA_SYNC ++ BPOFF + lg %r10,__LC_LAST_BREAK + lg %r12,__LC_THREAD_INFO + lghi %r14,_PIF_SYSCALL +@@ -276,12 +419,15 @@ ENTRY(system_call) + LAST_BREAK %r13 + .Lsysc_vtime: + UPDATE_VTIME %r10,%r13,__LC_SYNC_ENTER_TIMER ++ BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP + stmg %r0,%r7,__PT_R0(%r11) + mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC + mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW + mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC + stg %r14,__PT_FLAGS(%r11) + .Lsysc_do_svc: ++ # clear user controlled register to prevent speculative use ++ xgr %r0,%r0 + lg %r10,__TI_sysc_table(%r12) # address of system call table + llgh %r8,__PT_INT_CODE+2(%r11) + slag %r8,%r8,2 # shift and test for svc 0 +@@ -299,7 +445,7 @@ ENTRY(system_call) + lgf %r9,0(%r8,%r10) # get system call add. + TSTMSK __TI_flags(%r12),_TIF_TRACE + jnz .Lsysc_tracesys +- basr %r14,%r9 # call sys_xxxx ++ BASR_R14_R9 # call sys_xxxx + stg %r2,__PT_R2(%r11) # store return value + + .Lsysc_return: +@@ -311,6 +457,7 @@ ENTRY(system_call) + jnz .Lsysc_work # check for work + TSTMSK __LC_CPU_FLAGS,_CIF_WORK + jnz .Lsysc_work ++ BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP + .Lsysc_restore: + lg %r14,__LC_VDSO_PER_CPU + lmg %r0,%r10,__PT_R0(%r11) +@@ -438,7 +585,7 @@ ENTRY(system_call) + lmg %r3,%r7,__PT_R3(%r11) + stg %r7,STACK_FRAME_OVERHEAD(%r15) + lg %r2,__PT_ORIG_GPR2(%r11) +- basr %r14,%r9 # call sys_xxx ++ BASR_R14_R9 # call sys_xxx + stg %r2,__PT_R2(%r11) # store return value + .Lsysc_tracenogo: + TSTMSK __TI_flags(%r12),_TIF_TRACE +@@ -462,7 +609,7 @@ ENTRY(ret_from_fork) + lmg %r9,%r10,__PT_R9(%r11) # load gprs + ENTRY(kernel_thread_starter) + la %r2,0(%r10) +- basr %r14,%r9 ++ BASR_R14_R9 + j .Lsysc_tracenogo + + /* +@@ -471,6 +618,7 @@ ENTRY(kernel_thread_starter) + + ENTRY(pgm_check_handler) + stpt __LC_SYNC_ENTER_TIMER ++ BPOFF + stmg %r8,%r15,__LC_SAVE_AREA_SYNC + lg %r10,__LC_LAST_BREAK + lg %r12,__LC_THREAD_INFO +@@ -495,6 +643,7 @@ ENTRY(pgm_check_handler) + j 3f + 2: LAST_BREAK %r14 + UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER ++ BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP + lg %r15,__LC_KERNEL_STACK + lg %r14,__TI_task(%r12) + aghi %r14,__TASK_thread # pointer to thread_struct +@@ -504,6 +653,15 @@ ENTRY(pgm_check_handler) + mvc __THREAD_trap_tdb(256,%r14),0(%r13) + 3: la %r11,STACK_FRAME_OVERHEAD(%r15) + stmg %r0,%r7,__PT_R0(%r11) ++ # clear user controlled registers to prevent speculative use ++ xgr %r0,%r0 ++ xgr %r1,%r1 ++ xgr %r2,%r2 ++ xgr %r3,%r3 ++ xgr %r4,%r4 ++ xgr %r5,%r5 ++ xgr %r6,%r6 ++ xgr %r7,%r7 + mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC + stmg %r8,%r9,__PT_PSW(%r11) + mvc __PT_INT_CODE(4,%r11),__LC_PGM_ILC +@@ -525,9 +683,9 @@ ENTRY(pgm_check_handler) + nill %r10,0x007f + sll %r10,2 + je .Lpgm_return +- lgf %r1,0(%r10,%r1) # load address of handler routine ++ lgf %r9,0(%r10,%r1) # load address of handler routine + lgr %r2,%r11 # pass pointer to pt_regs +- basr %r14,%r1 # branch to interrupt-handler ++ BASR_R14_R9 # branch to interrupt-handler + .Lpgm_return: + LOCKDEP_SYS_EXIT + tm __PT_PSW+1(%r11),0x01 # returning to user ? +@@ -560,6 +718,7 @@ ENTRY(pgm_check_handler) + ENTRY(io_int_handler) + STCK __LC_INT_CLOCK + stpt __LC_ASYNC_ENTER_TIMER ++ BPOFF + stmg %r8,%r15,__LC_SAVE_AREA_ASYNC + lg %r10,__LC_LAST_BREAK + lg %r12,__LC_THREAD_INFO +@@ -567,6 +726,16 @@ ENTRY(io_int_handler) + lmg %r8,%r9,__LC_IO_OLD_PSW + SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER + stmg %r0,%r7,__PT_R0(%r11) ++ # clear user controlled registers to prevent speculative use ++ xgr %r0,%r0 ++ xgr %r1,%r1 ++ xgr %r2,%r2 ++ xgr %r3,%r3 ++ xgr %r4,%r4 ++ xgr %r5,%r5 ++ xgr %r6,%r6 ++ xgr %r7,%r7 ++ xgr %r10,%r10 + mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC + stmg %r8,%r9,__PT_PSW(%r11) + mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID +@@ -601,9 +770,13 @@ ENTRY(io_int_handler) + lg %r14,__LC_VDSO_PER_CPU + lmg %r0,%r10,__PT_R0(%r11) + mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) ++ tm __PT_PSW+1(%r11),0x01 # returning to user ? ++ jno .Lio_exit_kernel ++ BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP + .Lio_exit_timer: + stpt __LC_EXIT_TIMER + mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER ++.Lio_exit_kernel: + lmg %r11,%r15,__PT_R11(%r11) + lpswe __LC_RETURN_PSW + .Lio_done: +@@ -735,6 +908,7 @@ ENTRY(io_int_handler) + ENTRY(ext_int_handler) + STCK __LC_INT_CLOCK + stpt __LC_ASYNC_ENTER_TIMER ++ BPOFF + stmg %r8,%r15,__LC_SAVE_AREA_ASYNC + lg %r10,__LC_LAST_BREAK + lg %r12,__LC_THREAD_INFO +@@ -742,6 +916,16 @@ ENTRY(ext_int_handler) + lmg %r8,%r9,__LC_EXT_OLD_PSW + SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_ENTER_TIMER + stmg %r0,%r7,__PT_R0(%r11) ++ # clear user controlled registers to prevent speculative use ++ xgr %r0,%r0 ++ xgr %r1,%r1 ++ xgr %r2,%r2 ++ xgr %r3,%r3 ++ xgr %r4,%r4 ++ xgr %r5,%r5 ++ xgr %r6,%r6 ++ xgr %r7,%r7 ++ xgr %r10,%r10 + mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC + stmg %r8,%r9,__PT_PSW(%r11) + lghi %r1,__LC_EXT_PARAMS2 +@@ -773,11 +957,12 @@ ENTRY(psw_idle) + .insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15) + .Lpsw_idle_stcctm: + #endif ++ BPON + STCK __CLOCK_IDLE_ENTER(%r2) + stpt __TIMER_IDLE_ENTER(%r2) + .Lpsw_idle_lpsw: + lpswe __SF_EMPTY(%r15) +- br %r14 ++ BR_R1USE_R14 + .Lpsw_idle_end: + + /* +@@ -791,7 +976,7 @@ ENTRY(save_fpu_regs) + lg %r2,__LC_CURRENT + aghi %r2,__TASK_thread + TSTMSK __LC_CPU_FLAGS,_CIF_FPU +- bor %r14 ++ jo .Lsave_fpu_regs_exit + stfpc __THREAD_FPU_fpc(%r2) + .Lsave_fpu_regs_fpc_end: + lg %r3,__THREAD_FPU_regs(%r2) +@@ -821,7 +1006,8 @@ ENTRY(save_fpu_regs) + std 15,120(%r3) + .Lsave_fpu_regs_done: + oi __LC_CPU_FLAGS+7,_CIF_FPU +- br %r14 ++.Lsave_fpu_regs_exit: ++ BR_R1USE_R14 + .Lsave_fpu_regs_end: + + /* +@@ -838,7 +1024,7 @@ load_fpu_regs: + lg %r4,__LC_CURRENT + aghi %r4,__TASK_thread + TSTMSK __LC_CPU_FLAGS,_CIF_FPU +- bnor %r14 ++ jno .Lload_fpu_regs_exit + lfpc __THREAD_FPU_fpc(%r4) + TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_VX + lg %r4,__THREAD_FPU_regs(%r4) # %r4 <- reg save area +@@ -867,7 +1053,8 @@ load_fpu_regs: + ld 15,120(%r4) + .Lload_fpu_regs_done: + ni __LC_CPU_FLAGS+7,255-_CIF_FPU +- br %r14 ++.Lload_fpu_regs_exit: ++ BR_R1USE_R14 + .Lload_fpu_regs_end: + + .L__critical_end: +@@ -877,6 +1064,7 @@ load_fpu_regs: + */ + ENTRY(mcck_int_handler) + STCK __LC_MCCK_CLOCK ++ BPOFF + la %r1,4095 # revalidate r1 + spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer + lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs +@@ -908,6 +1096,16 @@ ENTRY(mcck_int_handler) + .Lmcck_skip: + lghi %r14,__LC_GPREGS_SAVE_AREA+64 + stmg %r0,%r7,__PT_R0(%r11) ++ # clear user controlled registers to prevent speculative use ++ xgr %r0,%r0 ++ xgr %r1,%r1 ++ xgr %r2,%r2 ++ xgr %r3,%r3 ++ xgr %r4,%r4 ++ xgr %r5,%r5 ++ xgr %r6,%r6 ++ xgr %r7,%r7 ++ xgr %r10,%r10 + mvc __PT_R8(64,%r11),0(%r14) + stmg %r8,%r9,__PT_PSW(%r11) + xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) +@@ -933,6 +1131,7 @@ ENTRY(mcck_int_handler) + mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW + tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? + jno 0f ++ BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP + stpt __LC_EXIT_TIMER + mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER + 0: lmg %r11,%r15,__PT_R11(%r11) +@@ -1028,7 +1227,7 @@ cleanup_critical: + jl 0f + clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end + jl .Lcleanup_load_fpu_regs +-0: br %r14 ++0: BR_R11USE_R14 + + .align 8 + .Lcleanup_table: +@@ -1053,11 +1252,12 @@ cleanup_critical: + .quad .Lsie_done + + .Lcleanup_sie: ++ BPENTER __SF_EMPTY+24(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) + lg %r9,__SF_EMPTY(%r15) # get control block pointer + ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE + lctlg %c1,%c1,__LC_USER_ASCE # load primary asce + larl %r9,sie_exit # skip forward to sie_exit +- br %r14 ++ BR_R11USE_R14 + #endif + + .Lcleanup_system_call: +@@ -1099,7 +1299,8 @@ cleanup_critical: + srag %r9,%r9,23 + jz 0f + mvc __TI_last_break(8,%r12),16(%r11) +-0: # set up saved register r11 ++0: BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP ++ # set up saved register r11 + lg %r15,__LC_KERNEL_STACK + la %r9,STACK_FRAME_OVERHEAD(%r15) + stg %r9,24(%r11) # r11 pt_regs pointer +@@ -1114,7 +1315,7 @@ cleanup_critical: + stg %r15,56(%r11) # r15 stack pointer + # set new psw address and exit + larl %r9,.Lsysc_do_svc +- br %r14 ++ BR_R11USE_R14 + .Lcleanup_system_call_insn: + .quad system_call + .quad .Lsysc_stmg +@@ -1124,7 +1325,7 @@ cleanup_critical: + + .Lcleanup_sysc_tif: + larl %r9,.Lsysc_tif +- br %r14 ++ BR_R11USE_R14 + + .Lcleanup_sysc_restore: + # check if stpt has been executed +@@ -1141,14 +1342,14 @@ cleanup_critical: + mvc 0(64,%r11),__PT_R8(%r9) + lmg %r0,%r7,__PT_R0(%r9) + 1: lmg %r8,%r9,__LC_RETURN_PSW +- br %r14 ++ BR_R11USE_R14 + .Lcleanup_sysc_restore_insn: + .quad .Lsysc_exit_timer + .quad .Lsysc_done - 4 + + .Lcleanup_io_tif: + larl %r9,.Lio_tif +- br %r14 ++ BR_R11USE_R14 + + .Lcleanup_io_restore: + # check if stpt has been executed +@@ -1162,7 +1363,7 @@ cleanup_critical: + mvc 0(64,%r11),__PT_R8(%r9) + lmg %r0,%r7,__PT_R0(%r9) + 1: lmg %r8,%r9,__LC_RETURN_PSW +- br %r14 ++ BR_R11USE_R14 + .Lcleanup_io_restore_insn: + .quad .Lio_exit_timer + .quad .Lio_done - 4 +@@ -1214,17 +1415,17 @@ cleanup_critical: + # prepare return psw + nihh %r8,0xfcfd # clear irq & wait state bits + lg %r9,48(%r11) # return from psw_idle +- br %r14 ++ BR_R11USE_R14 + .Lcleanup_idle_insn: + .quad .Lpsw_idle_lpsw + + .Lcleanup_save_fpu_regs: + larl %r9,save_fpu_regs +- br %r14 ++ BR_R11USE_R14 + + .Lcleanup_load_fpu_regs: + larl %r9,load_fpu_regs +- br %r14 ++ BR_R11USE_R14 + + /* + * Integer constants +@@ -1240,7 +1441,6 @@ cleanup_critical: + .Lsie_critical_length: + .quad .Lsie_done - .Lsie_gmap + #endif +- + .section .rodata, "a" + #define SYSCALL(esame,emu) .long esame + .globl sys_call_table +diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c +index e73979236659..837bb301023f 100644 +--- a/arch/s390/kernel/ipl.c ++++ b/arch/s390/kernel/ipl.c +@@ -563,6 +563,7 @@ static struct kset *ipl_kset; + + static void __ipl_run(void *unused) + { ++ __bpon(); + diag308(DIAG308_IPL, NULL); + if (MACHINE_IS_VM) + __cpcmd("IPL", NULL, 0, NULL); +diff --git a/arch/s390/kernel/nospec-branch.c b/arch/s390/kernel/nospec-branch.c +new file mode 100644 +index 000000000000..9f3b5b382743 +--- /dev/null ++++ b/arch/s390/kernel/nospec-branch.c +@@ -0,0 +1,169 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include ++#include ++#include ++#include ++ ++static int __init nobp_setup_early(char *str) ++{ ++ bool enabled; ++ int rc; ++ ++ rc = kstrtobool(str, &enabled); ++ if (rc) ++ return rc; ++ if (enabled && test_facility(82)) { ++ /* ++ * The user explicitely requested nobp=1, enable it and ++ * disable the expoline support. ++ */ ++ __set_facility(82, S390_lowcore.alt_stfle_fac_list); ++ if (IS_ENABLED(CONFIG_EXPOLINE)) ++ nospec_disable = 1; ++ } else { ++ __clear_facility(82, S390_lowcore.alt_stfle_fac_list); ++ } ++ return 0; ++} ++early_param("nobp", nobp_setup_early); ++ ++static int __init nospec_setup_early(char *str) ++{ ++ __clear_facility(82, S390_lowcore.alt_stfle_fac_list); ++ return 0; ++} ++early_param("nospec", nospec_setup_early); ++ ++static int __init nospec_report(void) ++{ ++ if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) ++ pr_info("Spectre V2 mitigation: execute trampolines.\n"); ++ if (__test_facility(82, S390_lowcore.alt_stfle_fac_list)) ++ pr_info("Spectre V2 mitigation: limited branch prediction.\n"); ++ return 0; ++} ++arch_initcall(nospec_report); ++ ++#ifdef CONFIG_SYSFS ++ssize_t cpu_show_spectre_v1(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sprintf(buf, "Mitigation: __user pointer sanitization\n"); ++} ++ ++ssize_t cpu_show_spectre_v2(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) ++ return sprintf(buf, "Mitigation: execute trampolines\n"); ++ if (__test_facility(82, S390_lowcore.alt_stfle_fac_list)) ++ return sprintf(buf, "Mitigation: limited branch prediction.\n"); ++ return sprintf(buf, "Vulnerable\n"); ++} ++#endif ++ ++#ifdef CONFIG_EXPOLINE ++ ++int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF); ++ ++static int __init nospectre_v2_setup_early(char *str) ++{ ++ nospec_disable = 1; ++ return 0; ++} ++early_param("nospectre_v2", nospectre_v2_setup_early); ++ ++void __init nospec_auto_detect(void) ++{ ++ if (IS_ENABLED(CC_USING_EXPOLINE)) { ++ /* ++ * The kernel has been compiled with expolines. ++ * Keep expolines enabled and disable nobp. ++ */ ++ nospec_disable = 0; ++ __clear_facility(82, S390_lowcore.alt_stfle_fac_list); ++ } ++ /* ++ * If the kernel has not been compiled with expolines the ++ * nobp setting decides what is done, this depends on the ++ * CONFIG_KERNEL_NP option and the nobp/nospec parameters. ++ */ ++} ++ ++static int __init spectre_v2_setup_early(char *str) ++{ ++ if (str && !strncmp(str, "on", 2)) { ++ nospec_disable = 0; ++ __clear_facility(82, S390_lowcore.alt_stfle_fac_list); ++ } ++ if (str && !strncmp(str, "off", 3)) ++ nospec_disable = 1; ++ if (str && !strncmp(str, "auto", 4)) ++ nospec_auto_detect(); ++ return 0; ++} ++early_param("spectre_v2", spectre_v2_setup_early); ++ ++static void __init_or_module __nospec_revert(s32 *start, s32 *end) ++{ ++ enum { BRCL_EXPOLINE, BRASL_EXPOLINE } type; ++ u8 *instr, *thunk, *br; ++ u8 insnbuf[6]; ++ s32 *epo; ++ ++ /* Second part of the instruction replace is always a nop */ ++ memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x00, 0x00 }, 4); ++ for (epo = start; epo < end; epo++) { ++ instr = (u8 *) epo + *epo; ++ if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04) ++ type = BRCL_EXPOLINE; /* brcl instruction */ ++ else if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x05) ++ type = BRASL_EXPOLINE; /* brasl instruction */ ++ else ++ continue; ++ thunk = instr + (*(int *)(instr + 2)) * 2; ++ if (thunk[0] == 0xc6 && thunk[1] == 0x00) ++ /* exrl %r0, */ ++ br = thunk + (*(int *)(thunk + 2)) * 2; ++ else if (thunk[0] == 0xc0 && (thunk[1] & 0x0f) == 0x00 && ++ thunk[6] == 0x44 && thunk[7] == 0x00 && ++ (thunk[8] & 0x0f) == 0x00 && thunk[9] == 0x00 && ++ (thunk[1] & 0xf0) == (thunk[8] & 0xf0)) ++ /* larl %rx, + ex %r0,0(%rx) */ ++ br = thunk + (*(int *)(thunk + 2)) * 2; ++ else ++ continue; ++ if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0) ++ continue; ++ switch (type) { ++ case BRCL_EXPOLINE: ++ /* brcl to thunk, replace with br + nop */ ++ insnbuf[0] = br[0]; ++ insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); ++ break; ++ case BRASL_EXPOLINE: ++ /* brasl to thunk, replace with basr + nop */ ++ insnbuf[0] = 0x0d; ++ insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); ++ break; ++ } ++ ++ s390_kernel_write(instr, insnbuf, 6); ++ } ++} ++ ++void __init_or_module nospec_revert(s32 *start, s32 *end) ++{ ++ if (nospec_disable) ++ __nospec_revert(start, end); ++} ++ ++extern s32 __nospec_call_start[], __nospec_call_end[]; ++extern s32 __nospec_return_start[], __nospec_return_end[]; ++void __init nospec_init_branches(void) ++{ ++ nospec_revert(__nospec_call_start, __nospec_call_end); ++ nospec_revert(__nospec_return_start, __nospec_return_end); ++} ++ ++#endif /* CONFIG_EXPOLINE */ +diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c +index 7ce00e7a709a..ab236bd970bb 100644 +--- a/arch/s390/kernel/processor.c ++++ b/arch/s390/kernel/processor.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -113,3 +114,20 @@ const struct seq_operations cpuinfo_op = { + .show = show_cpuinfo, + }; + ++int s390_isolate_bp(void) ++{ ++ if (!test_facility(82)) ++ return -EOPNOTSUPP; ++ set_thread_flag(TIF_ISOLATE_BP); ++ return 0; ++} ++EXPORT_SYMBOL(s390_isolate_bp); ++ ++int s390_isolate_bp_guest(void) ++{ ++ if (!test_facility(82)) ++ return -EOPNOTSUPP; ++ set_thread_flag(TIF_ISOLATE_BP_GUEST); ++ return 0; ++} ++EXPORT_SYMBOL(s390_isolate_bp_guest); +diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c +index d097d71685df..e7a43a30e3ff 100644 +--- a/arch/s390/kernel/setup.c ++++ b/arch/s390/kernel/setup.c +@@ -63,6 +63,8 @@ + #include + #include + #include ++#include ++#include + #include "entry.h" + + /* +@@ -333,7 +335,9 @@ static void __init setup_lowcore(void) + lc->machine_flags = S390_lowcore.machine_flags; + lc->stfl_fac_list = S390_lowcore.stfl_fac_list; + memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list, +- MAX_FACILITY_BIT/8); ++ sizeof(lc->stfle_fac_list)); ++ memcpy(lc->alt_stfle_fac_list, S390_lowcore.alt_stfle_fac_list, ++ sizeof(lc->alt_stfle_fac_list)); + if (MACHINE_HAS_VX) + lc->vector_save_area_addr = + (unsigned long) &lc->vector_save_area; +@@ -370,6 +374,7 @@ static void __init setup_lowcore(void) + #ifdef CONFIG_SMP + lc->spinlock_lockval = arch_spin_lockval(0); + #endif ++ lc->br_r1_trampoline = 0x07f1; /* br %r1 */ + + set_prefix((u32)(unsigned long) lc); + lowcore_ptr[0] = lc; +@@ -841,6 +846,9 @@ void __init setup_arch(char **cmdline_p) + init_mm.end_data = (unsigned long) &_edata; + init_mm.brk = (unsigned long) &_end; + ++ if (IS_ENABLED(CONFIG_EXPOLINE_AUTO)) ++ nospec_auto_detect(); ++ + parse_early_param(); + os_info_init(); + setup_ipl(); +@@ -893,6 +901,10 @@ void __init setup_arch(char **cmdline_p) + conmode_default(); + set_preferred_console(); + ++ apply_alternative_instructions(); ++ if (IS_ENABLED(CONFIG_EXPOLINE)) ++ nospec_init_branches(); ++ + /* Setup zfcpdump support */ + setup_zfcpdump(); + +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 9062df575afe..77f4f334a465 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -200,6 +200,7 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) + lc->panic_stack = panic_stack + PANIC_FRAME_OFFSET; + lc->cpu_nr = cpu; + lc->spinlock_lockval = arch_spin_lockval(cpu); ++ lc->br_r1_trampoline = 0x07f1; /* br %r1 */ + if (MACHINE_HAS_VX) + lc->vector_save_area_addr = + (unsigned long) &lc->vector_save_area; +@@ -250,7 +251,9 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) + __ctl_store(lc->cregs_save_area, 0, 15); + save_access_regs((unsigned int *) lc->access_regs_save_area); + memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list, +- MAX_FACILITY_BIT/8); ++ sizeof(lc->stfle_fac_list)); ++ memcpy(lc->alt_stfle_fac_list, S390_lowcore.alt_stfle_fac_list, ++ sizeof(lc->alt_stfle_fac_list)); + } + + static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) +@@ -299,6 +302,7 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), + mem_assign_absolute(lc->restart_fn, (unsigned long) func); + mem_assign_absolute(lc->restart_data, (unsigned long) data); + mem_assign_absolute(lc->restart_source, source_cpu); ++ __bpon(); + asm volatile( + "0: sigp 0,%0,%2 # sigp restart to target cpu\n" + " brc 2,0b # busy, try again\n" +@@ -888,6 +892,7 @@ void __cpu_die(unsigned int cpu) + void __noreturn cpu_die(void) + { + idle_task_exit(); ++ __bpon(); + pcpu_sigp_retry(pcpu_devices + smp_processor_id(), SIGP_STOP, 0); + for (;;) ; + } +diff --git a/arch/s390/kernel/uprobes.c b/arch/s390/kernel/uprobes.c +index 66956c09d5bf..3d04dfdabc9f 100644 +--- a/arch/s390/kernel/uprobes.c ++++ b/arch/s390/kernel/uprobes.c +@@ -147,6 +147,15 @@ unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline, + return orig; + } + ++bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, ++ struct pt_regs *regs) ++{ ++ if (ctx == RP_CHECK_CHAIN_CALL) ++ return user_stack_pointer(regs) <= ret->stack; ++ else ++ return user_stack_pointer(regs) < ret->stack; ++} ++ + /* Instruction Emulation */ + + static void adjust_psw_addr(psw_t *psw, unsigned long len) +diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S +index 6c553f6e791a..a4ae08e416e6 100644 +--- a/arch/s390/kernel/vmlinux.lds.S ++++ b/arch/s390/kernel/vmlinux.lds.S +@@ -78,6 +78,43 @@ SECTIONS + EXIT_DATA + } + ++ /* ++ * struct alt_inst entries. From the header (alternative.h): ++ * "Alternative instructions for different CPU types or capabilities" ++ * Think locking instructions on spinlocks. ++ * Note, that it is a part of __init region. ++ */ ++ . = ALIGN(8); ++ .altinstructions : { ++ __alt_instructions = .; ++ *(.altinstructions) ++ __alt_instructions_end = .; ++ } ++ ++ /* ++ * And here are the replacement instructions. The linker sticks ++ * them as binary blobs. The .altinstructions has enough data to ++ * get the address and the length of them to patch the kernel safely. ++ * Note, that it is a part of __init region. ++ */ ++ .altinstr_replacement : { ++ *(.altinstr_replacement) ++ } ++ ++ /* ++ * Table with the patch locations to undo expolines ++ */ ++ .nospec_call_table : { ++ __nospec_call_start = . ; ++ *(.s390_indirect*) ++ __nospec_call_end = . ; ++ } ++ .nospec_return_table : { ++ __nospec_return_start = . ; ++ *(.s390_return*) ++ __nospec_return_end = . ; ++ } ++ + /* early.c uses stsi, which requires page aligned data. */ + . = ALIGN(PAGE_SIZE); + INIT_DATA_SECTION(0x100) +diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c +index 23e3f5d77a24..b011140e6b06 100644 +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -257,6 +257,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) + case KVM_CAP_S390_VECTOR_REGISTERS: + r = MACHINE_HAS_VX; + break; ++ case KVM_CAP_S390_BPB: ++ r = test_facility(82); ++ break; + default: + r = 0; + } +@@ -1264,6 +1267,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) + KVM_SYNC_PFAULT; + if (test_kvm_facility(vcpu->kvm, 129)) + vcpu->run->kvm_valid_regs |= KVM_SYNC_VRS; ++ if (test_kvm_facility(vcpu->kvm, 82)) ++ vcpu->run->kvm_valid_regs |= KVM_SYNC_BPBC; + + if (kvm_is_ucontrol(vcpu->kvm)) + return __kvm_ucontrol_vcpu_init(vcpu); +@@ -1327,6 +1332,7 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) + current->thread.fpu.fpc = 0; + vcpu->arch.sie_block->gbea = 1; + vcpu->arch.sie_block->pp = 0; ++ vcpu->arch.sie_block->fpf &= ~FPF_BPBC; + vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; + kvm_clear_async_pf_completion_queue(vcpu); + if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm)) +@@ -2145,6 +2151,11 @@ static void sync_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) + if (vcpu->arch.pfault_token == KVM_S390_PFAULT_TOKEN_INVALID) + kvm_clear_async_pf_completion_queue(vcpu); + } ++ if ((kvm_run->kvm_dirty_regs & KVM_SYNC_BPBC) && ++ test_kvm_facility(vcpu->kvm, 82)) { ++ vcpu->arch.sie_block->fpf &= ~FPF_BPBC; ++ vcpu->arch.sie_block->fpf |= kvm_run->s.regs.bpbc ? FPF_BPBC : 0; ++ } + kvm_run->kvm_dirty_regs = 0; + } + +@@ -2162,6 +2173,7 @@ static void store_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) + kvm_run->s.regs.pft = vcpu->arch.pfault_token; + kvm_run->s.regs.pfs = vcpu->arch.pfault_select; + kvm_run->s.regs.pfc = vcpu->arch.pfault_compare; ++ kvm_run->s.regs.bpbc = (vcpu->arch.sie_block->fpf & FPF_BPBC) == FPF_BPBC; + } + + int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c +index eb02087650d2..c42d4a3d9494 100644 +--- a/arch/x86/kernel/tsc.c ++++ b/arch/x86/kernel/tsc.c +@@ -408,7 +408,7 @@ static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) + hpet2 -= hpet1; + tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD)); + do_div(tmp, 1000000); +- do_div(deltatsc, tmp); ++ deltatsc = div64_u64(deltatsc, tmp); + + return (unsigned long) deltatsc; + } +diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c +index c206ccda899b..b5f245d2875c 100644 +--- a/drivers/cdrom/cdrom.c ++++ b/drivers/cdrom/cdrom.c +@@ -2358,7 +2358,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, + if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT) + return media_changed(cdi, 1); + +- if ((unsigned int)arg >= cdi->capacity) ++ if (arg >= cdi->capacity) + return -EINVAL; + + info = kmalloc(sizeof(*info), GFP_KERNEL); +diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c +index 930424e55439..251d64ca41ce 100644 +--- a/drivers/input/misc/drv260x.c ++++ b/drivers/input/misc/drv260x.c +@@ -521,7 +521,7 @@ static int drv260x_probe(struct i2c_client *client, + if (!haptics) + return -ENOMEM; + +- haptics->rated_voltage = DRV260X_DEF_OD_CLAMP_VOLT; ++ haptics->overdrive_voltage = DRV260X_DEF_OD_CLAMP_VOLT; + haptics->rated_voltage = DRV260X_DEF_RATED_VOLT; + + if (pdata) { +diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c +index 7ebccfa8072a..cb790b68920f 100644 +--- a/drivers/message/fusion/mptsas.c ++++ b/drivers/message/fusion/mptsas.c +@@ -1994,6 +1994,7 @@ static struct scsi_host_template mptsas_driver_template = { + .cmd_per_lun = 7, + .use_clustering = ENABLE_CLUSTERING, + .shost_attrs = mptscsih_host_attrs, ++ .no_write_same = 1, + }; + + static int mptsas_get_linkerrors(struct sas_phy *phy) +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index 278d12888cab..339118f3c718 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1614,8 +1614,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) + } /* switch(bond_mode) */ + + #ifdef CONFIG_NET_POLL_CONTROLLER +- slave_dev->npinfo = bond->dev->npinfo; +- if (slave_dev->npinfo) { ++ if (bond->dev->npinfo) { + if (slave_enable_netpoll(new_slave)) { + netdev_info(bond_dev, "master_dev is using netpoll, but new slave device does not support netpoll\n"); + res = -EBUSY; +diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c +index b7b859c3a0c7..583d50f80b24 100644 +--- a/drivers/net/ppp/pppoe.c ++++ b/drivers/net/ppp/pppoe.c +@@ -638,6 +638,10 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, + lock_sock(sk); + + error = -EINVAL; ++ ++ if (sockaddr_len != sizeof(struct sockaddr_pppox)) ++ goto end; ++ + if (sp->sa_protocol != PX_PROTO_OE) + goto end; + +diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c +index 9bca36e1fefd..e74709e4b5dd 100644 +--- a/drivers/net/team/team.c ++++ b/drivers/net/team/team.c +@@ -247,6 +247,17 @@ static void __team_option_inst_mark_removed_port(struct team *team, + } + } + ++static bool __team_option_inst_tmp_find(const struct list_head *opts, ++ const struct team_option_inst *needle) ++{ ++ struct team_option_inst *opt_inst; ++ ++ list_for_each_entry(opt_inst, opts, tmp_list) ++ if (opt_inst == needle) ++ return true; ++ return false; ++} ++ + static int __team_options_register(struct team *team, + const struct team_option *option, + size_t option_count) +@@ -1039,14 +1050,11 @@ static void team_port_leave(struct team *team, struct team_port *port) + } + + #ifdef CONFIG_NET_POLL_CONTROLLER +-static int team_port_enable_netpoll(struct team *team, struct team_port *port) ++static int __team_port_enable_netpoll(struct team_port *port) + { + struct netpoll *np; + int err; + +- if (!team->dev->npinfo) +- return 0; +- + np = kzalloc(sizeof(*np), GFP_KERNEL); + if (!np) + return -ENOMEM; +@@ -1060,6 +1068,14 @@ static int team_port_enable_netpoll(struct team *team, struct team_port *port) + return err; + } + ++static int team_port_enable_netpoll(struct team_port *port) ++{ ++ if (!port->team->dev->npinfo) ++ return 0; ++ ++ return __team_port_enable_netpoll(port); ++} ++ + static void team_port_disable_netpoll(struct team_port *port) + { + struct netpoll *np = port->np; +@@ -1074,7 +1090,7 @@ static void team_port_disable_netpoll(struct team_port *port) + kfree(np); + } + #else +-static int team_port_enable_netpoll(struct team *team, struct team_port *port) ++static int team_port_enable_netpoll(struct team_port *port) + { + return 0; + } +@@ -1181,7 +1197,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev) + goto err_vids_add; + } + +- err = team_port_enable_netpoll(team, port); ++ err = team_port_enable_netpoll(port); + if (err) { + netdev_err(dev, "Failed to enable netpoll on device %s\n", + portname); +@@ -1889,7 +1905,7 @@ static int team_netpoll_setup(struct net_device *dev, + + mutex_lock(&team->lock); + list_for_each_entry(port, &team->port_list, list) { +- err = team_port_enable_netpoll(team, port); ++ err = __team_port_enable_netpoll(port); + if (err) { + __team_netpoll_cleanup(team); + break; +@@ -2544,6 +2560,14 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) + if (err) + goto team_put; + opt_inst->changed = true; ++ ++ /* dumb/evil user-space can send us duplicate opt, ++ * keep only the last one ++ */ ++ if (__team_option_inst_tmp_find(&opt_inst_list, ++ opt_inst)) ++ continue; ++ + list_add(&opt_inst->tmp_list, &opt_inst_list); + } + if (!opt_found) { +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index 6578127db847..f71abe50ea6f 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -461,6 +461,7 @@ static const struct driver_info wwan_info = { + #define REALTEK_VENDOR_ID 0x0bda + #define SAMSUNG_VENDOR_ID 0x04e8 + #define LENOVO_VENDOR_ID 0x17ef ++#define LINKSYS_VENDOR_ID 0x13b1 + #define NVIDIA_VENDOR_ID 0x0955 + #define HP_VENDOR_ID 0x03f0 + +@@ -650,6 +651,15 @@ static const struct usb_device_id products[] = { + .driver_info = 0, + }, + ++#if IS_ENABLED(CONFIG_USB_RTL8152) ++/* Linksys USB3GIGV1 Ethernet Adapter */ ++{ ++ USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, USB_CLASS_COMM, ++ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), ++ .driver_info = 0, ++}, ++#endif ++ + /* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ + { + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM, +diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c +index 89950f5cea71..b2c1a435357f 100644 +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -506,6 +506,7 @@ enum rtl8152_flags { + #define VENDOR_ID_REALTEK 0x0bda + #define VENDOR_ID_SAMSUNG 0x04e8 + #define VENDOR_ID_LENOVO 0x17ef ++#define VENDOR_ID_LINKSYS 0x13b1 + #define VENDOR_ID_NVIDIA 0x0955 + + #define MCU_TYPE_PLA 0x0100 +@@ -4376,6 +4377,7 @@ static struct usb_device_id rtl8152_table[] = { + {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, ++ {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, + {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, + {} + }; +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 09e14ce85dd0..0c8efdff4843 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -5285,9 +5285,8 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk) + sta->addr, smps, err); + } + +- if (changed & IEEE80211_RC_SUPP_RATES_CHANGED || +- changed & IEEE80211_RC_NSS_CHANGED) { +- ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n", ++ if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { ++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", + sta->addr); + + err = ath10k_station_assoc(ar, arvif->vif, sta, true); +diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c +index 41382f89abe1..4435c7bbb625 100644 +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -1595,6 +1595,10 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) + int count = 50; + u32 reg, last_val; + ++ /* Check if chip failed to wake up */ ++ if (REG_READ(ah, AR_CFG) == 0xdeadbeef) ++ return false; ++ + if (AR_SREV_9300(ah)) + return !ath9k_hw_detect_mac_hang(ah); + +diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile +index 6fa9364d1c07..835f1054976b 100644 +--- a/drivers/s390/char/Makefile ++++ b/drivers/s390/char/Makefile +@@ -2,6 +2,8 @@ + # S/390 character devices + # + ++CFLAGS_REMOVE_sclp_early_core.o += $(CC_FLAGS_EXPOLINE) ++ + obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ + sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o \ + sclp_early.o +diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c +index 1e16331891a9..f9d6a9f00640 100644 +--- a/drivers/s390/cio/chsc.c ++++ b/drivers/s390/cio/chsc.c +@@ -451,6 +451,7 @@ static void chsc_process_sei_link_incident(struct chsc_sei_nt0_area *sei_area) + + static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area) + { ++ struct channel_path *chp; + struct chp_link link; + struct chp_id chpid; + int status; +@@ -463,10 +464,17 @@ static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area) + chpid.id = sei_area->rsid; + /* allocate a new channel path structure, if needed */ + status = chp_get_status(chpid); +- if (status < 0) +- chp_new(chpid); +- else if (!status) ++ if (!status) + return; ++ ++ if (status < 0) { ++ chp_new(chpid); ++ } else { ++ chp = chpid_to_chp(chpid); ++ mutex_lock(&chp->lock); ++ chp_update_desc(chp); ++ mutex_unlock(&chp->lock); ++ } + memset(&link, 0, sizeof(struct chp_link)); + link.chpid = chpid; + if ((sei_area->vf & 0xc0) != 0) { +diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c +index d4c3e5512dd5..b69dfc706440 100644 +--- a/drivers/staging/android/ion/ion_system_heap.c ++++ b/drivers/staging/android/ion/ion_system_heap.c +@@ -27,7 +27,7 @@ + #include "ion_priv.h" + + static gfp_t high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN | +- __GFP_NORETRY) & ~__GFP_DIRECT_RECLAIM; ++ __GFP_NORETRY) & ~__GFP_RECLAIM; + static gfp_t low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN); + static const unsigned int orders[] = {8, 4, 0}; + static const int num_orders = ARRAY_SIZE(orders); +diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c +index 49a0d6b027c1..76dacd5307b9 100644 +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -673,6 +673,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, + goto mknod_out; + } + ++ if (!S_ISCHR(mode) && !S_ISBLK(mode)) ++ goto mknod_out; ++ + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) + goto mknod_out; + +@@ -681,10 +684,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, + + buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); + if (buf == NULL) { +- kfree(full_path); + rc = -ENOMEM; +- free_xid(xid); +- return rc; ++ goto mknod_out; + } + + if (backup_cred(cifs_sb)) +@@ -731,7 +732,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, + pdev->minor = cpu_to_le64(MINOR(device_number)); + rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms, + &bytes_written, iov, 1); +- } /* else if (S_ISFIFO) */ ++ } + tcon->ses->server->ops->close(xid, tcon, &fid); + d_drop(direntry); + +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index 4759df4eb8ce..9398d1b70545 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -275,11 +275,11 @@ loop: + goto loop; + + end_loop: +- write_unlock(&journal->j_state_lock); + del_timer_sync(&journal->j_commit_timer); + journal->j_task = NULL; + wake_up(&journal->j_wait_done_commit); + jbd_debug(1, "Journal thread exiting.\n"); ++ write_unlock(&journal->j_state_lock); + return 0; + } + +diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h +index 19db03dbbd00..dd676ba758ee 100644 +--- a/include/linux/if_vlan.h ++++ b/include/linux/if_vlan.h +@@ -585,7 +585,7 @@ static inline bool skb_vlan_tagged(const struct sk_buff *skb) + * Returns true if the skb is tagged with multiple vlan headers, regardless + * of whether it is hardware accelerated or not. + */ +-static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb) ++static inline bool skb_vlan_tagged_multi(struct sk_buff *skb) + { + __be16 protocol = skb->protocol; + +@@ -596,6 +596,9 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb) + protocol != htons(ETH_P_8021AD))) + return false; + ++ if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) ++ return false; ++ + veh = (struct vlan_ethhdr *)skb->data; + protocol = veh->h_vlan_encapsulated_proto; + } +@@ -613,7 +616,7 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb) + * + * Returns features without unsafe ones if the skb has multiple tags. + */ +-static inline netdev_features_t vlan_features_check(const struct sk_buff *skb, ++static inline netdev_features_t vlan_features_check(struct sk_buff *skb, + netdev_features_t features) + { + if (skb_vlan_tagged_multi(skb)) { +diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h +index fe994d2e5286..ea985aa7a6c5 100644 +--- a/include/net/llc_conn.h ++++ b/include/net/llc_conn.h +@@ -97,6 +97,7 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb) + + struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, + struct proto *prot, int kern); ++void llc_sk_stop_all_timers(struct sock *sk, bool sync); + void llc_sk_free(struct sock *sk); + + void llc_sk_reset(struct sock *sk); +diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h +index 03f3618612aa..376d0ab5b9f2 100644 +--- a/include/uapi/linux/kvm.h ++++ b/include/uapi/linux/kvm.h +@@ -831,6 +831,7 @@ struct kvm_ppc_smmu_info { + #define KVM_CAP_GUEST_DEBUG_HW_WPS 120 + #define KVM_CAP_SPLIT_IRQCHIP 121 + #define KVM_CAP_IOEVENTFD_ANY_LENGTH 122 ++#define KVM_CAP_S390_BPB 152 + + #ifdef KVM_CAP_IRQ_ROUTING + +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 835ac4d9f349..6aeb0ef4fe70 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -8133,9 +8133,9 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, + * __u16 sample size limit. + */ + if (attr->sample_stack_user >= USHRT_MAX) +- ret = -EINVAL; ++ return -EINVAL; + else if (!IS_ALIGNED(attr->sample_stack_user, sizeof(u64))) +- ret = -EINVAL; ++ return -EINVAL; + } + + if (attr->sample_type & PERF_SAMPLE_REGS_INTR) +diff --git a/net/core/dev.c b/net/core/dev.c +index dc63c37d5301..3bcbf931a910 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2706,7 +2706,7 @@ netdev_features_t passthru_features_check(struct sk_buff *skb, + } + EXPORT_SYMBOL(passthru_features_check); + +-static netdev_features_t dflt_features_check(const struct sk_buff *skb, ++static netdev_features_t dflt_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) + { +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index 33432e64804c..f60b93627876 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -54,7 +54,8 @@ do { \ + static void neigh_timer_handler(unsigned long arg); + static void __neigh_notify(struct neighbour *n, int type, int flags); + static void neigh_update_notify(struct neighbour *neigh); +-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev); ++static int pneigh_ifdown_and_unlock(struct neigh_table *tbl, ++ struct net_device *dev); + + #ifdef CONFIG_PROC_FS + static const struct file_operations neigh_stat_seq_fops; +@@ -254,8 +255,7 @@ int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev) + { + write_lock_bh(&tbl->lock); + neigh_flush_dev(tbl, dev); +- pneigh_ifdown(tbl, dev); +- write_unlock_bh(&tbl->lock); ++ pneigh_ifdown_and_unlock(tbl, dev); + + del_timer_sync(&tbl->proxy_timer); + pneigh_queue_purge(&tbl->proxy_queue); +@@ -645,9 +645,10 @@ int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey, + return -ENOENT; + } + +-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev) ++static int pneigh_ifdown_and_unlock(struct neigh_table *tbl, ++ struct net_device *dev) + { +- struct pneigh_entry *n, **np; ++ struct pneigh_entry *n, **np, *freelist = NULL; + u32 h; + + for (h = 0; h <= PNEIGH_HASHMASK; h++) { +@@ -655,16 +656,23 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev) + while ((n = *np) != NULL) { + if (!dev || n->dev == dev) { + *np = n->next; +- if (tbl->pdestructor) +- tbl->pdestructor(n); +- if (n->dev) +- dev_put(n->dev); +- kfree(n); ++ n->next = freelist; ++ freelist = n; + continue; + } + np = &n->next; + } + } ++ write_unlock_bh(&tbl->lock); ++ while ((n = freelist)) { ++ freelist = n->next; ++ n->next = NULL; ++ if (tbl->pdestructor) ++ tbl->pdestructor(n); ++ if (n->dev) ++ dev_put(n->dev); ++ kfree(n); ++ } + return -ENOENT; + } + +@@ -2280,12 +2288,16 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, + + err = nlmsg_parse(nlh, sizeof(struct ndmsg), tb, NDA_MAX, NULL); + if (!err) { +- if (tb[NDA_IFINDEX]) ++ if (tb[NDA_IFINDEX]) { ++ if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32)) ++ return -EINVAL; + filter_idx = nla_get_u32(tb[NDA_IFINDEX]); +- +- if (tb[NDA_MASTER]) ++ } ++ if (tb[NDA_MASTER]) { ++ if (nla_len(tb[NDA_MASTER]) != sizeof(u32)) ++ return -EINVAL; + filter_master_idx = nla_get_u32(tb[NDA_MASTER]); +- ++ } + if (filter_idx || filter_master_idx) + flags |= NLM_F_DUMP_FILTERED; + } +diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c +index 6abc5012200b..e26df2764e83 100644 +--- a/net/dns_resolver/dns_key.c ++++ b/net/dns_resolver/dns_key.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -91,9 +92,9 @@ dns_resolver_preparse(struct key_preparsed_payload *prep) + + next_opt = memchr(opt, '#', end - opt) ?: end; + opt_len = next_opt - opt; +- if (!opt_len) { +- printk(KERN_WARNING +- "Empty option to dns_resolver key\n"); ++ if (opt_len <= 0 || opt_len > 128) { ++ pr_warn_ratelimited("Invalid option length (%d) for dns_resolver key\n", ++ opt_len); + return -EINVAL; + } + +@@ -127,10 +128,8 @@ dns_resolver_preparse(struct key_preparsed_payload *prep) + } + + bad_option_value: +- printk(KERN_WARNING +- "Option '%*.*s' to dns_resolver key:" +- " bad/missing value\n", +- opt_nlen, opt_nlen, opt); ++ pr_warn_ratelimited("Option '%*.*s' to dns_resolver key: bad/missing value\n", ++ opt_nlen, opt_nlen, opt); + return -EINVAL; + } while (opt = next_opt + 1, opt < end); + } +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 23d77ff1da59..82d2b55c953a 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2589,8 +2589,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level, + + #ifdef CONFIG_TCP_MD5SIG + case TCP_MD5SIG: +- /* Read the IP->Key mappings from userspace */ +- err = tp->af_specific->md5_parse(sk, optval, optlen); ++ if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ++ err = tp->af_specific->md5_parse(sk, optval, optlen); ++ else ++ err = -EINVAL; + break; + #endif + case TCP_USER_TIMEOUT: +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 96115d1e0d90..ed018760502e 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -3869,11 +3869,8 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th) + int length = (th->doff << 2) - sizeof(*th); + const u8 *ptr = (const u8 *)(th + 1); + +- /* If the TCP option is too short, we can short cut */ +- if (length < TCPOLEN_MD5SIG) +- return NULL; +- +- while (length > 0) { ++ /* If not enough data remaining, we can short cut */ ++ while (length >= TCPOLEN_MD5SIG) { + int opcode = *ptr++; + int opsize; + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 99920fcea97c..2f6d8f57fdd4 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -2711,6 +2711,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned int mtu) + + static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { + [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, ++ [RTA_PREFSRC] = { .len = sizeof(struct in6_addr) }, + [RTA_OIF] = { .type = NLA_U32 }, + [RTA_IIF] = { .type = NLA_U32 }, + [RTA_PRIORITY] = { .type = NLA_U32 }, +@@ -2711,6 +2711,7 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { + [RTA_PREF] = { .type = NLA_U8 }, + [RTA_ENCAP_TYPE] = { .type = NLA_U16 }, + [RTA_ENCAP] = { .type = NLA_NESTED }, ++ [RTA_TABLE] = { .type = NLA_U32 }, + [RTA_UID] = { .type = NLA_U32 }, + }; + + static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index 67f2e72723b2..2764c4bd072c 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -606,6 +606,13 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, + lock_sock(sk); + + error = -EINVAL; ++ ++ if (sockaddr_len != sizeof(struct sockaddr_pppol2tp) && ++ sockaddr_len != sizeof(struct sockaddr_pppol2tpv3) && ++ sockaddr_len != sizeof(struct sockaddr_pppol2tpin6) && ++ sockaddr_len != sizeof(struct sockaddr_pppol2tpv3in6)) ++ goto end; ++ + if (sp->sa_protocol != PX_PROTO_OL2TP) + goto end; + +diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c +index 1e698768aca8..09f2f3471ad6 100644 +--- a/net/llc/af_llc.c ++++ b/net/llc/af_llc.c +@@ -197,9 +197,19 @@ static int llc_ui_release(struct socket *sock) + llc->laddr.lsap, llc->daddr.lsap); + if (!llc_send_disc(sk)) + llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo); +- if (!sock_flag(sk, SOCK_ZAPPED)) ++ if (!sock_flag(sk, SOCK_ZAPPED)) { ++ struct llc_sap *sap = llc->sap; ++ ++ /* Hold this for release_sock(), so that llc_backlog_rcv() ++ * could still use it. ++ */ ++ llc_sap_hold(sap); + llc_sap_remove_socket(llc->sap, sk); +- release_sock(sk); ++ release_sock(sk); ++ llc_sap_put(sap); ++ } else { ++ release_sock(sk); ++ } + if (llc->dev) + dev_put(llc->dev); + sock_put(sk); +diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c +index ea225bd2672c..f8d4ab8ca1a5 100644 +--- a/net/llc/llc_c_ac.c ++++ b/net/llc/llc_c_ac.c +@@ -1096,14 +1096,7 @@ int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb) + + int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb) + { +- struct llc_sock *llc = llc_sk(sk); +- +- del_timer(&llc->pf_cycle_timer.timer); +- del_timer(&llc->ack_timer.timer); +- del_timer(&llc->rej_sent_timer.timer); +- del_timer(&llc->busy_state_timer.timer); +- llc->ack_must_be_send = 0; +- llc->ack_pf = 0; ++ llc_sk_stop_all_timers(sk, false); + return 0; + } + +diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c +index 8bc5a1bd2d45..d861b74ad068 100644 +--- a/net/llc/llc_conn.c ++++ b/net/llc/llc_conn.c +@@ -951,6 +951,26 @@ out: + return sk; + } + ++void llc_sk_stop_all_timers(struct sock *sk, bool sync) ++{ ++ struct llc_sock *llc = llc_sk(sk); ++ ++ if (sync) { ++ del_timer_sync(&llc->pf_cycle_timer.timer); ++ del_timer_sync(&llc->ack_timer.timer); ++ del_timer_sync(&llc->rej_sent_timer.timer); ++ del_timer_sync(&llc->busy_state_timer.timer); ++ } else { ++ del_timer(&llc->pf_cycle_timer.timer); ++ del_timer(&llc->ack_timer.timer); ++ del_timer(&llc->rej_sent_timer.timer); ++ del_timer(&llc->busy_state_timer.timer); ++ } ++ ++ llc->ack_must_be_send = 0; ++ llc->ack_pf = 0; ++} ++ + /** + * llc_sk_free - Frees a LLC socket + * @sk - socket to free +@@ -963,7 +983,7 @@ void llc_sk_free(struct sock *sk) + + llc->state = LLC_CONN_OUT_OF_SVC; + /* Stop all (possibly) running timers */ +- llc_conn_ac_stop_all_timers(sk, NULL); ++ llc_sk_stop_all_timers(sk, true); + #ifdef DEBUG_LLC_CONN_ALLOC + printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __func__, + skb_queue_len(&llc->pdu_unack_q), +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 92ca3e106c2b..f165514a4db5 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -332,11 +332,11 @@ static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb) + skb_set_queue_mapping(skb, queue_index); + } + +-/* register_prot_hook must be invoked with the po->bind_lock held, ++/* __register_prot_hook must be invoked through register_prot_hook + * or from a context in which asynchronous accesses to the packet + * socket is not possible (packet_create()). + */ +-static void register_prot_hook(struct sock *sk) ++static void __register_prot_hook(struct sock *sk) + { + struct packet_sock *po = pkt_sk(sk); + +@@ -351,8 +351,13 @@ static void register_prot_hook(struct sock *sk) + } + } + +-/* {,__}unregister_prot_hook() must be invoked with the po->bind_lock +- * held. If the sync parameter is true, we will temporarily drop ++static void register_prot_hook(struct sock *sk) ++{ ++ lockdep_assert_held_once(&pkt_sk(sk)->bind_lock); ++ __register_prot_hook(sk); ++} ++ ++/* If the sync parameter is true, we will temporarily drop + * the po->bind_lock and do a synchronize_net to make sure no + * asynchronous packet processing paths still refer to the elements + * of po->prot_hook. If the sync parameter is false, it is the +@@ -362,6 +367,8 @@ static void __unregister_prot_hook(struct sock *sk, bool sync) + { + struct packet_sock *po = pkt_sk(sk); + ++ lockdep_assert_held_once(&po->bind_lock); ++ + po->running = 0; + + if (po->fanout) +@@ -2892,6 +2899,7 @@ static int packet_release(struct socket *sock) + + packet_flush_mclist(sk); + ++ lock_sock(sk); + if (po->rx_ring.pg_vec) { + memset(&req_u, 0, sizeof(req_u)); + packet_set_ring(sk, &req_u, 1, 0); +@@ -2901,6 +2909,7 @@ static int packet_release(struct socket *sock) + memset(&req_u, 0, sizeof(req_u)); + packet_set_ring(sk, &req_u, 1, 1); + } ++ release_sock(sk); + + f = fanout_release(sk); + +@@ -3134,7 +3143,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, + + if (proto) { + po->prot_hook.type = proto; +- register_prot_hook(sk); ++ __register_prot_hook(sk); + } + + mutex_lock(&net->packet.sklist_lock); +@@ -3570,6 +3579,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + union tpacket_req_u req_u; + int len; + ++ lock_sock(sk); + switch (po->tp_version) { + case TPACKET_V1: + case TPACKET_V2: +@@ -3580,14 +3590,21 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + len = sizeof(req_u.req3); + break; + } +- if (optlen < len) +- return -EINVAL; +- if (pkt_sk(sk)->has_vnet_hdr) +- return -EINVAL; +- if (copy_from_user(&req_u.req, optval, len)) +- return -EFAULT; +- return packet_set_ring(sk, &req_u, 0, +- optname == PACKET_TX_RING); ++ if (optlen < len) { ++ ret = -EINVAL; ++ } else { ++ if (pkt_sk(sk)->has_vnet_hdr) { ++ ret = -EINVAL; ++ } else { ++ if (copy_from_user(&req_u.req, optval, len)) ++ ret = -EFAULT; ++ else ++ ret = packet_set_ring(sk, &req_u, 0, ++ optname == PACKET_TX_RING); ++ } ++ } ++ release_sock(sk); ++ return ret; + } + case PACKET_COPY_THRESH: + { +@@ -3653,12 +3670,18 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + + if (optlen != sizeof(val)) + return -EINVAL; +- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) +- return -EBUSY; + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; +- po->tp_loss = !!val; +- return 0; ++ ++ lock_sock(sk); ++ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { ++ ret = -EBUSY; ++ } else { ++ po->tp_loss = !!val; ++ ret = 0; ++ } ++ release_sock(sk); ++ return ret; + } + case PACKET_AUXDATA: + { +@@ -3669,7 +3692,9 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; + ++ lock_sock(sk); + po->auxdata = !!val; ++ release_sock(sk); + return 0; + } + case PACKET_ORIGDEV: +@@ -3681,7 +3706,9 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; + ++ lock_sock(sk); + po->origdev = !!val; ++ release_sock(sk); + return 0; + } + case PACKET_VNET_HDR: +@@ -3690,15 +3717,20 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + + if (sock->type != SOCK_RAW) + return -EINVAL; +- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) +- return -EBUSY; + if (optlen < sizeof(val)) + return -EINVAL; + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; + +- po->has_vnet_hdr = !!val; +- return 0; ++ lock_sock(sk); ++ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { ++ ret = -EBUSY; ++ } else { ++ po->has_vnet_hdr = !!val; ++ ret = 0; ++ } ++ release_sock(sk); ++ return ret; + } + case PACKET_TIMESTAMP: + { +@@ -3736,11 +3768,17 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + + if (optlen != sizeof(val)) + return -EINVAL; +- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) +- return -EBUSY; + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; +- po->tp_tx_has_off = !!val; ++ ++ lock_sock(sk); ++ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { ++ ret = -EBUSY; ++ } else { ++ po->tp_tx_has_off = !!val; ++ ret = 0; ++ } ++ release_sock(sk); + return 0; + } + case PACKET_QDISC_BYPASS: +@@ -4116,7 +4154,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + /* Added to avoid minimal code churn */ + struct tpacket_req *req = &req_u->req; + +- lock_sock(sk); + /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ + if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { + WARN(1, "Tx-ring is not supported.\n"); +@@ -4252,7 +4289,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + if (pg_vec) + free_pg_vec(pg_vec, order, req->tp_block_nr); + out: +- release_sock(sk); + return err; + } + +diff --git a/net/packet/internal.h b/net/packet/internal.h +index d55bfc34d6b3..1309e2a7baad 100644 +--- a/net/packet/internal.h ++++ b/net/packet/internal.h +@@ -109,10 +109,12 @@ struct packet_sock { + int copy_thresh; + spinlock_t bind_lock; + struct mutex pg_vec_lock; +- unsigned int running:1, /* prot_hook is attached*/ +- auxdata:1, ++ unsigned int running; /* bind_lock must be held */ ++ unsigned int auxdata:1, /* writer must hold sock lock */ + origdev:1, +- has_vnet_hdr:1; ++ has_vnet_hdr:1, ++ tp_loss:1, ++ tp_tx_has_off:1; + int pressure; + int ifindex; /* bound device */ + __be16 num; +@@ -122,8 +124,6 @@ struct packet_sock { + enum tpacket_versions tp_version; + unsigned int tp_hdrlen; + unsigned int tp_reserve; +- unsigned int tp_loss:1; +- unsigned int tp_tx_has_off:1; + unsigned int tp_tstamp; + struct net_device __rcu *cached_dev; + int (*xmit)(struct sk_buff *skb); +diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c +index edb8514b4e00..1cd7b7e33fa3 100644 +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -519,46 +519,49 @@ static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr, + addr->v6.sin6_scope_id = 0; + } + +-/* Compare addresses exactly. +- * v4-mapped-v6 is also in consideration. +- */ +-static int sctp_v6_cmp_addr(const union sctp_addr *addr1, +- const union sctp_addr *addr2) ++static int __sctp_v6_cmp_addr(const union sctp_addr *addr1, ++ const union sctp_addr *addr2) + { + if (addr1->sa.sa_family != addr2->sa.sa_family) { + if (addr1->sa.sa_family == AF_INET && + addr2->sa.sa_family == AF_INET6 && +- ipv6_addr_v4mapped(&addr2->v6.sin6_addr)) { +- if (addr2->v6.sin6_port == addr1->v4.sin_port && +- addr2->v6.sin6_addr.s6_addr32[3] == +- addr1->v4.sin_addr.s_addr) +- return 1; +- } ++ ipv6_addr_v4mapped(&addr2->v6.sin6_addr) && ++ addr2->v6.sin6_addr.s6_addr32[3] == ++ addr1->v4.sin_addr.s_addr) ++ return 1; ++ + if (addr2->sa.sa_family == AF_INET && + addr1->sa.sa_family == AF_INET6 && +- ipv6_addr_v4mapped(&addr1->v6.sin6_addr)) { +- if (addr1->v6.sin6_port == addr2->v4.sin_port && +- addr1->v6.sin6_addr.s6_addr32[3] == +- addr2->v4.sin_addr.s_addr) +- return 1; +- } ++ ipv6_addr_v4mapped(&addr1->v6.sin6_addr) && ++ addr1->v6.sin6_addr.s6_addr32[3] == ++ addr2->v4.sin_addr.s_addr) ++ return 1; ++ + return 0; + } +- if (addr1->v6.sin6_port != addr2->v6.sin6_port) +- return 0; ++ + if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr)) + return 0; ++ + /* If this is a linklocal address, compare the scope_id. */ +- if (ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) { +- if (addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id && +- (addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)) { +- return 0; +- } +- } ++ if ((ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) && ++ addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id && ++ addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id) ++ return 0; + + return 1; + } + ++/* Compare addresses exactly. ++ * v4-mapped-v6 is also in consideration. ++ */ ++static int sctp_v6_cmp_addr(const union sctp_addr *addr1, ++ const union sctp_addr *addr2) ++{ ++ return __sctp_v6_cmp_addr(addr1, addr2) && ++ addr1->v6.sin6_port == addr2->v6.sin6_port; ++} ++ + /* Initialize addr struct to INADDR_ANY. */ + static void sctp_v6_inaddr_any(union sctp_addr *addr, __be16 port) + { +@@ -843,8 +846,8 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1, + const union sctp_addr *addr2, + struct sctp_sock *opt) + { +- struct sctp_af *af1, *af2; + struct sock *sk = sctp_opt2sk(opt); ++ struct sctp_af *af1, *af2; + + af1 = sctp_get_af_specific(addr1->sa.sa_family); + af2 = sctp_get_af_specific(addr2->sa.sa_family); +@@ -860,10 +863,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1, + if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2)) + return 1; + +- if (addr1->sa.sa_family != addr2->sa.sa_family) +- return 0; +- +- return af1->cmp_addr(addr1, addr2); ++ return __sctp_v6_cmp_addr(addr1, addr2); + } + + /* Verify that the provided sockaddr looks bindable. Common verification, +diff --git a/net/tipc/net.c b/net/tipc/net.c +index 77bf9113c7a7..2763bd369b79 100644 +--- a/net/tipc/net.c ++++ b/net/tipc/net.c +@@ -44,7 +44,8 @@ + + static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { + [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, +- [TIPC_NLA_NET_ID] = { .type = NLA_U32 } ++ [TIPC_NLA_NET_ID] = { .type = NLA_U32 }, ++ [TIPC_NLA_NET_ADDR] = { .type = NLA_U32 }, + }; + + /* diff --git a/patch/kernel/rk3328-default/04-patch-4.4.130-131.patch b/patch/kernel/rk3328-default/04-patch-4.4.130-131.patch new file mode 100644 index 000000000..0a4d3770d --- /dev/null +++ b/patch/kernel/rk3328-default/04-patch-4.4.130-131.patch @@ -0,0 +1,1558 @@ +diff --git a/Makefile b/Makefile +index 151477d4d5e5..6ec65396a56d 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 130 ++SUBLEVEL = 131 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/x86/include/uapi/asm/msgbuf.h b/arch/x86/include/uapi/asm/msgbuf.h +index 809134c644a6..90ab9a795b49 100644 +--- a/arch/x86/include/uapi/asm/msgbuf.h ++++ b/arch/x86/include/uapi/asm/msgbuf.h +@@ -1 +1,32 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef __ASM_X64_MSGBUF_H ++#define __ASM_X64_MSGBUF_H ++ ++#if !defined(__x86_64__) || !defined(__ILP32__) + #include ++#else ++/* ++ * The msqid64_ds structure for x86 architecture with x32 ABI. ++ * ++ * On x86-32 and x86-64 we can just use the generic definition, but ++ * x32 uses the same binary layout as x86_64, which is differnet ++ * from other 32-bit architectures. ++ */ ++ ++struct msqid64_ds { ++ struct ipc64_perm msg_perm; ++ __kernel_time_t msg_stime; /* last msgsnd time */ ++ __kernel_time_t msg_rtime; /* last msgrcv time */ ++ __kernel_time_t msg_ctime; /* last change time */ ++ __kernel_ulong_t msg_cbytes; /* current number of bytes on queue */ ++ __kernel_ulong_t msg_qnum; /* number of messages in queue */ ++ __kernel_ulong_t msg_qbytes; /* max number of bytes on queue */ ++ __kernel_pid_t msg_lspid; /* pid of last msgsnd */ ++ __kernel_pid_t msg_lrpid; /* last receive pid */ ++ __kernel_ulong_t __unused4; ++ __kernel_ulong_t __unused5; ++}; ++ ++#endif ++ ++#endif /* __ASM_GENERIC_MSGBUF_H */ +diff --git a/arch/x86/include/uapi/asm/shmbuf.h b/arch/x86/include/uapi/asm/shmbuf.h +index 83c05fc2de38..644421f3823b 100644 +--- a/arch/x86/include/uapi/asm/shmbuf.h ++++ b/arch/x86/include/uapi/asm/shmbuf.h +@@ -1 +1,43 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef __ASM_X86_SHMBUF_H ++#define __ASM_X86_SHMBUF_H ++ ++#if !defined(__x86_64__) || !defined(__ILP32__) + #include ++#else ++/* ++ * The shmid64_ds structure for x86 architecture with x32 ABI. ++ * ++ * On x86-32 and x86-64 we can just use the generic definition, but ++ * x32 uses the same binary layout as x86_64, which is differnet ++ * from other 32-bit architectures. ++ */ ++ ++struct shmid64_ds { ++ struct ipc64_perm shm_perm; /* operation perms */ ++ size_t shm_segsz; /* size of segment (bytes) */ ++ __kernel_time_t shm_atime; /* last attach time */ ++ __kernel_time_t shm_dtime; /* last detach time */ ++ __kernel_time_t shm_ctime; /* last change time */ ++ __kernel_pid_t shm_cpid; /* pid of creator */ ++ __kernel_pid_t shm_lpid; /* pid of last operator */ ++ __kernel_ulong_t shm_nattch; /* no. of current attaches */ ++ __kernel_ulong_t __unused4; ++ __kernel_ulong_t __unused5; ++}; ++ ++struct shminfo64 { ++ __kernel_ulong_t shmmax; ++ __kernel_ulong_t shmmin; ++ __kernel_ulong_t shmmni; ++ __kernel_ulong_t shmseg; ++ __kernel_ulong_t shmall; ++ __kernel_ulong_t __unused1; ++ __kernel_ulong_t __unused2; ++ __kernel_ulong_t __unused3; ++ __kernel_ulong_t __unused4; ++}; ++ ++#endif ++ ++#endif /* __ASM_X86_SHMBUF_H */ +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index fe89f938e0f0..00c7878043ef 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -1442,6 +1442,8 @@ static inline void mwait_play_dead(void) + void *mwait_ptr; + int i; + ++ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) ++ return; + if (!this_cpu_has(X86_FEATURE_MWAIT)) + return; + if (!this_cpu_has(X86_FEATURE_CLFLUSH)) +diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c +index f0099360039e..1accc01fb0ca 100644 +--- a/drivers/amba/bus.c ++++ b/drivers/amba/bus.c +@@ -68,11 +68,12 @@ static ssize_t driver_override_show(struct device *_dev, + struct device_attribute *attr, char *buf) + { + struct amba_device *dev = to_amba_device(_dev); ++ ssize_t len; + +- if (!dev->driver_override) +- return 0; +- +- return sprintf(buf, "%s\n", dev->driver_override); ++ device_lock(_dev); ++ len = sprintf(buf, "%s\n", dev->driver_override); ++ device_unlock(_dev); ++ return len; + } + + static ssize_t driver_override_store(struct device *_dev, +@@ -80,9 +81,10 @@ static ssize_t driver_override_store(struct device *_dev, + const char *buf, size_t count) + { + struct amba_device *dev = to_amba_device(_dev); +- char *driver_override, *old = dev->driver_override, *cp; ++ char *driver_override, *old, *cp; + +- if (count > PATH_MAX) ++ /* We need to keep extra room for a newline */ ++ if (count >= (PAGE_SIZE - 1)) + return -EINVAL; + + driver_override = kstrndup(buf, count, GFP_KERNEL); +@@ -93,12 +95,15 @@ static ssize_t driver_override_store(struct device *_dev, + if (cp) + *cp = '\0'; + ++ device_lock(_dev); ++ old = dev->driver_override; + if (strlen(driver_override)) { + dev->driver_override = driver_override; + } else { + kfree(driver_override); + dev->driver_override = NULL; + } ++ device_unlock(_dev); + + kfree(old); + +diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c +index be0b09a0fb44..2aca689061e1 100644 +--- a/drivers/char/virtio_console.c ++++ b/drivers/char/virtio_console.c +@@ -1399,7 +1399,6 @@ static int add_port(struct ports_device *portdev, u32 id) + { + char debugfs_name[16]; + struct port *port; +- struct port_buffer *buf; + dev_t devt; + unsigned int nr_added_bufs; + int err; +@@ -1510,8 +1509,6 @@ static int add_port(struct ports_device *portdev, u32 id) + return 0; + + free_inbufs: +- while ((buf = virtqueue_detach_unused_buf(port->in_vq))) +- free_buf(buf, true); + free_device: + device_destroy(pdrvdata.class, port->dev->devt); + free_cdev: +@@ -1536,34 +1533,14 @@ static void remove_port(struct kref *kref) + + static void remove_port_data(struct port *port) + { +- struct port_buffer *buf; +- + spin_lock_irq(&port->inbuf_lock); + /* Remove unused data this port might have received. */ + discard_port_data(port); + spin_unlock_irq(&port->inbuf_lock); + +- /* Remove buffers we queued up for the Host to send us data in. */ +- do { +- spin_lock_irq(&port->inbuf_lock); +- buf = virtqueue_detach_unused_buf(port->in_vq); +- spin_unlock_irq(&port->inbuf_lock); +- if (buf) +- free_buf(buf, true); +- } while (buf); +- + spin_lock_irq(&port->outvq_lock); + reclaim_consumed_buffers(port); + spin_unlock_irq(&port->outvq_lock); +- +- /* Free pending buffers from the out-queue. */ +- do { +- spin_lock_irq(&port->outvq_lock); +- buf = virtqueue_detach_unused_buf(port->out_vq); +- spin_unlock_irq(&port->outvq_lock); +- if (buf) +- free_buf(buf, true); +- } while (buf); + } + + /* +@@ -1788,13 +1765,24 @@ static void control_work_handler(struct work_struct *work) + spin_unlock(&portdev->c_ivq_lock); + } + ++static void flush_bufs(struct virtqueue *vq, bool can_sleep) ++{ ++ struct port_buffer *buf; ++ unsigned int len; ++ ++ while ((buf = virtqueue_get_buf(vq, &len))) ++ free_buf(buf, can_sleep); ++} ++ + static void out_intr(struct virtqueue *vq) + { + struct port *port; + + port = find_port_by_vq(vq->vdev->priv, vq); +- if (!port) ++ if (!port) { ++ flush_bufs(vq, false); + return; ++ } + + wake_up_interruptible(&port->waitqueue); + } +@@ -1805,8 +1793,10 @@ static void in_intr(struct virtqueue *vq) + unsigned long flags; + + port = find_port_by_vq(vq->vdev->priv, vq); +- if (!port) ++ if (!port) { ++ flush_bufs(vq, false); + return; ++ } + + spin_lock_irqsave(&port->inbuf_lock, flags); + port->inbuf = get_inbuf(port); +@@ -1981,6 +1971,15 @@ static const struct file_operations portdev_fops = { + + static void remove_vqs(struct ports_device *portdev) + { ++ struct virtqueue *vq; ++ ++ virtio_device_for_each_vq(portdev->vdev, vq) { ++ struct port_buffer *buf; ++ ++ flush_bufs(vq, true); ++ while ((buf = virtqueue_detach_unused_buf(vq))) ++ free_buf(buf, true); ++ } + portdev->vdev->config->del_vqs(portdev->vdev); + kfree(portdev->in_vqs); + kfree(portdev->out_vqs); +diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c +index 5a0f8a745b9d..52436b3c01bb 100644 +--- a/drivers/gpu/drm/virtio/virtgpu_vq.c ++++ b/drivers/gpu/drm/virtio/virtgpu_vq.c +@@ -324,7 +324,7 @@ retry: + ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC); + if (ret == -ENOSPC) { + spin_unlock(&vgdev->ctrlq.qlock); +- wait_event(vgdev->ctrlq.ack_queue, vq->num_free); ++ wait_event(vgdev->ctrlq.ack_queue, vq->num_free >= outcnt + incnt); + spin_lock(&vgdev->ctrlq.qlock); + goto retry; + } else { +@@ -399,7 +399,7 @@ retry: + ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC); + if (ret == -ENOSPC) { + spin_unlock(&vgdev->cursorq.qlock); +- wait_event(vgdev->cursorq.ack_queue, vq->num_free); ++ wait_event(vgdev->cursorq.ack_queue, vq->num_free >= outcnt); + spin_lock(&vgdev->cursorq.qlock); + goto retry; + } else { +diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c +index 286b97a304cf..4509ee0b294a 100644 +--- a/drivers/mtd/chips/cfi_cmdset_0001.c ++++ b/drivers/mtd/chips/cfi_cmdset_0001.c +@@ -45,6 +45,7 @@ + #define I82802AB 0x00ad + #define I82802AC 0x00ac + #define PF38F4476 0x881c ++#define M28F00AP30 0x8963 + /* STMicroelectronics chips */ + #define M50LPW080 0x002F + #define M50FLW080A 0x0080 +@@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi, + extp->MinorVersion = '1'; + } + ++static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip) ++{ ++ /* ++ * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t ++ * Erase Supend for their small Erase Blocks(0x8000) ++ */ ++ if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30) ++ return 1; ++ return 0; ++} ++ + static inline struct cfi_pri_intelext * + read_pri_intelext(struct map_info *map, __u16 adr) + { +@@ -825,21 +837,30 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long + (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1)))) + goto sleep; + ++ /* Do not allow suspend iff read/write to EB address */ ++ if ((adr & chip->in_progress_block_mask) == ++ chip->in_progress_block_addr) ++ goto sleep; ++ ++ /* do not suspend small EBs, buggy Micron Chips */ ++ if (cfi_is_micron_28F00AP30(cfi, chip) && ++ (chip->in_progress_block_mask == ~(0x8000-1))) ++ goto sleep; + + /* Erase suspend */ +- map_write(map, CMD(0xB0), adr); ++ map_write(map, CMD(0xB0), chip->in_progress_block_addr); + + /* If the flash has finished erasing, then 'erase suspend' + * appears to make some (28F320) flash devices switch to + * 'read' mode. Make sure that we switch to 'read status' + * mode so we get the right data. --rmk + */ +- map_write(map, CMD(0x70), adr); ++ map_write(map, CMD(0x70), chip->in_progress_block_addr); + chip->oldstate = FL_ERASING; + chip->state = FL_ERASE_SUSPENDING; + chip->erase_suspended = 1; + for (;;) { +- status = map_read(map, adr); ++ status = map_read(map, chip->in_progress_block_addr); + if (map_word_andequal(map, status, status_OK, status_OK)) + break; + +@@ -1035,8 +1056,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad + sending the 0x70 (Read Status) command to an erasing + chip and expecting it to be ignored, that's what we + do. */ +- map_write(map, CMD(0xd0), adr); +- map_write(map, CMD(0x70), adr); ++ map_write(map, CMD(0xd0), chip->in_progress_block_addr); ++ map_write(map, CMD(0x70), chip->in_progress_block_addr); + chip->oldstate = FL_READY; + chip->state = FL_ERASING; + break; +@@ -1927,6 +1948,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, + map_write(map, CMD(0xD0), adr); + chip->state = FL_ERASING; + chip->erase_suspended = 0; ++ chip->in_progress_block_addr = adr; ++ chip->in_progress_block_mask = ~(len - 1); + + ret = INVAL_CACHE_AND_WAIT(map, chip, adr, + adr, len, +diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c +index c3624eb571d1..31448a2b39ae 100644 +--- a/drivers/mtd/chips/cfi_cmdset_0002.c ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c +@@ -814,9 +814,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr + (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) + goto sleep; + +- /* We could check to see if we're trying to access the sector +- * that is currently being erased. However, no user will try +- * anything like that so we just wait for the timeout. */ ++ /* Do not allow suspend iff read/write to EB address */ ++ if ((adr & chip->in_progress_block_mask) == ++ chip->in_progress_block_addr) ++ goto sleep; + + /* Erase suspend */ + /* It's harmless to issue the Erase-Suspend and Erase-Resume +@@ -2265,6 +2266,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) + chip->state = FL_ERASING; + chip->erase_suspended = 0; + chip->in_progress_block_addr = adr; ++ chip->in_progress_block_mask = ~(map->size - 1); + + INVALIDATE_CACHE_UDELAY(map, chip, + adr, map->size, +@@ -2354,6 +2356,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, + chip->state = FL_ERASING; + chip->erase_suspended = 0; + chip->in_progress_block_addr = adr; ++ chip->in_progress_block_mask = ~(len - 1); + + INVALIDATE_CACHE_UDELAY(map, chip, + adr, len, +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index dd72205ba298..8c9e4a3ec3fb 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -1929,6 +1929,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) + break; /* standby */ + if (sshdr.asc == 4 && sshdr.ascq == 0xc) + break; /* unavailable */ ++ if (sshdr.asc == 4 && sshdr.ascq == 0x1b) ++ break; /* sanitize in progress */ + /* + * Issue command to spin up drive when not ready + */ +diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c +index 78bd121ecede..6060c3e8925e 100644 +--- a/drivers/tty/n_gsm.c ++++ b/drivers/tty/n_gsm.c +@@ -137,6 +137,9 @@ struct gsm_dlci { + struct mutex mutex; + + /* Link layer */ ++ int mode; ++#define DLCI_MODE_ABM 0 /* Normal Asynchronous Balanced Mode */ ++#define DLCI_MODE_ADM 1 /* Asynchronous Disconnected Mode */ + spinlock_t lock; /* Protects the internal state */ + struct timer_list t1; /* Retransmit timer for SABM and UA */ + int retries; +@@ -1380,7 +1383,13 @@ retry: + ctrl->data = data; + ctrl->len = clen; + gsm->pending_cmd = ctrl; +- gsm->cretries = gsm->n2; ++ ++ /* If DLCI0 is in ADM mode skip retries, it won't respond */ ++ if (gsm->dlci[0]->mode == DLCI_MODE_ADM) ++ gsm->cretries = 1; ++ else ++ gsm->cretries = gsm->n2; ++ + mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100); + gsm_control_transmit(gsm, ctrl); + spin_unlock_irqrestore(&gsm->control_lock, flags); +@@ -1488,6 +1497,7 @@ static void gsm_dlci_t1(unsigned long data) + if (debug & 8) + pr_info("DLCI %d opening in ADM mode.\n", + dlci->addr); ++ dlci->mode = DLCI_MODE_ADM; + gsm_dlci_open(dlci); + } else { + gsm_dlci_close(dlci); +@@ -2881,11 +2891,22 @@ static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk) + static int gsm_carrier_raised(struct tty_port *port) + { + struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port); ++ struct gsm_mux *gsm = dlci->gsm; ++ + /* Not yet open so no carrier info */ + if (dlci->state != DLCI_OPEN) + return 0; + if (debug & 2) + return 1; ++ ++ /* ++ * Basic mode with control channel in ADM mode may not respond ++ * to CMD_MSC at all and modem_rx is empty. ++ */ ++ if (gsm->encoding == 0 && gsm->dlci[0]->mode == DLCI_MODE_ADM && ++ !dlci->modem_rx) ++ return 1; ++ + return dlci->modem_rx & TIOCM_CD; + } + +diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c +index 3eb57eb532f1..02147361eaa9 100644 +--- a/drivers/tty/serial/serial_mctrl_gpio.c ++++ b/drivers/tty/serial/serial_mctrl_gpio.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #include "serial_mctrl_gpio.h" + +@@ -193,6 +194,7 @@ struct mctrl_gpios *mctrl_gpio_init(struct uart_port *port, unsigned int idx) + + return gpios; + } ++EXPORT_SYMBOL_GPL(mctrl_gpio_init); + + void mctrl_gpio_free(struct device *dev, struct mctrl_gpios *gpios) + { +@@ -247,3 +249,6 @@ void mctrl_gpio_disable_ms(struct mctrl_gpios *gpios) + disable_irq(gpios->irq[i]); + } + } ++EXPORT_SYMBOL_GPL(mctrl_gpio_disable_ms); ++ ++MODULE_LICENSE("GPL"); +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index 89fd20382ce4..198451fa9e5d 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -3154,7 +3154,10 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) + + kref_init(&tty->kref); + tty->magic = TTY_MAGIC; +- tty_ldisc_init(tty); ++ if (tty_ldisc_init(tty)) { ++ kfree(tty); ++ return NULL; ++ } + tty->session = NULL; + tty->pgrp = NULL; + mutex_init(&tty->legacy_mutex); +diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c +index 9bee25cfa0be..d9e013dc2c08 100644 +--- a/drivers/tty/tty_ldisc.c ++++ b/drivers/tty/tty_ldisc.c +@@ -168,12 +168,11 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) + return ERR_CAST(ldops); + } + +- ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL); +- if (ld == NULL) { +- put_ldops(ldops); +- return ERR_PTR(-ENOMEM); +- } +- ++ /* ++ * There is no way to handle allocation failure of only 16 bytes. ++ * Let's simplify error handling and save more memory. ++ */ ++ ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL); + ld->ops = ldops; + ld->tty = tty; + +@@ -804,12 +803,13 @@ void tty_ldisc_release(struct tty_struct *tty) + * the tty structure is not completely set up when this call is made. + */ + +-void tty_ldisc_init(struct tty_struct *tty) ++int tty_ldisc_init(struct tty_struct *tty) + { + struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY); + if (IS_ERR(ld)) +- panic("n_tty: init_tty"); ++ return PTR_ERR(ld); + tty->ldisc = ld; ++ return 0; + } + + /** +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c +index 87a83d925eea..9c4f9b6e57e2 100644 +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -2339,6 +2339,7 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd) + + spin_lock_irqsave (&hcd_root_hub_lock, flags); + if (hcd->rh_registered) { ++ pm_wakeup_event(&hcd->self.root_hub->dev, 0); + set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); + queue_work(pm_wq, &hcd->wakeup_work); + } +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 0f38f577c047..6d84f6c8fbe6 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -632,12 +632,17 @@ void usb_wakeup_notification(struct usb_device *hdev, + unsigned int portnum) + { + struct usb_hub *hub; ++ struct usb_port *port_dev; + + if (!hdev) + return; + + hub = usb_hub_to_struct_hub(hdev); + if (hub) { ++ port_dev = hub->ports[portnum - 1]; ++ if (port_dev && port_dev->child) ++ pm_wakeup_event(&port_dev->child->dev, 0); ++ + set_bit(portnum, hub->wakeup_bits); + kick_hub_wq(hub); + } +@@ -3361,8 +3366,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) + + /* Skip the initial Clear-Suspend step for a remote wakeup */ + status = hub_port_status(hub, port1, &portstatus, &portchange); +- if (status == 0 && !port_is_suspended(hub, portstatus)) ++ if (status == 0 && !port_is_suspended(hub, portstatus)) { ++ if (portchange & USB_PORT_STAT_C_SUSPEND) ++ pm_wakeup_event(&udev->dev, 0); + goto SuspendCleared; ++ } + + /* see 7.1.7.7; affects power usage, but not budgeting */ + if (hub_is_superspeed(hub->hdev)) +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 4f1c6f8d4352..40ce175655e6 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -45,6 +45,9 @@ static const struct usb_device_id usb_quirk_list[] = { + { USB_DEVICE(0x03f0, 0x0701), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, + ++ /* HP v222w 16GB Mini USB Drive */ ++ { USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT }, ++ + /* Creative SB Audigy 2 NX */ + { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, + +diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig +index 584ae8cbaf1c..77c3ebe860c5 100644 +--- a/drivers/usb/serial/Kconfig ++++ b/drivers/usb/serial/Kconfig +@@ -62,6 +62,7 @@ config USB_SERIAL_SIMPLE + - Fundamental Software dongle. + - Google USB serial devices + - HP4x calculators ++ - Libtransistor USB console + - a number of Motorola phones + - Motorola Tetra devices + - Novatel Wireless GPS receivers +diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c +index 64a4427678b0..32cadca198b2 100644 +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -210,6 +210,7 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ + { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ + { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ ++ { USB_DEVICE(0x3923, 0x7A0B) }, /* National Instruments USB Serial Console */ + { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ + { } /* Terminating Entry */ + }; +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index a224c7a3ce09..3e5b189a79b4 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1911,7 +1911,8 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial) + return ftdi_jtag_probe(serial); + + if (udev->product && +- (!strcmp(udev->product, "BeagleBone/XDS100V2") || ++ (!strcmp(udev->product, "Arrow USB Blaster") || ++ !strcmp(udev->product, "BeagleBone/XDS100V2") || + !strcmp(udev->product, "SNAP Connect E10"))) + return ftdi_jtag_probe(serial); + +diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c +index 6aa7ff2c1cf7..2674da40d9cd 100644 +--- a/drivers/usb/serial/usb-serial-simple.c ++++ b/drivers/usb/serial/usb-serial-simple.c +@@ -66,6 +66,11 @@ DEVICE(flashloader, FLASHLOADER_IDS); + 0x01) } + DEVICE(google, GOOGLE_IDS); + ++/* Libtransistor USB console */ ++#define LIBTRANSISTOR_IDS() \ ++ { USB_DEVICE(0x1209, 0x8b00) } ++DEVICE(libtransistor, LIBTRANSISTOR_IDS); ++ + /* ViVOpay USB Serial Driver */ + #define VIVOPAY_IDS() \ + { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ +@@ -113,6 +118,7 @@ static struct usb_serial_driver * const serial_drivers[] = { + &funsoft_device, + &flashloader_device, + &google_device, ++ &libtransistor_device, + &vivopay_device, + &moto_modem_device, + &motorola_tetra_device, +@@ -129,6 +135,7 @@ static const struct usb_device_id id_table[] = { + FUNSOFT_IDS(), + FLASHLOADER_IDS(), + GOOGLE_IDS(), ++ LIBTRANSISTOR_IDS(), + VIVOPAY_IDS(), + MOTO_IDS(), + MOTOROLA_TETRA_IDS(), +diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c +index 325b4c05acdd..f761e02e75c9 100644 +--- a/drivers/usb/usbip/stub_main.c ++++ b/drivers/usb/usbip/stub_main.c +@@ -201,7 +201,12 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf, + if (!bid) + return -ENODEV; + ++ /* device_attach() callers should hold parent lock for USB */ ++ if (bid->udev->dev.parent) ++ device_lock(bid->udev->dev.parent); + ret = device_attach(&bid->udev->dev); ++ if (bid->udev->dev.parent) ++ device_unlock(bid->udev->dev.parent); + if (ret < 0) { + dev_err(&bid->udev->dev, "rebind failed\n"); + return ret; +diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h +index f875ccaa55f9..0fc5ace57c0e 100644 +--- a/drivers/usb/usbip/usbip_common.h ++++ b/drivers/usb/usbip/usbip_common.h +@@ -248,7 +248,7 @@ enum usbip_side { + #define SDEV_EVENT_ERROR_SUBMIT (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) + #define SDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) + +-#define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_BYE) ++#define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE) + #define VDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) + #define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) + #define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) +diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c +index 78c51ce913db..c57a94f1c198 100644 +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -320,6 +320,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb, + struct ext4_sb_info *sbi = EXT4_SB(sb); + ext4_grpblk_t offset; + ext4_grpblk_t next_zero_bit; ++ ext4_grpblk_t max_bit = EXT4_CLUSTERS_PER_GROUP(sb); + ext4_fsblk_t blk; + ext4_fsblk_t group_first_block; + +@@ -337,20 +338,25 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb, + /* check whether block bitmap block number is set */ + blk = ext4_block_bitmap(sb, desc); + offset = blk - group_first_block; +- if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) ++ if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit || ++ !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) + /* bad block bitmap */ + return blk; + + /* check whether the inode bitmap block number is set */ + blk = ext4_inode_bitmap(sb, desc); + offset = blk - group_first_block; +- if (!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) ++ if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit || ++ !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) + /* bad block bitmap */ + return blk; + + /* check whether the inode table block number is set */ + blk = ext4_inode_table(sb, desc); + offset = blk - group_first_block; ++ if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit || ++ EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= max_bit) ++ return blk; + next_zero_bit = ext4_find_next_zero_bit(bh->b_data, + EXT4_B2C(sbi, offset + EXT4_SB(sb)->s_itb_per_group), + EXT4_B2C(sbi, offset)); +@@ -416,6 +422,7 @@ struct buffer_head * + ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) + { + struct ext4_group_desc *desc; ++ struct ext4_sb_info *sbi = EXT4_SB(sb); + struct buffer_head *bh; + ext4_fsblk_t bitmap_blk; + int err; +@@ -424,6 +431,12 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) + if (!desc) + return ERR_PTR(-EFSCORRUPTED); + bitmap_blk = ext4_block_bitmap(sb, desc); ++ if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || ++ (bitmap_blk >= ext4_blocks_count(sbi->s_es))) { ++ ext4_error(sb, "Invalid block bitmap block %llu in " ++ "block_group %u", bitmap_blk, block_group); ++ return ERR_PTR(-EFSCORRUPTED); ++ } + bh = sb_getblk(sb, bitmap_blk); + if (unlikely(!bh)) { + ext4_error(sb, "Cannot get buffer for block bitmap - " +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index 403c4bae3e18..4705c21f9d03 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -5380,8 +5380,9 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, + stop = le32_to_cpu(extent->ee_block); + + /* +- * In case of left shift, Don't start shifting extents until we make +- * sure the hole is big enough to accommodate the shift. ++ * For left shifts, make sure the hole on the left is big enough to ++ * accommodate the shift. For right shifts, make sure the last extent ++ * won't be shifted beyond EXT_MAX_BLOCKS. + */ + if (SHIFT == SHIFT_LEFT) { + path = ext4_find_extent(inode, start - 1, &path, +@@ -5401,9 +5402,14 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, + + if ((start == ex_start && shift > ex_start) || + (shift > start - ex_end)) { +- ext4_ext_drop_refs(path); +- kfree(path); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out; ++ } ++ } else { ++ if (shift > EXT_MAX_BLOCKS - ++ (stop + ext4_ext_get_actual_len(extent))) { ++ ret = -EINVAL; ++ goto out; + } + } + +diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c +index e10c12f59c58..9fe55b7d4c2c 100644 +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -119,6 +119,7 @@ static struct buffer_head * + ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) + { + struct ext4_group_desc *desc; ++ struct ext4_sb_info *sbi = EXT4_SB(sb); + struct buffer_head *bh = NULL; + ext4_fsblk_t bitmap_blk; + int err; +@@ -128,6 +129,12 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) + return ERR_PTR(-EFSCORRUPTED); + + bitmap_blk = ext4_inode_bitmap(sb, desc); ++ if ((bitmap_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || ++ (bitmap_blk >= ext4_blocks_count(sbi->s_es))) { ++ ext4_error(sb, "Invalid inode bitmap blk %llu in " ++ "block_group %u", bitmap_blk, block_group); ++ return ERR_PTR(-EFSCORRUPTED); ++ } + bh = sb_getblk(sb, bitmap_blk); + if (unlikely(!bh)) { + ext4_error(sb, "Cannot read inode bitmap - " +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index a2e724053919..f3a31f55f372 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -527,6 +527,7 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type, + */ + ret = start_this_handle(journal, handle, GFP_NOFS); + if (ret < 0) { ++ handle->h_journal = journal; + jbd2_journal_free_reserved(handle); + return ret; + } +diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h +index b63fa457febd..3529683f691e 100644 +--- a/include/linux/mtd/flashchip.h ++++ b/include/linux/mtd/flashchip.h +@@ -85,6 +85,7 @@ struct flchip { + unsigned int write_suspended:1; + unsigned int erase_suspended:1; + unsigned long in_progress_block_addr; ++ unsigned long in_progress_block_mask; + + struct mutex mutex; + wait_queue_head_t wq; /* Wait on here when we're waiting for the chip +diff --git a/include/linux/tty.h b/include/linux/tty.h +index d67ceb3f5958..812cdd8cff22 100644 +--- a/include/linux/tty.h ++++ b/include/linux/tty.h +@@ -586,7 +586,7 @@ extern int tty_unregister_ldisc(int disc); + extern int tty_set_ldisc(struct tty_struct *tty, int ldisc); + extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty); + extern void tty_ldisc_release(struct tty_struct *tty); +-extern void tty_ldisc_init(struct tty_struct *tty); ++extern int __must_check tty_ldisc_init(struct tty_struct *tty); + extern void tty_ldisc_deinit(struct tty_struct *tty); + extern void tty_ldisc_begin(void); + +diff --git a/include/linux/virtio.h b/include/linux/virtio.h +index 8f4d4bfa6d46..d7844d215381 100644 +--- a/include/linux/virtio.h ++++ b/include/linux/virtio.h +@@ -124,6 +124,9 @@ int virtio_device_freeze(struct virtio_device *dev); + int virtio_device_restore(struct virtio_device *dev); + #endif + ++#define virtio_device_for_each_vq(vdev, vq) \ ++ list_for_each_entry(vq, &vdev->vqs, list) ++ + /** + * virtio_driver - operations for a virtio I/O driver + * @driver: underlying device driver (populate name and owner). +diff --git a/include/sound/control.h b/include/sound/control.h +index 21d047f229a1..4142757080f8 100644 +--- a/include/sound/control.h ++++ b/include/sound/control.h +@@ -22,6 +22,7 @@ + * + */ + ++#include + #include + + #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data) +@@ -147,12 +148,14 @@ int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type); + + static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) + { +- return id->numid - kctl->id.numid; ++ unsigned int ioff = id->numid - kctl->id.numid; ++ return array_index_nospec(ioff, kctl->count); + } + + static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) + { +- return id->index - kctl->id.index; ++ unsigned int ioff = id->index - kctl->id.index; ++ return array_index_nospec(ioff, kctl->count); + } + + static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id) +diff --git a/lib/kobject.c b/lib/kobject.c +index 7cbccd2b4c72..895edb63fba4 100644 +--- a/lib/kobject.c ++++ b/lib/kobject.c +@@ -234,14 +234,12 @@ static int kobject_add_internal(struct kobject *kobj) + + /* be noisy on error issues */ + if (error == -EEXIST) +- WARN(1, "%s failed for %s with " +- "-EEXIST, don't try to register things with " +- "the same name in the same directory.\n", +- __func__, kobject_name(kobj)); ++ pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n", ++ __func__, kobject_name(kobj)); + else +- WARN(1, "%s failed for %s (error: %d parent: %s)\n", +- __func__, kobject_name(kobj), error, +- parent ? kobject_name(parent) : "'none'"); ++ pr_err("%s failed for %s (error: %d parent: %s)\n", ++ __func__, kobject_name(kobj), error, ++ parent ? kobject_name(parent) : "'none'"); + } else + kobj->state_in_sysfs = 1; + +diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c +index a6b2f2138c9d..ad3c9e96a275 100644 +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -2531,6 +2531,11 @@ static int try_write(struct ceph_connection *con) + int ret = 1; + + dout("try_write start %p state %lu\n", con, con->state); ++ if (con->state != CON_STATE_PREOPEN && ++ con->state != CON_STATE_CONNECTING && ++ con->state != CON_STATE_NEGOTIATING && ++ con->state != CON_STATE_OPEN) ++ return 0; + + more: + dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes); +@@ -2556,6 +2561,8 @@ more: + } + + more_kvec: ++ BUG_ON(!con->sock); ++ + /* kvec data queued? */ + if (con->out_kvec_left) { + ret = write_partial_kvec(con); +diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c +index ce2954a31238..3de88974eeb6 100644 +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -2727,6 +2727,7 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream, + sync_ptr.s.status.hw_ptr = status->hw_ptr; + sync_ptr.s.status.tstamp = status->tstamp; + sync_ptr.s.status.suspended_state = status->suspended_state; ++ sync_ptr.s.status.audio_tstamp = status->audio_tstamp; + snd_pcm_stream_unlock_irq(substream); + if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr))) + return -EFAULT; +diff --git a/sound/core/seq/oss/seq_oss_event.c b/sound/core/seq/oss/seq_oss_event.c +index c3908862bc8b..86ca584c27b2 100644 +--- a/sound/core/seq/oss/seq_oss_event.c ++++ b/sound/core/seq/oss/seq_oss_event.c +@@ -26,6 +26,7 @@ + #include + #include "seq_oss_readq.h" + #include "seq_oss_writeq.h" ++#include + + + /* +@@ -287,10 +288,10 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st + { + struct seq_oss_synthinfo *info; + +- if (!snd_seq_oss_synth_is_valid(dp, dev)) ++ info = snd_seq_oss_synth_info(dp, dev); ++ if (!info) + return -ENXIO; + +- info = &dp->synths[dev]; + switch (info->arg.event_passing) { + case SNDRV_SEQ_OSS_PROCESS_EVENTS: + if (! info->ch || ch < 0 || ch >= info->nr_voices) { +@@ -298,6 +299,7 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st + return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev); + } + ++ ch = array_index_nospec(ch, info->nr_voices); + if (note == 255 && info->ch[ch].note >= 0) { + /* volume control */ + int type; +@@ -347,10 +349,10 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s + { + struct seq_oss_synthinfo *info; + +- if (!snd_seq_oss_synth_is_valid(dp, dev)) ++ info = snd_seq_oss_synth_info(dp, dev); ++ if (!info) + return -ENXIO; + +- info = &dp->synths[dev]; + switch (info->arg.event_passing) { + case SNDRV_SEQ_OSS_PROCESS_EVENTS: + if (! info->ch || ch < 0 || ch >= info->nr_voices) { +@@ -358,6 +360,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s + return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev); + } + ++ ch = array_index_nospec(ch, info->nr_voices); + if (info->ch[ch].note >= 0) { + note = info->ch[ch].note; + info->ch[ch].vel = 0; +@@ -381,7 +384,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s + static int + set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev) + { +- if (! snd_seq_oss_synth_is_valid(dp, dev)) ++ if (!snd_seq_oss_synth_info(dp, dev)) + return -ENXIO; + + ev->type = type; +@@ -399,7 +402,7 @@ set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, + static int + set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev) + { +- if (! snd_seq_oss_synth_is_valid(dp, dev)) ++ if (!snd_seq_oss_synth_info(dp, dev)) + return -ENXIO; + + ev->type = type; +diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c +index b30b2139e3f0..9debd1b8fd28 100644 +--- a/sound/core/seq/oss/seq_oss_midi.c ++++ b/sound/core/seq/oss/seq_oss_midi.c +@@ -29,6 +29,7 @@ + #include "../seq_lock.h" + #include + #include ++#include + + + /* +@@ -315,6 +316,7 @@ get_mididev(struct seq_oss_devinfo *dp, int dev) + { + if (dev < 0 || dev >= dp->max_mididev) + return NULL; ++ dev = array_index_nospec(dev, dp->max_mididev); + return get_mdev(dev); + } + +diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c +index b16dbef04174..ea545f9291b4 100644 +--- a/sound/core/seq/oss/seq_oss_synth.c ++++ b/sound/core/seq/oss/seq_oss_synth.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + /* + * constants +@@ -339,17 +340,13 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp) + dp->max_synthdev = 0; + } + +-/* +- * check if the specified device is MIDI mapped device +- */ +-static int +-is_midi_dev(struct seq_oss_devinfo *dp, int dev) ++static struct seq_oss_synthinfo * ++get_synthinfo_nospec(struct seq_oss_devinfo *dp, int dev) + { + if (dev < 0 || dev >= dp->max_synthdev) +- return 0; +- if (dp->synths[dev].is_midi) +- return 1; +- return 0; ++ return NULL; ++ dev = array_index_nospec(dev, SNDRV_SEQ_OSS_MAX_SYNTH_DEVS); ++ return &dp->synths[dev]; + } + + /* +@@ -359,14 +356,20 @@ static struct seq_oss_synth * + get_synthdev(struct seq_oss_devinfo *dp, int dev) + { + struct seq_oss_synth *rec; +- if (dev < 0 || dev >= dp->max_synthdev) +- return NULL; +- if (! dp->synths[dev].opened) ++ struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev); ++ ++ if (!info) + return NULL; +- if (dp->synths[dev].is_midi) +- return &midi_synth_dev; +- if ((rec = get_sdev(dev)) == NULL) ++ if (!info->opened) + return NULL; ++ if (info->is_midi) { ++ rec = &midi_synth_dev; ++ snd_use_lock_use(&rec->use_lock); ++ } else { ++ rec = get_sdev(dev); ++ if (!rec) ++ return NULL; ++ } + if (! rec->opened) { + snd_use_lock_free(&rec->use_lock); + return NULL; +@@ -402,10 +405,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev) + struct seq_oss_synth *rec; + struct seq_oss_synthinfo *info; + +- if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev)) +- return; +- info = &dp->synths[dev]; +- if (! info->opened) ++ info = get_synthinfo_nospec(dp, dev); ++ if (!info || !info->opened) + return; + if (info->sysex) + info->sysex->len = 0; /* reset sysex */ +@@ -454,12 +455,14 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt, + const char __user *buf, int p, int c) + { + struct seq_oss_synth *rec; ++ struct seq_oss_synthinfo *info; + int rc; + +- if (dev < 0 || dev >= dp->max_synthdev) ++ info = get_synthinfo_nospec(dp, dev); ++ if (!info) + return -ENXIO; + +- if (is_midi_dev(dp, dev)) ++ if (info->is_midi) + return 0; + if ((rec = get_synthdev(dp, dev)) == NULL) + return -ENXIO; +@@ -467,24 +470,25 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt, + if (rec->oper.load_patch == NULL) + rc = -ENXIO; + else +- rc = rec->oper.load_patch(&dp->synths[dev].arg, fmt, buf, p, c); ++ rc = rec->oper.load_patch(&info->arg, fmt, buf, p, c); + snd_use_lock_free(&rec->use_lock); + return rc; + } + + /* +- * check if the device is valid synth device ++ * check if the device is valid synth device and return the synth info + */ +-int +-snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev) ++struct seq_oss_synthinfo * ++snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, int dev) + { + struct seq_oss_synth *rec; ++ + rec = get_synthdev(dp, dev); + if (rec) { + snd_use_lock_free(&rec->use_lock); +- return 1; ++ return get_synthinfo_nospec(dp, dev); + } +- return 0; ++ return NULL; + } + + +@@ -499,16 +503,18 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf, + int i, send; + unsigned char *dest; + struct seq_oss_synth_sysex *sysex; ++ struct seq_oss_synthinfo *info; + +- if (! snd_seq_oss_synth_is_valid(dp, dev)) ++ info = snd_seq_oss_synth_info(dp, dev); ++ if (!info) + return -ENXIO; + +- sysex = dp->synths[dev].sysex; ++ sysex = info->sysex; + if (sysex == NULL) { + sysex = kzalloc(sizeof(*sysex), GFP_KERNEL); + if (sysex == NULL) + return -ENOMEM; +- dp->synths[dev].sysex = sysex; ++ info->sysex = sysex; + } + + send = 0; +@@ -553,10 +559,12 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf, + int + snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev) + { +- if (! snd_seq_oss_synth_is_valid(dp, dev)) ++ struct seq_oss_synthinfo *info = snd_seq_oss_synth_info(dp, dev); ++ ++ if (!info) + return -EINVAL; +- snd_seq_oss_fill_addr(dp, ev, dp->synths[dev].arg.addr.client, +- dp->synths[dev].arg.addr.port); ++ snd_seq_oss_fill_addr(dp, ev, info->arg.addr.client, ++ info->arg.addr.port); + return 0; + } + +@@ -568,16 +576,18 @@ int + snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr) + { + struct seq_oss_synth *rec; ++ struct seq_oss_synthinfo *info; + int rc; + +- if (is_midi_dev(dp, dev)) ++ info = get_synthinfo_nospec(dp, dev); ++ if (!info || info->is_midi) + return -ENXIO; + if ((rec = get_synthdev(dp, dev)) == NULL) + return -ENXIO; + if (rec->oper.ioctl == NULL) + rc = -ENXIO; + else +- rc = rec->oper.ioctl(&dp->synths[dev].arg, cmd, addr); ++ rc = rec->oper.ioctl(&info->arg, cmd, addr); + snd_use_lock_free(&rec->use_lock); + return rc; + } +@@ -589,7 +599,10 @@ snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, u + int + snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev) + { +- if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev)) ++ struct seq_oss_synthinfo *info; ++ ++ info = snd_seq_oss_synth_info(dp, dev); ++ if (!info || info->is_midi) + return -ENXIO; + ev->type = SNDRV_SEQ_EVENT_OSS; + memcpy(ev->data.raw8.d, data, 8); +diff --git a/sound/core/seq/oss/seq_oss_synth.h b/sound/core/seq/oss/seq_oss_synth.h +index 74ac55f166b6..a63f9e22974d 100644 +--- a/sound/core/seq/oss/seq_oss_synth.h ++++ b/sound/core/seq/oss/seq_oss_synth.h +@@ -37,7 +37,8 @@ void snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp); + void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev); + int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt, + const char __user *buf, int p, int c); +-int snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev); ++struct seq_oss_synthinfo *snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, ++ int dev); + int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf, + struct snd_seq_event *ev); + int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev); +diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c +index ddcc1a325a61..42920a243328 100644 +--- a/sound/drivers/opl3/opl3_synth.c ++++ b/sound/drivers/opl3/opl3_synth.c +@@ -21,6 +21,7 @@ + + #include + #include ++#include + #include + #include + +@@ -448,7 +449,7 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v + { + unsigned short reg_side; + unsigned char op_offset; +- unsigned char voice_offset; ++ unsigned char voice_offset, voice_op; + + unsigned short opl3_reg; + unsigned char reg_val; +@@ -473,7 +474,9 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v + voice_offset = voice->voice - MAX_OPL2_VOICES; + } + /* Get register offset of operator */ +- op_offset = snd_opl3_regmap[voice_offset][voice->op]; ++ voice_offset = array_index_nospec(voice_offset, MAX_OPL2_VOICES); ++ voice_op = array_index_nospec(voice->op, 4); ++ op_offset = snd_opl3_regmap[voice_offset][voice_op]; + + reg_val = 0x00; + /* Set amplitude modulation (tremolo) effect */ +diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c +index 7eb617175fde..a31a70dccecf 100644 +--- a/sound/pci/asihpi/hpimsginit.c ++++ b/sound/pci/asihpi/hpimsginit.c +@@ -23,6 +23,7 @@ + + #include "hpi_internal.h" + #include "hpimsginit.h" ++#include + + /* The actual message size for each object type */ + static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT; +@@ -39,10 +40,12 @@ static void hpi_init_message(struct hpi_message *phm, u16 object, + { + u16 size; + +- if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) ++ if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { ++ object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); + size = msg_size[object]; +- else ++ } else { + size = sizeof(*phm); ++ } + + memset(phm, 0, size); + phm->size = size; +@@ -66,10 +69,12 @@ void hpi_init_response(struct hpi_response *phr, u16 object, u16 function, + { + u16 size; + +- if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) ++ if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { ++ object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); + size = res_size[object]; +- else ++ } else { + size = sizeof(*phr); ++ } + + memset(phr, 0, sizeof(*phr)); + phr->size = size; +diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c +index d17937b92331..7a32abbe0cef 100644 +--- a/sound/pci/asihpi/hpioctl.c ++++ b/sound/pci/asihpi/hpioctl.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + #ifdef MODULE_FIRMWARE + MODULE_FIRMWARE("asihpi/dsp5000.bin"); +@@ -182,7 +183,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + struct hpi_adapter *pa = NULL; + + if (hm->h.adapter_index < ARRAY_SIZE(adapters)) +- pa = &adapters[hm->h.adapter_index]; ++ pa = &adapters[array_index_nospec(hm->h.adapter_index, ++ ARRAY_SIZE(adapters))]; + + if (!pa || !pa->adapter || !pa->adapter->type) { + hpi_init_response(&hr->r0, hm->h.object, +diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c +index 57df06e76968..cc009a4a3d1d 100644 +--- a/sound/pci/hda/hda_hwdep.c ++++ b/sound/pci/hda/hda_hwdep.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include "hda_codec.h" + #include "hda_local.h" +@@ -51,7 +52,16 @@ static int get_wcap_ioctl(struct hda_codec *codec, + + if (get_user(verb, &arg->verb)) + return -EFAULT; +- res = get_wcaps(codec, verb >> 24); ++ /* open-code get_wcaps(verb>>24) with nospec */ ++ verb >>= 24; ++ if (verb < codec->core.start_nid || ++ verb >= codec->core.start_nid + codec->core.num_nodes) { ++ res = 0; ++ } else { ++ verb -= codec->core.start_nid; ++ verb = array_index_nospec(verb, codec->core.num_nodes); ++ res = codec->wcaps[verb]; ++ } + if (put_user(res, &arg->res)) + return -EFAULT; + return 0; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 8cb14e27988b..6a789278970e 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -329,6 +329,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) + break; + case 0x10ec0225: + case 0x10ec0233: ++ case 0x10ec0235: + case 0x10ec0236: + case 0x10ec0255: + case 0x10ec0256: +@@ -6296,6 +6297,7 @@ static int patch_alc269(struct hda_codec *codec) + case 0x10ec0298: + spec->codec_variant = ALC269_TYPE_ALC298; + break; ++ case 0x10ec0235: + case 0x10ec0255: + spec->codec_variant = ALC269_TYPE_ALC255; + break; +diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c +index a4a999a0317e..1a0c0d16a279 100644 +--- a/sound/pci/rme9652/hdspm.c ++++ b/sound/pci/rme9652/hdspm.c +@@ -137,6 +137,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -5692,40 +5693,43 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream, + struct snd_pcm_channel_info *info) + { + struct hdspm *hdspm = snd_pcm_substream_chip(substream); ++ unsigned int channel = info->channel; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { +- if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) { ++ if (snd_BUG_ON(channel >= hdspm->max_channels_out)) { + dev_info(hdspm->card->dev, + "snd_hdspm_channel_info: output channel out of range (%d)\n", +- info->channel); ++ channel); + return -EINVAL; + } + +- if (hdspm->channel_map_out[info->channel] < 0) { ++ channel = array_index_nospec(channel, hdspm->max_channels_out); ++ if (hdspm->channel_map_out[channel] < 0) { + dev_info(hdspm->card->dev, + "snd_hdspm_channel_info: output channel %d mapped out\n", +- info->channel); ++ channel); + return -EINVAL; + } + +- info->offset = hdspm->channel_map_out[info->channel] * ++ info->offset = hdspm->channel_map_out[channel] * + HDSPM_CHANNEL_BUFFER_BYTES; + } else { +- if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) { ++ if (snd_BUG_ON(channel >= hdspm->max_channels_in)) { + dev_info(hdspm->card->dev, + "snd_hdspm_channel_info: input channel out of range (%d)\n", +- info->channel); ++ channel); + return -EINVAL; + } + +- if (hdspm->channel_map_in[info->channel] < 0) { ++ channel = array_index_nospec(channel, hdspm->max_channels_in); ++ if (hdspm->channel_map_in[channel] < 0) { + dev_info(hdspm->card->dev, + "snd_hdspm_channel_info: input channel %d mapped out\n", +- info->channel); ++ channel); + return -EINVAL; + } + +- info->offset = hdspm->channel_map_in[info->channel] * ++ info->offset = hdspm->channel_map_in[channel] * + HDSPM_CHANNEL_BUFFER_BYTES; + } + +diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c +index fdbc0aa2776a..c253bdf92e36 100644 +--- a/sound/pci/rme9652/rme9652.c ++++ b/sound/pci/rme9652/rme9652.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -2036,9 +2037,10 @@ static int snd_rme9652_channel_info(struct snd_pcm_substream *substream, + if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS)) + return -EINVAL; + +- if ((chn = rme9652->channel_map[info->channel]) < 0) { ++ chn = rme9652->channel_map[array_index_nospec(info->channel, ++ RME9652_NCHANNELS)]; ++ if (chn < 0) + return -EINVAL; +- } + + info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES; + info->first = 0; +diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c +index 59f234e51971..e8adead8be00 100644 +--- a/sound/soc/fsl/fsl_esai.c ++++ b/sound/soc/fsl/fsl_esai.c +@@ -143,6 +143,13 @@ static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio, + + psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8; + ++ /* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */ ++ if (ratio <= 256) { ++ pm = ratio; ++ fp = 1; ++ goto out; ++ } ++ + /* Set the max fluctuation -- 0.1% of the max devisor */ + savesub = (psr ? 1 : 8) * 256 * maxfp / 1000; + +diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c +index 1f8fb0d904e0..f5cf23ffb35b 100644 +--- a/sound/usb/mixer_maps.c ++++ b/sound/usb/mixer_maps.c +@@ -351,8 +351,11 @@ static struct usbmix_name_map bose_companion5_map[] = { + /* + * Dell usb dock with ALC4020 codec had a firmware problem where it got + * screwed up when zero volume is passed; just skip it as a workaround ++ * ++ * Also the extension unit gives an access error, so skip it as well. + */ + static const struct usbmix_name_map dell_alc4020_map[] = { ++ { 4, NULL }, /* extension unit */ + { 16, NULL }, + { 19, NULL }, + { 0 } diff --git a/patch/kernel/rk3328-default/04-patch-4.4.131-132.patch b/patch/kernel/rk3328-default/04-patch-4.4.131-132.patch new file mode 100644 index 000000000..c2f7c0270 --- /dev/null +++ b/patch/kernel/rk3328-default/04-patch-4.4.131-132.patch @@ -0,0 +1,2948 @@ +diff --git a/Makefile b/Makefile +index 6ec65396a56d..ace4a655548a 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 131 ++SUBLEVEL = 132 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c +index b011140e6b06..5ddb1debba95 100644 +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -118,8 +118,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { + + /* upper facilities limit for kvm */ + unsigned long kvm_s390_fac_list_mask[] = { +- 0xffe6fffbfcfdfc40UL, +- 0x005e800000000000UL, ++ 0xffe6ffffffffffffUL, ++ 0x005effffffffffffUL, + }; + + unsigned long kvm_s390_fac_list_mask_size(void) +diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c +index b52a8d08ab36..fbf2edc3eb35 100644 +--- a/arch/x86/kernel/cpu/perf_event.c ++++ b/arch/x86/kernel/cpu/perf_event.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -297,17 +298,20 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event *event) + + config = attr->config; + +- cache_type = (config >> 0) & 0xff; ++ cache_type = (config >> 0) & 0xff; + if (cache_type >= PERF_COUNT_HW_CACHE_MAX) + return -EINVAL; ++ cache_type = array_index_nospec(cache_type, PERF_COUNT_HW_CACHE_MAX); + + cache_op = (config >> 8) & 0xff; + if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX) + return -EINVAL; ++ cache_op = array_index_nospec(cache_op, PERF_COUNT_HW_CACHE_OP_MAX); + + cache_result = (config >> 16) & 0xff; + if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) + return -EINVAL; ++ cache_result = array_index_nospec(cache_result, PERF_COUNT_HW_CACHE_RESULT_MAX); + + val = hw_cache_event_ids[cache_type][cache_op][cache_result]; + +@@ -404,6 +408,8 @@ int x86_setup_perfctr(struct perf_event *event) + if (attr->config >= x86_pmu.max_events) + return -EINVAL; + ++ attr->config = array_index_nospec((unsigned long)attr->config, x86_pmu.max_events); ++ + /* + * The generic map: + */ +diff --git a/arch/x86/kernel/cpu/perf_event_intel_cstate.c b/arch/x86/kernel/cpu/perf_event_intel_cstate.c +index 75a38b5a2e26..5b8c90935270 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel_cstate.c ++++ b/arch/x86/kernel/cpu/perf_event_intel_cstate.c +@@ -88,6 +88,7 @@ + #include + #include + #include ++#include + #include + #include "perf_event.h" + +@@ -409,6 +410,7 @@ static int cstate_pmu_event_init(struct perf_event *event) + } else if (event->pmu == &cstate_pkg_pmu) { + if (cfg >= PERF_CSTATE_PKG_EVENT_MAX) + return -EINVAL; ++ cfg = array_index_nospec((unsigned long)cfg, PERF_CSTATE_PKG_EVENT_MAX); + if (!pkg_msr[cfg].attr) + return -EINVAL; + event->hw.event_base = pkg_msr[cfg].msr; +diff --git a/arch/x86/kernel/cpu/perf_event_msr.c b/arch/x86/kernel/cpu/perf_event_msr.c +index ec863b9a9f78..067427384a63 100644 +--- a/arch/x86/kernel/cpu/perf_event_msr.c ++++ b/arch/x86/kernel/cpu/perf_event_msr.c +@@ -1,4 +1,5 @@ + #include ++#include + + enum perf_msr_id { + PERF_MSR_TSC = 0, +@@ -115,9 +116,6 @@ static int msr_event_init(struct perf_event *event) + if (event->attr.type != event->pmu->type) + return -ENOENT; + +- if (cfg >= PERF_MSR_EVENT_MAX) +- return -EINVAL; +- + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || +@@ -128,6 +126,11 @@ static int msr_event_init(struct perf_event *event) + event->attr.sample_period) /* no sampling */ + return -EINVAL; + ++ if (cfg >= PERF_MSR_EVENT_MAX) ++ return -EINVAL; ++ ++ cfg = array_index_nospec((unsigned long)cfg, PERF_MSR_EVENT_MAX); ++ + if (!msr[cfg].attr) + return -EINVAL; + +diff --git a/crypto/af_alg.c b/crypto/af_alg.c +index ca50eeb13097..b5953f1d1a18 100644 +--- a/crypto/af_alg.c ++++ b/crypto/af_alg.c +@@ -157,16 +157,16 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) + void *private; + int err; + +- /* If caller uses non-allowed flag, return error. */ +- if ((sa->salg_feat & ~allowed) || (sa->salg_mask & ~allowed)) +- return -EINVAL; +- + if (sock->state == SS_CONNECTED) + return -EINVAL; + + if (addr_len != sizeof(*sa)) + return -EINVAL; + ++ /* If caller uses non-allowed flag, return error. */ ++ if ((sa->salg_feat & ~allowed) || (sa->salg_mask & ~allowed)) ++ return -EINVAL; ++ + sa->salg_type[sizeof(sa->salg_type) - 1] = 0; + sa->salg_name[sizeof(sa->salg_name) - 1] = 0; + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 2d677ba46d77..60d6db82ce5a 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4243,6 +4243,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { + ATA_HORKAGE_ZERO_AFTER_TRIM | + ATA_HORKAGE_NOLPM, }, + ++ /* Sandisk devices which are known to not handle LPM well */ ++ { "SanDisk SD7UB3Q*G1001", NULL, ATA_HORKAGE_NOLPM, }, ++ + /* devices that don't properly handle queued TRIM commands */ + { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM, }, +diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c +index cecfb943762f..6eab52b92e01 100644 +--- a/drivers/atm/zatm.c ++++ b/drivers/atm/zatm.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1456,6 +1457,8 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) + return -EFAULT; + if (pool < 0 || pool > ZATM_LAST_POOL) + return -EINVAL; ++ pool = array_index_nospec(pool, ++ ZATM_LAST_POOL + 1); + spin_lock_irqsave(&zatm_dev->lock, flags); + info = zatm_dev->pool_info[pool]; + if (cmd == ZATM_GETPOOLZ) { +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 7fca7cfd5b09..54cef3dc0beb 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -216,6 +216,7 @@ static const struct usb_device_id blacklist_table[] = { + { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 }, +@@ -246,7 +247,6 @@ static const struct usb_device_id blacklist_table[] = { + { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, + + /* QCA ROME chipset */ +- { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_QCA_ROME }, + { USB_DEVICE(0x0cf3, 0xe007), .driver_info = BTUSB_QCA_ROME }, + { USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME }, + { USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME }, +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +index 098e562bd579..9b97f70fbb3d 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +@@ -1991,6 +1991,7 @@ void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, + vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, + out_fence, NULL); + ++ vmw_dmabuf_unreference(&ctx->buf); + vmw_resource_unreserve(res, false, NULL, 0); + mutex_unlock(&res->dev_priv->cmdbuf_mutex); + } +diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c +index ea3bc9bb1b7a..2b9c00faca7d 100644 +--- a/drivers/infiniband/core/ucma.c ++++ b/drivers/infiniband/core/ucma.c +@@ -675,7 +675,7 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file, + if (copy_from_user(&cmd, inbuf, sizeof(cmd))) + return -EFAULT; + +- if (!rdma_addr_size_in6(&cmd.src_addr) || ++ if ((cmd.src_addr.sin6_family && !rdma_addr_size_in6(&cmd.src_addr)) || + !rdma_addr_size_in6(&cmd.dst_addr)) + return -EINVAL; + +diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c +index cfcfbb6b84d7..c5390f6f94c5 100644 +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -231,7 +231,11 @@ static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap, + } else { + if (ucmd) { + qp->rq.wqe_cnt = ucmd->rq_wqe_count; ++ if (ucmd->rq_wqe_shift > BITS_PER_BYTE * sizeof(ucmd->rq_wqe_shift)) ++ return -EINVAL; + qp->rq.wqe_shift = ucmd->rq_wqe_shift; ++ if ((1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) < qp->wq_sig) ++ return -EINVAL; + qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig; + qp->rq.max_post = qp->rq.wqe_cnt; + } else { +@@ -1348,18 +1352,18 @@ enum { + + static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate) + { +- if (rate == IB_RATE_PORT_CURRENT) { ++ if (rate == IB_RATE_PORT_CURRENT) + return 0; +- } else if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) { ++ ++ if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_300_GBPS) + return -EINVAL; +- } else { +- while (rate != IB_RATE_2_5_GBPS && +- !(1 << (rate + MLX5_STAT_RATE_OFFSET) & +- MLX5_CAP_GEN(dev->mdev, stat_rate_support))) +- --rate; +- } + +- return rate + MLX5_STAT_RATE_OFFSET; ++ while (rate != IB_RATE_PORT_CURRENT && ++ !(1 << (rate + MLX5_STAT_RATE_OFFSET) & ++ MLX5_CAP_GEN(dev->mdev, stat_rate_support))) ++ --rate; ++ ++ return rate ? rate + MLX5_STAT_RATE_OFFSET : rate; + } + + static int mlx5_set_path(struct mlx5_ib_dev *dev, const struct ib_ah_attr *ah, +diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c +index 766bf2660116..5f04b2d94635 100644 +--- a/drivers/input/input-leds.c ++++ b/drivers/input/input-leds.c +@@ -88,6 +88,7 @@ static int input_leds_connect(struct input_handler *handler, + const struct input_device_id *id) + { + struct input_leds *leds; ++ struct input_led *led; + unsigned int num_leds; + unsigned int led_code; + int led_no; +@@ -119,14 +120,13 @@ static int input_leds_connect(struct input_handler *handler, + + led_no = 0; + for_each_set_bit(led_code, dev->ledbit, LED_CNT) { +- struct input_led *led = &leds->leds[led_no]; ++ if (!input_led_info[led_code].name) ++ continue; + ++ led = &leds->leds[led_no]; + led->handle = &leds->handle; + led->code = led_code; + +- if (!input_led_info[led_code].name) +- continue; +- + led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s", + dev_name(&dev->dev), + input_led_info[led_code].name); +diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c +index 2d5794ec338b..88dfe3008cf4 100644 +--- a/drivers/input/touchscreen/atmel_mxt_ts.c ++++ b/drivers/input/touchscreen/atmel_mxt_ts.c +@@ -2522,6 +2522,15 @@ static const struct dmi_system_id mxt_dmi_table[] = { + }, + .driver_data = samus_platform_data, + }, ++ { ++ /* Samsung Chromebook Pro */ ++ .ident = "Samsung Chromebook Pro", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Google"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"), ++ }, ++ .driver_data = samus_platform_data, ++ }, + { + /* Other Google Chromebooks */ + .ident = "Chromebook", +diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +index e2a239c1f40b..40a335c6b792 100644 +--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c ++++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +@@ -1032,14 +1032,87 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, + /* Loop over status bytes, accumulating ECC status. */ + status = auxiliary_virt + nfc_geo->auxiliary_status_offset; + ++ read_page_swap_end(this, buf, nfc_geo->payload_size, ++ this->payload_virt, this->payload_phys, ++ nfc_geo->payload_size, ++ payload_virt, payload_phys); ++ + for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) { + if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED)) + continue; + + if (*status == STATUS_UNCORRECTABLE) { ++ int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; ++ u8 *eccbuf = this->raw_buffer; ++ int offset, bitoffset; ++ int eccbytes; ++ int flips; ++ ++ /* Read ECC bytes into our internal raw_buffer */ ++ offset = nfc_geo->metadata_size * 8; ++ offset += ((8 * nfc_geo->ecc_chunk_size) + eccbits) * (i + 1); ++ offset -= eccbits; ++ bitoffset = offset % 8; ++ eccbytes = DIV_ROUND_UP(offset + eccbits, 8); ++ offset /= 8; ++ eccbytes -= offset; ++ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, offset, -1); ++ chip->read_buf(mtd, eccbuf, eccbytes); ++ ++ /* ++ * ECC data are not byte aligned and we may have ++ * in-band data in the first and last byte of ++ * eccbuf. Set non-eccbits to one so that ++ * nand_check_erased_ecc_chunk() does not count them ++ * as bitflips. ++ */ ++ if (bitoffset) ++ eccbuf[0] |= GENMASK(bitoffset - 1, 0); ++ ++ bitoffset = (bitoffset + eccbits) % 8; ++ if (bitoffset) ++ eccbuf[eccbytes - 1] |= GENMASK(7, bitoffset); ++ ++ /* ++ * The ECC hardware has an uncorrectable ECC status ++ * code in case we have bitflips in an erased page. As ++ * nothing was written into this subpage the ECC is ++ * obviously wrong and we can not trust it. We assume ++ * at this point that we are reading an erased page and ++ * try to correct the bitflips in buffer up to ++ * ecc_strength bitflips. If this is a page with random ++ * data, we exceed this number of bitflips and have a ++ * ECC failure. Otherwise we use the corrected buffer. ++ */ ++ if (i == 0) { ++ /* The first block includes metadata */ ++ flips = nand_check_erased_ecc_chunk( ++ buf + i * nfc_geo->ecc_chunk_size, ++ nfc_geo->ecc_chunk_size, ++ eccbuf, eccbytes, ++ auxiliary_virt, ++ nfc_geo->metadata_size, ++ nfc_geo->ecc_strength); ++ } else { ++ flips = nand_check_erased_ecc_chunk( ++ buf + i * nfc_geo->ecc_chunk_size, ++ nfc_geo->ecc_chunk_size, ++ eccbuf, eccbytes, ++ NULL, 0, ++ nfc_geo->ecc_strength); ++ } ++ ++ if (flips > 0) { ++ max_bitflips = max_t(unsigned int, max_bitflips, ++ flips); ++ mtd->ecc_stats.corrected += flips; ++ continue; ++ } ++ + mtd->ecc_stats.failed++; + continue; + } ++ + mtd->ecc_stats.corrected += *status; + max_bitflips = max_t(unsigned int, max_bitflips, *status); + } +@@ -1062,11 +1135,6 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, + chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0]; + } + +- read_page_swap_end(this, buf, nfc_geo->payload_size, +- this->payload_virt, this->payload_phys, +- nfc_geo->payload_size, +- payload_virt, payload_phys); +- + return max_bitflips; + } + +diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c +index db1855b0e08f..59f891bebcc6 100644 +--- a/drivers/net/can/usb/kvaser_usb.c ++++ b/drivers/net/can/usb/kvaser_usb.c +@@ -1175,7 +1175,7 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, + + skb = alloc_can_skb(priv->netdev, &cf); + if (!skb) { +- stats->tx_dropped++; ++ stats->rx_dropped++; + return; + } + +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index b0ea8dee5f06..a6f0a8f516d6 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -631,6 +631,7 @@ static const struct usb_device_id products[] = { + {QMI_FIXED_INTF(0x05c6, 0x9080, 8)}, + {QMI_FIXED_INTF(0x05c6, 0x9083, 3)}, + {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, ++ {QMI_FIXED_INTF(0x05c6, 0x90b2, 3)}, /* ublox R410M */ + {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, + {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, + {QMI_FIXED_INTF(0x0846, 0x68a2, 8)}, +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index ee638cb8b48f..0c23768aa1ec 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -67,6 +67,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { + .board_size = QCA988X_BOARD_DATA_SZ, + .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ, + }, ++ .decap_align_bytes = 4, + }, + { + .id = QCA6174_HW_2_1_VERSION, +@@ -85,6 +86,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { + .board_size = QCA6174_BOARD_DATA_SZ, + .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, + }, ++ .decap_align_bytes = 4, + }, + { + .id = QCA6174_HW_2_1_VERSION, +@@ -103,6 +105,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { + .board_size = QCA6174_BOARD_DATA_SZ, + .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, + }, ++ .decap_align_bytes = 4, + }, + { + .id = QCA6174_HW_3_0_VERSION, +@@ -121,6 +124,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { + .board_size = QCA6174_BOARD_DATA_SZ, + .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, + }, ++ .decap_align_bytes = 4, + }, + { + .id = QCA6174_HW_3_2_VERSION, +@@ -140,6 +144,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { + .board_size = QCA6174_BOARD_DATA_SZ, + .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, + }, ++ .decap_align_bytes = 4, + }, + { + .id = QCA99X0_HW_2_0_DEV_VERSION, +@@ -159,6 +164,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { + .board_size = QCA99X0_BOARD_DATA_SZ, + .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, + }, ++ .decap_align_bytes = 1, + }, + { + .id = QCA9377_HW_1_0_DEV_VERSION, +@@ -177,6 +183,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { + .board_size = QCA9377_BOARD_DATA_SZ, + .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ, + }, ++ .decap_align_bytes = 4, + }, + { + .id = QCA9377_HW_1_1_DEV_VERSION, +@@ -195,6 +202,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { + .board_size = QCA9377_BOARD_DATA_SZ, + .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ, + }, ++ .decap_align_bytes = 4, + }, + }; + +diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h +index 858d75f49a9f..257836a0cfbc 100644 +--- a/drivers/net/wireless/ath/ath10k/core.h ++++ b/drivers/net/wireless/ath/ath10k/core.h +@@ -670,6 +670,10 @@ struct ath10k { + size_t board_size; + size_t board_ext_size; + } fw; ++ ++ /* Number of bytes used for alignment in rx_hdr_status */ ++ int decap_align_bytes; ++ + } hw_params; + + const struct firmware *board; +diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c +index 6060dda4e910..d26cb37b1fbd 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -979,7 +979,7 @@ static void ath10k_process_rx(struct ath10k *ar, + *status = *rx_status; + + ath10k_dbg(ar, ATH10K_DBG_DATA, +- "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", ++ "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n", + skb, + skb->len, + ieee80211_get_SA(hdr), +@@ -1076,7 +1076,21 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, + hdr = (void *)msdu->data; + + /* Tail */ +- skb_trim(msdu, msdu->len - ath10k_htt_rx_crypto_tail_len(ar, enctype)); ++ if (status->flag & RX_FLAG_IV_STRIPPED) { ++ skb_trim(msdu, msdu->len - ++ ath10k_htt_rx_crypto_tail_len(ar, enctype)); ++ } else { ++ /* MIC */ ++ if ((status->flag & RX_FLAG_MIC_STRIPPED) && ++ enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) ++ skb_trim(msdu, msdu->len - 8); ++ ++ /* ICV */ ++ if (status->flag & RX_FLAG_ICV_STRIPPED && ++ enctype != HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) ++ skb_trim(msdu, msdu->len - ++ ath10k_htt_rx_crypto_tail_len(ar, enctype)); ++ } + + /* MMIC */ + if (!ieee80211_has_morefrags(hdr->frame_control) && +@@ -1095,12 +1109,14 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, + static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, +- const u8 first_hdr[64]) ++ const u8 first_hdr[64], ++ enum htt_rx_mpdu_encrypt_type enctype) + { + struct ieee80211_hdr *hdr; + size_t hdr_len; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; ++ int bytes_aligned = ar->hw_params.decap_align_bytes; + + /* Delivered decapped frame: + * [nwifi 802.11 header] <-- replaced with 802.11 hdr +@@ -1123,6 +1139,14 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar, + /* push original 802.11 header */ + hdr = (struct ieee80211_hdr *)first_hdr; + hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ ++ if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ memcpy(skb_push(msdu, ++ ath10k_htt_rx_crypto_param_len(ar, enctype)), ++ (void *)hdr + round_up(hdr_len, bytes_aligned), ++ ath10k_htt_rx_crypto_param_len(ar, enctype)); ++ } ++ + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + + /* original 802.11 header has a different DA and in +@@ -1180,6 +1204,7 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, + void *rfc1042; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; ++ int bytes_aligned = ar->hw_params.decap_align_bytes; + + /* Delivered decapped frame: + * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc +@@ -1203,6 +1228,14 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, + /* push original 802.11 header */ + hdr = (struct ieee80211_hdr *)first_hdr; + hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ ++ if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ memcpy(skb_push(msdu, ++ ath10k_htt_rx_crypto_param_len(ar, enctype)), ++ (void *)hdr + round_up(hdr_len, bytes_aligned), ++ ath10k_htt_rx_crypto_param_len(ar, enctype)); ++ } ++ + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + + /* original 802.11 header has a different DA and in +@@ -1216,10 +1249,12 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, + static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar, + struct sk_buff *msdu, + struct ieee80211_rx_status *status, +- const u8 first_hdr[64]) ++ const u8 first_hdr[64], ++ enum htt_rx_mpdu_encrypt_type enctype) + { + struct ieee80211_hdr *hdr; + size_t hdr_len; ++ int bytes_aligned = ar->hw_params.decap_align_bytes; + + /* Delivered decapped frame: + * [amsdu header] <-- replaced with 802.11 hdr +@@ -1231,6 +1266,14 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar, + + hdr = (struct ieee80211_hdr *)first_hdr; + hdr_len = ieee80211_hdrlen(hdr->frame_control); ++ ++ if (!(status->flag & RX_FLAG_IV_STRIPPED)) { ++ memcpy(skb_push(msdu, ++ ath10k_htt_rx_crypto_param_len(ar, enctype)), ++ (void *)hdr + round_up(hdr_len, bytes_aligned), ++ ath10k_htt_rx_crypto_param_len(ar, enctype)); ++ } ++ + memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); + } + +@@ -1265,13 +1308,15 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar, + is_decrypted); + break; + case RX_MSDU_DECAP_NATIVE_WIFI: +- ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr); ++ ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr, ++ enctype); + break; + case RX_MSDU_DECAP_ETHERNET2_DIX: + ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, enctype); + break; + case RX_MSDU_DECAP_8023_SNAP_LLC: +- ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr); ++ ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr, ++ enctype); + break; + } + } +@@ -1314,7 +1359,8 @@ static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu) + + static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + struct sk_buff_head *amsdu, +- struct ieee80211_rx_status *status) ++ struct ieee80211_rx_status *status, ++ bool fill_crypt_header) + { + struct sk_buff *first; + struct sk_buff *last; +@@ -1324,7 +1370,6 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + enum htt_rx_mpdu_encrypt_type enctype; + u8 first_hdr[64]; + u8 *qos; +- size_t hdr_len; + bool has_fcs_err; + bool has_crypto_err; + bool has_tkip_err; +@@ -1345,15 +1390,17 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + * decapped header. It'll be used for undecapping of each MSDU. + */ + hdr = (void *)rxd->rx_hdr_status; +- hdr_len = ieee80211_hdrlen(hdr->frame_control); +- memcpy(first_hdr, hdr, hdr_len); ++ memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN); + + /* Each A-MSDU subframe will use the original header as the base and be + * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl. + */ + hdr = (void *)first_hdr; +- qos = ieee80211_get_qos_ctl(hdr); +- qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; ++ ++ if (ieee80211_is_data_qos(hdr->frame_control)) { ++ qos = ieee80211_get_qos_ctl(hdr); ++ qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; ++ } + + /* Some attention flags are valid only in the last MSDU. */ + last = skb_peek_tail(amsdu); +@@ -1387,11 +1434,17 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + if (has_tkip_err) + status->flag |= RX_FLAG_MMIC_ERROR; + +- if (is_decrypted) ++ if (is_decrypted) { + status->flag |= RX_FLAG_DECRYPTED | +- RX_FLAG_IV_STRIPPED | + RX_FLAG_MMIC_STRIPPED; + ++ if (fill_crypt_header) ++ status->flag |= RX_FLAG_MIC_STRIPPED | ++ RX_FLAG_ICV_STRIPPED; ++ else ++ status->flag |= RX_FLAG_IV_STRIPPED; ++ } ++ + skb_queue_walk(amsdu, msdu) { + ath10k_htt_rx_h_csum_offload(msdu); + ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype, +@@ -1404,6 +1457,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, + if (!is_decrypted) + continue; + ++ if (fill_crypt_header) ++ continue; ++ + hdr = (void *)msdu->data; + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); + } +@@ -1414,6 +1470,9 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar, + struct ieee80211_rx_status *status) + { + struct sk_buff *msdu; ++ struct sk_buff *first_subframe; ++ ++ first_subframe = skb_peek(amsdu); + + while ((msdu = __skb_dequeue(amsdu))) { + /* Setup per-MSDU flags */ +@@ -1422,6 +1481,13 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar, + else + status->flag |= RX_FLAG_AMSDU_MORE; + ++ if (msdu == first_subframe) { ++ first_subframe = NULL; ++ status->flag &= ~RX_FLAG_ALLOW_SAME_PN; ++ } else { ++ status->flag |= RX_FLAG_ALLOW_SAME_PN; ++ } ++ + ath10k_process_rx(ar, status, msdu); + } + } +@@ -1607,7 +1673,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, + ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); + ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); + ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); +- ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); ++ ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true); + ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); + } + +@@ -1653,7 +1719,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, + + ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); + ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); +- ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); ++ ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true); + ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); + + if (fw_desc_len > 0) { +@@ -1952,7 +2018,7 @@ static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) + */ + ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); + ath10k_htt_rx_h_filter(ar, &amsdu, status); +- ath10k_htt_rx_h_mpdu(ar, &amsdu, status); ++ ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false); + ath10k_htt_rx_h_deliver(ar, &amsdu, status); + break; + case -EAGAIN: +diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c +index 9bec8237231d..99c21aac68bd 100644 +--- a/drivers/net/wireless/ath/wcn36xx/txrx.c ++++ b/drivers/net/wireless/ath/wcn36xx/txrx.c +@@ -57,7 +57,7 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) + RX_FLAG_MMIC_STRIPPED | + RX_FLAG_DECRYPTED; + +- wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%x\n", status.flag); ++ wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%llx\n", status.flag); + + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); + +diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c +index 22dcccf2d286..6a287c81a7be 100644 +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -157,7 +157,9 @@ static const unsigned short full_speed_maxpacket_maxes[4] = { + static const unsigned short high_speed_maxpacket_maxes[4] = { + [USB_ENDPOINT_XFER_CONTROL] = 64, + [USB_ENDPOINT_XFER_ISOC] = 1024, +- [USB_ENDPOINT_XFER_BULK] = 512, ++ ++ /* Bulk should be 512, but some devices use 1024: we will warn below */ ++ [USB_ENDPOINT_XFER_BULK] = 1024, + [USB_ENDPOINT_XFER_INT] = 1024, + }; + static const unsigned short super_speed_maxpacket_maxes[4] = { +diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c +index 0d843e0f8055..494823f21c28 100644 +--- a/drivers/usb/musb/musb_host.c ++++ b/drivers/usb/musb/musb_host.c +@@ -1048,7 +1048,9 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep, + /* set tx_reinit and schedule the next qh */ + ep->tx_reinit = 1; + } +- musb_start_urb(musb, is_in, next_qh); ++ ++ if (next_qh) ++ musb_start_urb(musb, is_in, next_qh); + } + } + +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 1799aa058a5b..d982c455e18e 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -236,6 +236,8 @@ static void option_instat_callback(struct urb *urb); + /* These Quectel products use Qualcomm's vendor ID */ + #define QUECTEL_PRODUCT_UC20 0x9003 + #define QUECTEL_PRODUCT_UC15 0x9090 ++/* These u-blox products use Qualcomm's vendor ID */ ++#define UBLOX_PRODUCT_R410M 0x90b2 + /* These Yuga products use Qualcomm's vendor ID */ + #define YUGA_PRODUCT_CLM920_NC5 0x9625 + +@@ -244,6 +246,7 @@ static void option_instat_callback(struct urb *urb); + #define QUECTEL_PRODUCT_EC21 0x0121 + #define QUECTEL_PRODUCT_EC25 0x0125 + #define QUECTEL_PRODUCT_BG96 0x0296 ++#define QUECTEL_PRODUCT_EP06 0x0306 + + #define CMOTECH_VENDOR_ID 0x16d8 + #define CMOTECH_PRODUCT_6001 0x6001 +@@ -550,147 +553,15 @@ static void option_instat_callback(struct urb *urb); + #define WETELECOM_PRODUCT_6802 0x6802 + #define WETELECOM_PRODUCT_WMD300 0x6803 + +-struct option_blacklist_info { +- /* bitmask of interface numbers blacklisted for send_setup */ +- const unsigned long sendsetup; +- /* bitmask of interface numbers that are reserved */ +- const unsigned long reserved; +-}; +- +-static const struct option_blacklist_info four_g_w14_blacklist = { +- .sendsetup = BIT(0) | BIT(1), +-}; +- +-static const struct option_blacklist_info four_g_w100_blacklist = { +- .sendsetup = BIT(1) | BIT(2), +- .reserved = BIT(3), +-}; +- +-static const struct option_blacklist_info alcatel_x200_blacklist = { +- .sendsetup = BIT(0) | BIT(1), +- .reserved = BIT(4), +-}; +- +-static const struct option_blacklist_info zte_0037_blacklist = { +- .sendsetup = BIT(0) | BIT(1), +-}; +- +-static const struct option_blacklist_info zte_k3765_z_blacklist = { +- .sendsetup = BIT(0) | BIT(1) | BIT(2), +- .reserved = BIT(4), +-}; +- +-static const struct option_blacklist_info zte_ad3812_z_blacklist = { +- .sendsetup = BIT(0) | BIT(1) | BIT(2), +-}; +- +-static const struct option_blacklist_info zte_mc2718_z_blacklist = { +- .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), +-}; +- +-static const struct option_blacklist_info zte_mc2716_z_blacklist = { +- .sendsetup = BIT(1) | BIT(2) | BIT(3), +-}; +- +-static const struct option_blacklist_info zte_me3620_mbim_blacklist = { +- .reserved = BIT(2) | BIT(3) | BIT(4), +-}; +- +-static const struct option_blacklist_info zte_me3620_xl_blacklist = { +- .reserved = BIT(3) | BIT(4) | BIT(5), +-}; +- +-static const struct option_blacklist_info zte_zm8620_x_blacklist = { +- .reserved = BIT(3) | BIT(4) | BIT(5), +-}; +- +-static const struct option_blacklist_info huawei_cdc12_blacklist = { +- .reserved = BIT(1) | BIT(2), +-}; +- +-static const struct option_blacklist_info net_intf0_blacklist = { +- .reserved = BIT(0), +-}; + +-static const struct option_blacklist_info net_intf1_blacklist = { +- .reserved = BIT(1), +-}; ++/* Device flags */ + +-static const struct option_blacklist_info net_intf2_blacklist = { +- .reserved = BIT(2), +-}; ++/* Interface does not support modem-control requests */ ++#define NCTRL(ifnum) ((BIT(ifnum) & 0xff) << 8) + +-static const struct option_blacklist_info net_intf3_blacklist = { +- .reserved = BIT(3), +-}; ++/* Interface is reserved */ ++#define RSVD(ifnum) ((BIT(ifnum) & 0xff) << 0) + +-static const struct option_blacklist_info net_intf4_blacklist = { +- .reserved = BIT(4), +-}; +- +-static const struct option_blacklist_info net_intf5_blacklist = { +- .reserved = BIT(5), +-}; +- +-static const struct option_blacklist_info net_intf6_blacklist = { +- .reserved = BIT(6), +-}; +- +-static const struct option_blacklist_info zte_mf626_blacklist = { +- .sendsetup = BIT(0) | BIT(1), +- .reserved = BIT(4), +-}; +- +-static const struct option_blacklist_info zte_1255_blacklist = { +- .reserved = BIT(3) | BIT(4), +-}; +- +-static const struct option_blacklist_info simcom_sim7100e_blacklist = { +- .reserved = BIT(5) | BIT(6), +-}; +- +-static const struct option_blacklist_info telit_me910_blacklist = { +- .sendsetup = BIT(0), +- .reserved = BIT(1) | BIT(3), +-}; +- +-static const struct option_blacklist_info telit_me910_dual_modem_blacklist = { +- .sendsetup = BIT(0), +- .reserved = BIT(3), +-}; +- +-static const struct option_blacklist_info telit_le910_blacklist = { +- .sendsetup = BIT(0), +- .reserved = BIT(1) | BIT(2), +-}; +- +-static const struct option_blacklist_info telit_le920_blacklist = { +- .sendsetup = BIT(0), +- .reserved = BIT(1) | BIT(5), +-}; +- +-static const struct option_blacklist_info telit_le920a4_blacklist_1 = { +- .sendsetup = BIT(0), +- .reserved = BIT(1), +-}; +- +-static const struct option_blacklist_info telit_le922_blacklist_usbcfg0 = { +- .sendsetup = BIT(2), +- .reserved = BIT(0) | BIT(1) | BIT(3), +-}; +- +-static const struct option_blacklist_info telit_le922_blacklist_usbcfg3 = { +- .sendsetup = BIT(0), +- .reserved = BIT(1) | BIT(2) | BIT(3), +-}; +- +-static const struct option_blacklist_info cinterion_rmnet2_blacklist = { +- .reserved = BIT(4) | BIT(5), +-}; +- +-static const struct option_blacklist_info yuga_clm920_nc5_blacklist = { +- .reserved = BIT(1) | BIT(4), +-}; + + static const struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, +@@ -724,26 +595,26 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, + { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S6, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, ++ .driver_info = RSVD(1) | RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, ++ .driver_info = RSVD(1) | RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff), /* Huawei E1820 */ +- .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, ++ .driver_info = RSVD(1) | RSVD(2) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) }, +@@ -1188,65 +1059,70 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ + { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, 0x6001, 0xff, 0xff, 0xff), /* 4G LTE usb-modem U901 */ +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ + /* Quectel products using Qualcomm vendor ID */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, + { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + /* Yuga products use Qualcomm vendor ID */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5), +- .driver_info = (kernel_ulong_t)&yuga_clm920_nc5_blacklist }, ++ .driver_info = RSVD(1) | RSVD(4) }, ++ /* u-blox products using Qualcomm vendor ID */ ++ { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M), ++ .driver_info = RSVD(1) | RSVD(3) }, + /* Quectel products using Quectel vendor ID */ + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, ++ { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06), ++ .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6004) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6005) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_628A) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHE_628S), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_301), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628S) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_680) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_685A) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720S), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7002), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629K), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7004), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7005) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_629), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629S), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720I), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7212), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7213), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7251), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7252), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7253), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, +@@ -1254,38 +1130,38 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, ++ .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1), +- .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG2), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, ++ .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), +- .driver_info = (kernel_ulong_t)&telit_me910_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), +- .driver_info = (kernel_ulong_t)&telit_me910_dual_modem_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), +- .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), +- .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(5) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1207) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1208), +- .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, ++ .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1211), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1212), +- .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, ++ .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) }, +@@ -1301,58 +1177,58 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, +- 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mf626_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff), ++ .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_0037_blacklist }, ++ .driver_info = NCTRL(0) | NCTRL(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, +@@ -1377,26 +1253,26 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0135, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0136, 0xff, 0xff, 0xff) }, +@@ -1412,50 +1288,50 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0196, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0197, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */ +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0200, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0201, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0254, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0265, 0xff, 0xff, 0xff), /* ONDA MT8205 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff), /* ZTE MF880 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0317, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0412, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, +@@ -1572,23 +1448,23 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_1255_blacklist }, ++ .driver_info = RSVD(3) | RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, +@@ -1603,7 +1479,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) }, +@@ -1639,17 +1515,17 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1303, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1333, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */ +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) }, +@@ -1667,8 +1543,8 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1596, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1598, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1600, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, +- 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff), ++ .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, + + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ +@@ -1679,20 +1555,20 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff42, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff43, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff44, 0xff, 0xff, 0xff) }, +@@ -1844,19 +1720,19 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, ++ .driver_info = NCTRL(1) | NCTRL(2) | NCTRL(3) | NCTRL(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, ++ .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, ++ .driver_info = NCTRL(1) | NCTRL(2) | NCTRL(3) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_L), +- .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist }, ++ .driver_info = RSVD(3) | RSVD(4) | RSVD(5) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_MBIM), +- .driver_info = (kernel_ulong_t)&zte_me3620_mbim_blacklist }, ++ .driver_info = RSVD(2) | RSVD(3) | RSVD(4) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_X), +- .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist }, ++ .driver_info = RSVD(3) | RSVD(4) | RSVD(5) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ZM8620_X), +- .driver_info = (kernel_ulong_t)&zte_zm8620_x_blacklist }, ++ .driver_info = RSVD(3) | RSVD(4) | RSVD(5) }, + { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, + { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, + { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, +@@ -1876,37 +1752,34 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) }, + { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, + { USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E), +- .driver_info = (kernel_ulong_t)&simcom_sim7100e_blacklist }, ++ .driver_info = RSVD(5) | RSVD(6) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), +- .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist +- }, ++ .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0052), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b6), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b7), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L800MA), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, + { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), +- .driver_info = (kernel_ulong_t)&four_g_w14_blacklist +- }, ++ .driver_info = NCTRL(0) | NCTRL(1) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100), +- .driver_info = (kernel_ulong_t)&four_g_w100_blacklist +- }, ++ .driver_info = NCTRL(1) | NCTRL(2) | RSVD(3) }, + {USB_DEVICE(LONGCHEER_VENDOR_ID, FUJISOFT_PRODUCT_FS040U), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist}, ++ .driver_info = RSVD(3)}, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9801, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) }, + { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, +@@ -1932,14 +1805,14 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_2RMNET, 0xff), +- .driver_info = (kernel_ulong_t)&cinterion_rmnet2_blacklist }, ++ .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_AUDIO, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, +@@ -1949,20 +1822,20 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */ + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD140), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD155), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD160), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD500), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ + { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, +@@ -2039,9 +1912,9 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, + { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */ + { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */ +@@ -2052,9 +1925,9 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */ +@@ -2114,7 +1987,7 @@ static int option_probe(struct usb_serial *serial, + struct usb_interface_descriptor *iface_desc = + &serial->interface->cur_altsetting->desc; + struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; +- const struct option_blacklist_info *blacklist; ++ unsigned long device_flags = id->driver_info; + + /* Never bind to the CD-Rom emulation interface */ + if (iface_desc->bInterfaceClass == 0x08) +@@ -2125,9 +1998,7 @@ static int option_probe(struct usb_serial *serial, + * the same class/subclass/protocol as the serial interfaces. Look at + * the Windows driver .INF files for reserved interface numbers. + */ +- blacklist = (void *)id->driver_info; +- if (blacklist && test_bit(iface_desc->bInterfaceNumber, +- &blacklist->reserved)) ++ if (device_flags & RSVD(iface_desc->bInterfaceNumber)) + return -ENODEV; + /* + * Don't bind network interface on Samsung GT-B3730, it is handled by +@@ -2138,8 +2009,8 @@ static int option_probe(struct usb_serial *serial, + iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) + return -ENODEV; + +- /* Store the blacklist info so we can use it during attach. */ +- usb_set_serial_data(serial, (void *)blacklist); ++ /* Store the device flags so we can use them during attach. */ ++ usb_set_serial_data(serial, (void *)device_flags); + + return 0; + } +@@ -2147,22 +2018,21 @@ static int option_probe(struct usb_serial *serial, + static int option_attach(struct usb_serial *serial) + { + struct usb_interface_descriptor *iface_desc; +- const struct option_blacklist_info *blacklist; + struct usb_wwan_intf_private *data; ++ unsigned long device_flags; + + data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); + if (!data) + return -ENOMEM; + +- /* Retrieve blacklist info stored at probe. */ +- blacklist = usb_get_serial_data(serial); ++ /* Retrieve device flags stored at probe. */ ++ device_flags = (unsigned long)usb_get_serial_data(serial); + + iface_desc = &serial->interface->cur_altsetting->desc; + +- if (!blacklist || !test_bit(iface_desc->bInterfaceNumber, +- &blacklist->sendsetup)) { ++ if (!(device_flags & NCTRL(iface_desc->bInterfaceNumber))) + data->use_send_setup = 1; +- } ++ + spin_lock_init(&data->susp_lock); + + usb_set_serial_data(serial, data); +diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c +index 337a0be89fcf..dbc3801b43eb 100644 +--- a/drivers/usb/serial/visor.c ++++ b/drivers/usb/serial/visor.c +@@ -338,47 +338,48 @@ static int palm_os_3_probe(struct usb_serial *serial, + goto exit; + } + +- if (retval == sizeof(*connection_info)) { +- connection_info = (struct visor_connection_info *) +- transfer_buffer; +- +- num_ports = le16_to_cpu(connection_info->num_ports); +- for (i = 0; i < num_ports; ++i) { +- switch ( +- connection_info->connections[i].port_function_id) { +- case VISOR_FUNCTION_GENERIC: +- string = "Generic"; +- break; +- case VISOR_FUNCTION_DEBUGGER: +- string = "Debugger"; +- break; +- case VISOR_FUNCTION_HOTSYNC: +- string = "HotSync"; +- break; +- case VISOR_FUNCTION_CONSOLE: +- string = "Console"; +- break; +- case VISOR_FUNCTION_REMOTE_FILE_SYS: +- string = "Remote File System"; +- break; +- default: +- string = "unknown"; +- break; +- } +- dev_info(dev, "%s: port %d, is for %s use\n", +- serial->type->description, +- connection_info->connections[i].port, string); +- } ++ if (retval != sizeof(*connection_info)) { ++ dev_err(dev, "Invalid connection information received from device\n"); ++ retval = -ENODEV; ++ goto exit; + } +- /* +- * Handle devices that report invalid stuff here. +- */ ++ ++ connection_info = (struct visor_connection_info *)transfer_buffer; ++ ++ num_ports = le16_to_cpu(connection_info->num_ports); ++ ++ /* Handle devices that report invalid stuff here. */ + if (num_ports == 0 || num_ports > 2) { + dev_warn(dev, "%s: No valid connect info available\n", + serial->type->description); + num_ports = 2; + } + ++ for (i = 0; i < num_ports; ++i) { ++ switch (connection_info->connections[i].port_function_id) { ++ case VISOR_FUNCTION_GENERIC: ++ string = "Generic"; ++ break; ++ case VISOR_FUNCTION_DEBUGGER: ++ string = "Debugger"; ++ break; ++ case VISOR_FUNCTION_HOTSYNC: ++ string = "HotSync"; ++ break; ++ case VISOR_FUNCTION_CONSOLE: ++ string = "Console"; ++ break; ++ case VISOR_FUNCTION_REMOTE_FILE_SYS: ++ string = "Remote File System"; ++ break; ++ default: ++ string = "unknown"; ++ break; ++ } ++ dev_info(dev, "%s: port %d, is for %s use\n", ++ serial->type->description, ++ connection_info->connections[i].port, string); ++ } + dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, + num_ports); + +diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c +index 0fe667875852..cfb75dbb96f5 100644 +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -1906,7 +1906,7 @@ void wb_workfn(struct work_struct *work) + } + + if (!list_empty(&wb->work_list)) +- mod_delayed_work(bdi_wq, &wb->dwork, 0); ++ wb_wakeup(wb); + else if (wb_has_dirty_io(wb) && dirty_writeback_interval) + wb_wakeup_delayed(wb); + +diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c +index 3dd47307363f..e917aec4babe 100644 +--- a/fs/xfs/xfs_file.c ++++ b/fs/xfs/xfs_file.c +@@ -969,22 +969,26 @@ xfs_file_fallocate( + if (error) + goto out_unlock; + } else if (mode & FALLOC_FL_INSERT_RANGE) { +- unsigned int blksize_mask = i_blocksize(inode) - 1; ++ unsigned int blksize_mask = i_blocksize(inode) - 1; ++ loff_t isize = i_size_read(inode); + +- new_size = i_size_read(inode) + len; + if (offset & blksize_mask || len & blksize_mask) { + error = -EINVAL; + goto out_unlock; + } + +- /* check the new inode size does not wrap through zero */ +- if (new_size > inode->i_sb->s_maxbytes) { ++ /* ++ * New inode size must not exceed ->s_maxbytes, accounting for ++ * possible signed overflow. ++ */ ++ if (inode->i_sb->s_maxbytes - isize < len) { + error = -EFBIG; + goto out_unlock; + } ++ new_size = isize + len; + + /* Offset should be less than i_size */ +- if (offset >= i_size_read(inode)) { ++ if (offset >= isize) { + error = -EINVAL; + goto out_unlock; + } +diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h +index c9b3eb70f340..567017b5fc9e 100644 +--- a/include/net/inet_timewait_sock.h ++++ b/include/net/inet_timewait_sock.h +@@ -55,6 +55,7 @@ struct inet_timewait_sock { + #define tw_family __tw_common.skc_family + #define tw_state __tw_common.skc_state + #define tw_reuse __tw_common.skc_reuse ++#define tw_reuseport __tw_common.skc_reuseport + #define tw_ipv6only __tw_common.skc_ipv6only + #define tw_bound_dev_if __tw_common.skc_bound_dev_if + #define tw_node __tw_common.skc_nulls_node +diff --git a/include/net/mac80211.h b/include/net/mac80211.h +index 4e51f9a5a177..7a49a31f6ddc 100644 +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -975,7 +975,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) + * @RX_FLAG_DECRYPTED: This frame was decrypted in hardware. + * @RX_FLAG_MMIC_STRIPPED: the Michael MIC is stripped off this frame, + * verification has been done by the hardware. +- * @RX_FLAG_IV_STRIPPED: The IV/ICV are stripped from this frame. ++ * @RX_FLAG_IV_STRIPPED: The IV and ICV are stripped from this frame. + * If this flag is set, the stack cannot do any replay detection + * hence the driver or hardware will have to do that. + * @RX_FLAG_PN_VALIDATED: Currently only valid for CCMP/GCMP frames, this +@@ -1013,6 +1013,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) + * on this subframe + * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC + * is stored in the @ampdu_delimiter_crc field) ++ * @RX_FLAG_MIC_STRIPPED: The mic was stripped of this packet. Decryption was ++ * done by the hardware + * @RX_FLAG_LDPC: LDPC was used + * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3 + * @RX_FLAG_10MHZ: 10 MHz (half channel) was used +@@ -1029,6 +1031,11 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) + * @RX_FLAG_RADIOTAP_VENDOR_DATA: This frame contains vendor-specific + * radiotap data in the skb->data (before the frame) as described by + * the &struct ieee80211_vendor_radiotap. ++ * @RX_FLAG_ALLOW_SAME_PN: Allow the same PN as same packet before. ++ * This is used for AMSDU subframes which can have the same PN as ++ * the first subframe. ++ * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must ++ * be done in the hardware. + */ + enum mac80211_rx_flags { + RX_FLAG_MMIC_ERROR = BIT(0), +@@ -1059,6 +1066,9 @@ enum mac80211_rx_flags { + RX_FLAG_5MHZ = BIT(29), + RX_FLAG_AMSDU_MORE = BIT(30), + RX_FLAG_RADIOTAP_VENDOR_DATA = BIT(31), ++ RX_FLAG_MIC_STRIPPED = BIT_ULL(32), ++ RX_FLAG_ALLOW_SAME_PN = BIT_ULL(33), ++ RX_FLAG_ICV_STRIPPED = BIT_ULL(34), + }; + + #define RX_FLAG_STBC_SHIFT 26 +@@ -1113,7 +1123,7 @@ struct ieee80211_rx_status { + u64 mactime; + u32 device_timestamp; + u32 ampdu_reference; +- u32 flag; ++ u64 flag; + u16 freq; + u8 vht_flag; + u8 rate_idx; +diff --git a/include/net/nexthop.h b/include/net/nexthop.h +index 3334dbfa5aa4..7fc78663ec9d 100644 +--- a/include/net/nexthop.h ++++ b/include/net/nexthop.h +@@ -6,7 +6,7 @@ + + static inline int rtnh_ok(const struct rtnexthop *rtnh, int remaining) + { +- return remaining >= sizeof(*rtnh) && ++ return remaining >= (int)sizeof(*rtnh) && + rtnh->rtnh_len >= sizeof(*rtnh) && + rtnh->rtnh_len <= remaining; + } +diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c +index 3608fa1aec8a..0eb11b4ac4c7 100644 +--- a/kernel/bpf/arraymap.c ++++ b/kernel/bpf/arraymap.c +@@ -102,7 +102,7 @@ static void *array_map_lookup_elem(struct bpf_map *map, void *key) + static int array_map_get_next_key(struct bpf_map *map, void *key, void *next_key) + { + struct bpf_array *array = container_of(map, struct bpf_array, map); +- u32 index = *(u32 *)key; ++ u32 index = key ? *(u32 *)key : U32_MAX; + u32 *next = (u32 *)next_key; + + if (index >= array->map.max_entries) { +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index 34777b3746fa..a35abe048239 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -169,12 +169,15 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key) + struct hlist_head *head; + struct htab_elem *l, *next_l; + u32 hash, key_size; +- int i; ++ int i = 0; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + key_size = map->key_size; + ++ if (!key) ++ goto find_first_elem; ++ + hash = htab_map_hash(key, key_size); + + head = select_bucket(htab, hash); +@@ -182,10 +185,8 @@ static int htab_map_get_next_key(struct bpf_map *map, void *key, void *next_key) + /* lookup the key */ + l = lookup_elem_raw(head, hash, key, key_size); + +- if (!l) { +- i = 0; ++ if (!l) + goto find_first_elem; +- } + + /* key was found, get next key in the same bucket */ + next_l = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(&l->hash_node)), +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index dc19b6e210e6..4b9bbfe764e8 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -390,14 +390,18 @@ static int map_get_next_key(union bpf_attr *attr) + if (IS_ERR(map)) + return PTR_ERR(map); + +- err = -ENOMEM; +- key = kmalloc(map->key_size, GFP_USER); +- if (!key) +- goto err_put; +- +- err = -EFAULT; +- if (copy_from_user(key, ukey, map->key_size) != 0) +- goto free_key; ++ if (ukey) { ++ err = -ENOMEM; ++ key = kmalloc(map->key_size, GFP_USER); ++ if (!key) ++ goto err_put; ++ ++ err = -EFAULT; ++ if (copy_from_user(key, ukey, map->key_size) != 0) ++ goto free_key; ++ } else { ++ key = NULL; ++ } + + err = -ENOMEM; + next_key = kmalloc(map->key_size, GFP_USER); +diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c +index 9c418002b8c1..75f835d353db 100644 +--- a/kernel/events/callchain.c ++++ b/kernel/events/callchain.c +@@ -107,14 +107,8 @@ int get_callchain_buffers(void) + goto exit; + } + +- if (count > 1) { +- /* If the allocation failed, give up */ +- if (!callchain_cpus_entries) +- err = -ENOMEM; +- goto exit; +- } +- +- err = alloc_callchain_buffers(); ++ if (count == 1) ++ err = alloc_callchain_buffers(); + exit: + if (err) + atomic_dec(&nr_callchain_events); +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 6aeb0ef4fe70..92d1f12f4407 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -229,7 +229,7 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) + { +- int ret = proc_dointvec(table, write, buffer, lenp, ppos); ++ int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + + if (ret || !write) + return ret; +diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c +index 014b69528194..58013ef228a1 100644 +--- a/kernel/events/ring_buffer.c ++++ b/kernel/events/ring_buffer.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + #include "internal.h" + +@@ -779,8 +780,10 @@ perf_mmap_to_page(struct ring_buffer *rb, unsigned long pgoff) + return NULL; + + /* AUX space */ +- if (pgoff >= rb->aux_pgoff) +- return virt_to_page(rb->aux_pages[pgoff - rb->aux_pgoff]); ++ if (pgoff >= rb->aux_pgoff) { ++ int aux_pgoff = array_index_nospec(pgoff - rb->aux_pgoff, rb->aux_nr_pages); ++ return virt_to_page(rb->aux_pages[aux_pgoff]); ++ } + } + + return __perf_mmap_to_page(rb, pgoff); +diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c +index f0e5408499b6..1ab2db6c127b 100644 +--- a/kernel/trace/trace_events_filter.c ++++ b/kernel/trace/trace_events_filter.c +@@ -322,6 +322,9 @@ static int regex_match_full(char *str, struct regex *r, int len) + + static int regex_match_front(char *str, struct regex *r, int len) + { ++ if (len < r->len) ++ return 0; ++ + if (strncmp(str, r->pattern, r->len) == 0) + return 1; + return 0; +diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c +index d2f6d0be3503..68bb89ad9d28 100644 +--- a/kernel/trace/trace_uprobe.c ++++ b/kernel/trace/trace_uprobe.c +@@ -149,6 +149,8 @@ static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, + return; + + ret = strncpy_from_user(dst, src, maxlen); ++ if (ret == maxlen) ++ dst[--ret] = '\0'; + + if (ret < 0) { /* Failed to fetch string */ + ((u8 *)get_rloc_data(dest))[0] = '\0'; +diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c +index ecd536de603a..eda85bbf1c2e 100644 +--- a/kernel/tracepoint.c ++++ b/kernel/tracepoint.c +@@ -202,7 +202,7 @@ static int tracepoint_add_func(struct tracepoint *tp, + lockdep_is_held(&tracepoints_mutex)); + old = func_add(&tp_funcs, func, prio); + if (IS_ERR(old)) { +- WARN_ON_ONCE(1); ++ WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM); + return PTR_ERR(old); + } + +@@ -235,7 +235,7 @@ static int tracepoint_remove_func(struct tracepoint *tp, + lockdep_is_held(&tracepoints_mutex)); + old = func_remove(&tp_funcs, func); + if (IS_ERR(old)) { +- WARN_ON_ONCE(1); ++ WARN_ON_ONCE(PTR_ERR(old) != -ENOMEM); + return PTR_ERR(old); + } + +diff --git a/mm/percpu.c b/mm/percpu.c +index ef6353f0adbd..1c784df3bdfe 100644 +--- a/mm/percpu.c ++++ b/mm/percpu.c +@@ -68,6 +68,7 @@ + #include + #include + #include ++#include + + #include + #include +diff --git a/net/atm/lec.c b/net/atm/lec.c +index cd3b37989057..10e4066991b8 100644 +--- a/net/atm/lec.c ++++ b/net/atm/lec.c +@@ -41,6 +41,9 @@ static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 }; + #include + #include + ++/* Hardening for Spectre-v1 */ ++#include ++ + #include "lec.h" + #include "lec_arpc.h" + #include "resources.h" +@@ -697,8 +700,10 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) + bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc)); + if (bytes_left != 0) + pr_info("copy from user failed for %d bytes\n", bytes_left); +- if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF || +- !dev_lec[ioc_data.dev_num]) ++ if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF) ++ return -EINVAL; ++ ioc_data.dev_num = array_index_nospec(ioc_data.dev_num, MAX_LEC_ITF); ++ if (!dev_lec[ioc_data.dev_num]) + return -EINVAL; + vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL); + if (!vpriv) +diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c +index c0548d268e1a..e3e6a3e2ca22 100644 +--- a/net/core/dev_addr_lists.c ++++ b/net/core/dev_addr_lists.c +@@ -57,8 +57,8 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, + return -EINVAL; + + list_for_each_entry(ha, &list->list, list) { +- if (!memcmp(ha->addr, addr, addr_len) && +- ha->type == addr_type) { ++ if (ha->type == addr_type && ++ !memcmp(ha->addr, addr, addr_len)) { + if (global) { + /* check if addr is already used as global */ + if (ha->global_use) +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index 7d3442594e0d..5668dd3f9969 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -827,6 +827,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) + n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; + n->cloned = 1; + n->nohdr = 0; ++ n->peeked = 0; + n->destructor = NULL; + C(tail); + C(end); +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index 6eb2bbf9873b..45fd82e61e79 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -618,6 +618,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) + ireq = inet_rsk(req); + sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); + sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); ++ ireq->ir_mark = inet_request_mark(sk, skb); + ireq->ireq_family = AF_INET; + ireq->ir_iif = sk->sk_bound_dev_if; + +diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c +index 09a9ab65f4e1..0bf41faeffc4 100644 +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -345,6 +345,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) + ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr; + ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr; + ireq->ireq_family = AF_INET6; ++ ireq->ir_mark = inet_request_mark(sk, skb); + + if (ipv6_opt_accepted(sk, skb, IP6CB(skb)) || + np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || +diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c +index c67f9bd7699c..d8316869947a 100644 +--- a/net/ipv4/inet_timewait_sock.c ++++ b/net/ipv4/inet_timewait_sock.c +@@ -182,6 +182,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, + tw->tw_dport = inet->inet_dport; + tw->tw_family = sk->sk_family; + tw->tw_reuse = sk->sk_reuse; ++ tw->tw_reuseport = sk->sk_reuseport; + tw->tw_hash = sk->sk_hash; + tw->tw_ipv6only = 0; + tw->tw_transparent = inet->transparent; +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 82d2b55c953a..b531a0997664 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2450,7 +2450,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, + case TCP_REPAIR_QUEUE: + if (!tp->repair) + err = -EPERM; +- else if (val < TCP_QUEUES_NR) ++ else if ((unsigned int)val < TCP_QUEUES_NR) + tp->repair_queue = val; + else + err = -EINVAL; +diff --git a/net/mac80211/util.c b/net/mac80211/util.c +index 33344f5a66a8..ec26a84b00e2 100644 +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -2663,8 +2663,9 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, + + rate = cfg80211_calculate_bitrate(&ri); + if (WARN_ONCE(!rate, +- "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n", +- status->flag, status->rate_idx, status->vht_nss)) ++ "Invalid bitrate: flags=0x%llx, idx=%d, vht_nss=%d\n", ++ (unsigned long long)status->flag, status->rate_idx, ++ status->vht_nss)) + return 0; + + /* rewind from end of MPDU */ +diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c +index efa3f48f1ec5..73e8f347802e 100644 +--- a/net/mac80211/wep.c ++++ b/net/mac80211/wep.c +@@ -293,7 +293,8 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) + return RX_DROP_UNUSABLE; + ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); + /* remove ICV */ +- if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN)) ++ if (!(status->flag & RX_FLAG_ICV_STRIPPED) && ++ pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN)) + return RX_DROP_UNUSABLE; + } + +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index e19ea1c53afa..cb439e06919f 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -298,7 +298,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) + return RX_DROP_UNUSABLE; + + /* Trim ICV */ +- skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN); ++ if (!(status->flag & RX_FLAG_ICV_STRIPPED)) ++ skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN); + + /* Remove IV */ + memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen); +@@ -508,25 +509,31 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, + !ieee80211_is_robust_mgmt_frame(skb)) + return RX_CONTINUE; + +- data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len; +- if (!rx->sta || data_len < 0) +- return RX_DROP_UNUSABLE; +- + if (status->flag & RX_FLAG_DECRYPTED) { + if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN)) + return RX_DROP_UNUSABLE; ++ if (status->flag & RX_FLAG_MIC_STRIPPED) ++ mic_len = 0; + } else { + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + } + ++ data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len; ++ if (!rx->sta || data_len < 0) ++ return RX_DROP_UNUSABLE; ++ + if (!(status->flag & RX_FLAG_PN_VALIDATED)) { ++ int res; ++ + ccmp_hdr2pn(pn, skb->data + hdrlen); + + queue = rx->security_idx; + +- if (memcmp(pn, key->u.ccmp.rx_pn[queue], +- IEEE80211_CCMP_PN_LEN) <= 0) { ++ res = memcmp(pn, key->u.ccmp.rx_pn[queue], ++ IEEE80211_CCMP_PN_LEN); ++ if (res < 0 || ++ (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) { + key->u.ccmp.replays++; + return RX_DROP_UNUSABLE; + } +@@ -724,8 +731,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) + struct sk_buff *skb = rx->skb; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + u8 pn[IEEE80211_GCMP_PN_LEN]; +- int data_len; +- int queue; ++ int data_len, queue, mic_len = IEEE80211_GCMP_MIC_LEN; + + hdrlen = ieee80211_hdrlen(hdr->frame_control); + +@@ -733,26 +739,31 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) + !ieee80211_is_robust_mgmt_frame(skb)) + return RX_CONTINUE; + +- data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - +- IEEE80211_GCMP_MIC_LEN; +- if (!rx->sta || data_len < 0) +- return RX_DROP_UNUSABLE; +- + if (status->flag & RX_FLAG_DECRYPTED) { + if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN)) + return RX_DROP_UNUSABLE; ++ if (status->flag & RX_FLAG_MIC_STRIPPED) ++ mic_len = 0; + } else { + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + } + ++ data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - mic_len; ++ if (!rx->sta || data_len < 0) ++ return RX_DROP_UNUSABLE; ++ + if (!(status->flag & RX_FLAG_PN_VALIDATED)) { ++ int res; ++ + gcmp_hdr2pn(pn, skb->data + hdrlen); + + queue = rx->security_idx; + +- if (memcmp(pn, key->u.gcmp.rx_pn[queue], +- IEEE80211_GCMP_PN_LEN) <= 0) { ++ res = memcmp(pn, key->u.gcmp.rx_pn[queue], ++ IEEE80211_GCMP_PN_LEN); ++ if (res < 0 || ++ (!res && !(status->flag & RX_FLAG_ALLOW_SAME_PN))) { + key->u.gcmp.replays++; + return RX_DROP_UNUSABLE; + } +@@ -776,7 +787,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) + } + + /* Remove GCMP header and MIC */ +- if (pskb_trim(skb, skb->len - IEEE80211_GCMP_MIC_LEN)) ++ if (pskb_trim(skb, skb->len - mic_len)) + return RX_DROP_UNUSABLE; + memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen); + skb_pull(skb, IEEE80211_GCMP_HDR_LEN); +diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c +index 2f0e4f61c40f..c0656510c4dc 100644 +--- a/net/netfilter/ipvs/ip_vs_ctl.c ++++ b/net/netfilter/ipvs/ip_vs_ctl.c +@@ -2352,11 +2352,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) + strlcpy(cfg.mcast_ifn, dm->mcast_ifn, + sizeof(cfg.mcast_ifn)); + cfg.syncid = dm->syncid; +- rtnl_lock(); +- mutex_lock(&ipvs->sync_mutex); + ret = start_sync_thread(ipvs, &cfg, dm->state); +- mutex_unlock(&ipvs->sync_mutex); +- rtnl_unlock(); + } else { + mutex_lock(&ipvs->sync_mutex); + ret = stop_sync_thread(ipvs, dm->state); +@@ -3435,12 +3431,8 @@ static int ip_vs_genl_new_daemon(struct netns_ipvs *ipvs, struct nlattr **attrs) + if (ipvs->mixed_address_family_dests > 0) + return -EINVAL; + +- rtnl_lock(); +- mutex_lock(&ipvs->sync_mutex); + ret = start_sync_thread(ipvs, &c, + nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE])); +- mutex_unlock(&ipvs->sync_mutex); +- rtnl_unlock(); + return ret; + } + +diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c +index 1b07578bedf3..cec7234b7a1d 100644 +--- a/net/netfilter/ipvs/ip_vs_sync.c ++++ b/net/netfilter/ipvs/ip_vs_sync.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + #include /* Used for ntoh_seq and hton_seq */ + +@@ -1356,15 +1357,9 @@ static void set_mcast_pmtudisc(struct sock *sk, int val) + /* + * Specifiy default interface for outgoing multicasts + */ +-static int set_mcast_if(struct sock *sk, char *ifname) ++static int set_mcast_if(struct sock *sk, struct net_device *dev) + { +- struct net_device *dev; + struct inet_sock *inet = inet_sk(sk); +- struct net *net = sock_net(sk); +- +- dev = __dev_get_by_name(net, ifname); +- if (!dev) +- return -ENODEV; + + if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if) + return -EINVAL; +@@ -1392,19 +1387,14 @@ static int set_mcast_if(struct sock *sk, char *ifname) + * in the in_addr structure passed in as a parameter. + */ + static int +-join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname) ++join_mcast_group(struct sock *sk, struct in_addr *addr, struct net_device *dev) + { +- struct net *net = sock_net(sk); + struct ip_mreqn mreq; +- struct net_device *dev; + int ret; + + memset(&mreq, 0, sizeof(mreq)); + memcpy(&mreq.imr_multiaddr, addr, sizeof(struct in_addr)); + +- dev = __dev_get_by_name(net, ifname); +- if (!dev) +- return -ENODEV; + if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if) + return -EINVAL; + +@@ -1419,15 +1409,10 @@ join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname) + + #ifdef CONFIG_IP_VS_IPV6 + static int join_mcast_group6(struct sock *sk, struct in6_addr *addr, +- char *ifname) ++ struct net_device *dev) + { +- struct net *net = sock_net(sk); +- struct net_device *dev; + int ret; + +- dev = __dev_get_by_name(net, ifname); +- if (!dev) +- return -ENODEV; + if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if) + return -EINVAL; + +@@ -1439,24 +1424,18 @@ static int join_mcast_group6(struct sock *sk, struct in6_addr *addr, + } + #endif + +-static int bind_mcastif_addr(struct socket *sock, char *ifname) ++static int bind_mcastif_addr(struct socket *sock, struct net_device *dev) + { +- struct net *net = sock_net(sock->sk); +- struct net_device *dev; + __be32 addr; + struct sockaddr_in sin; + +- dev = __dev_get_by_name(net, ifname); +- if (!dev) +- return -ENODEV; +- + addr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE); + if (!addr) + pr_err("You probably need to specify IP address on " + "multicast interface.\n"); + + IP_VS_DBG(7, "binding socket with (%s) %pI4\n", +- ifname, &addr); ++ dev->name, &addr); + + /* Now bind the socket with the address of multicast interface */ + sin.sin_family = AF_INET; +@@ -1489,7 +1468,8 @@ static void get_mcast_sockaddr(union ipvs_sockaddr *sa, int *salen, + /* + * Set up sending multicast socket over UDP + */ +-static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id) ++static int make_send_sock(struct netns_ipvs *ipvs, int id, ++ struct net_device *dev, struct socket **sock_ret) + { + /* multicast addr */ + union ipvs_sockaddr mcast_addr; +@@ -1501,9 +1481,10 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id) + IPPROTO_UDP, &sock); + if (result < 0) { + pr_err("Error during creation of socket; terminating\n"); +- return ERR_PTR(result); ++ goto error; + } +- result = set_mcast_if(sock->sk, ipvs->mcfg.mcast_ifn); ++ *sock_ret = sock; ++ result = set_mcast_if(sock->sk, dev); + if (result < 0) { + pr_err("Error setting outbound mcast interface\n"); + goto error; +@@ -1518,7 +1499,7 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id) + set_sock_size(sock->sk, 1, result); + + if (AF_INET == ipvs->mcfg.mcast_af) +- result = bind_mcastif_addr(sock, ipvs->mcfg.mcast_ifn); ++ result = bind_mcastif_addr(sock, dev); + else + result = 0; + if (result < 0) { +@@ -1534,19 +1515,18 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id) + goto error; + } + +- return sock; ++ return 0; + + error: +- sock_release(sock); +- return ERR_PTR(result); ++ return result; + } + + + /* + * Set up receiving multicast socket over UDP + */ +-static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id, +- int ifindex) ++static int make_receive_sock(struct netns_ipvs *ipvs, int id, ++ struct net_device *dev, struct socket **sock_ret) + { + /* multicast addr */ + union ipvs_sockaddr mcast_addr; +@@ -1558,8 +1538,9 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id, + IPPROTO_UDP, &sock); + if (result < 0) { + pr_err("Error during creation of socket; terminating\n"); +- return ERR_PTR(result); ++ goto error; + } ++ *sock_ret = sock; + /* it is equivalent to the REUSEADDR option in user-space */ + sock->sk->sk_reuse = SK_CAN_REUSE; + result = sysctl_sync_sock_size(ipvs); +@@ -1567,7 +1548,7 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id, + set_sock_size(sock->sk, 0, result); + + get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id); +- sock->sk->sk_bound_dev_if = ifindex; ++ sock->sk->sk_bound_dev_if = dev->ifindex; + result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen); + if (result < 0) { + pr_err("Error binding to the multicast addr\n"); +@@ -1578,21 +1559,20 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id, + #ifdef CONFIG_IP_VS_IPV6 + if (ipvs->bcfg.mcast_af == AF_INET6) + result = join_mcast_group6(sock->sk, &mcast_addr.in6.sin6_addr, +- ipvs->bcfg.mcast_ifn); ++ dev); + else + #endif + result = join_mcast_group(sock->sk, &mcast_addr.in.sin_addr, +- ipvs->bcfg.mcast_ifn); ++ dev); + if (result < 0) { + pr_err("Error joining to the multicast group\n"); + goto error; + } + +- return sock; ++ return 0; + + error: +- sock_release(sock); +- return ERR_PTR(result); ++ return result; + } + + +@@ -1777,13 +1757,12 @@ static int sync_thread_backup(void *data) + int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, + int state) + { +- struct ip_vs_sync_thread_data *tinfo; ++ struct ip_vs_sync_thread_data *tinfo = NULL; + struct task_struct **array = NULL, *task; +- struct socket *sock; + struct net_device *dev; + char *name; + int (*threadfn)(void *data); +- int id, count, hlen; ++ int id = 0, count, hlen; + int result = -ENOMEM; + u16 mtu, min_mtu; + +@@ -1791,6 +1770,18 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, + IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n", + sizeof(struct ip_vs_sync_conn_v0)); + ++ /* Do not hold one mutex and then to block on another */ ++ for (;;) { ++ rtnl_lock(); ++ if (mutex_trylock(&ipvs->sync_mutex)) ++ break; ++ rtnl_unlock(); ++ mutex_lock(&ipvs->sync_mutex); ++ if (rtnl_trylock()) ++ break; ++ mutex_unlock(&ipvs->sync_mutex); ++ } ++ + if (!ipvs->sync_state) { + count = clamp(sysctl_sync_ports(ipvs), 1, IPVS_SYNC_PORTS_MAX); + ipvs->threads_mask = count - 1; +@@ -1809,7 +1800,8 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, + dev = __dev_get_by_name(ipvs->net, c->mcast_ifn); + if (!dev) { + pr_err("Unknown mcast interface: %s\n", c->mcast_ifn); +- return -ENODEV; ++ result = -ENODEV; ++ goto out_early; + } + hlen = (AF_INET6 == c->mcast_af) ? + sizeof(struct ipv6hdr) + sizeof(struct udphdr) : +@@ -1826,26 +1818,30 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, + c->sync_maxlen = mtu - hlen; + + if (state == IP_VS_STATE_MASTER) { ++ result = -EEXIST; + if (ipvs->ms) +- return -EEXIST; ++ goto out_early; + + ipvs->mcfg = *c; + name = "ipvs-m:%d:%d"; + threadfn = sync_thread_master; + } else if (state == IP_VS_STATE_BACKUP) { ++ result = -EEXIST; + if (ipvs->backup_threads) +- return -EEXIST; ++ goto out_early; + + ipvs->bcfg = *c; + name = "ipvs-b:%d:%d"; + threadfn = sync_thread_backup; + } else { +- return -EINVAL; ++ result = -EINVAL; ++ goto out_early; + } + + if (state == IP_VS_STATE_MASTER) { + struct ipvs_master_sync_state *ms; + ++ result = -ENOMEM; + ipvs->ms = kzalloc(count * sizeof(ipvs->ms[0]), GFP_KERNEL); + if (!ipvs->ms) + goto out; +@@ -1861,39 +1857,38 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, + } else { + array = kzalloc(count * sizeof(struct task_struct *), + GFP_KERNEL); ++ result = -ENOMEM; + if (!array) + goto out; + } + +- tinfo = NULL; + for (id = 0; id < count; id++) { +- if (state == IP_VS_STATE_MASTER) +- sock = make_send_sock(ipvs, id); +- else +- sock = make_receive_sock(ipvs, id, dev->ifindex); +- if (IS_ERR(sock)) { +- result = PTR_ERR(sock); +- goto outtinfo; +- } ++ result = -ENOMEM; + tinfo = kmalloc(sizeof(*tinfo), GFP_KERNEL); + if (!tinfo) +- goto outsocket; ++ goto out; + tinfo->ipvs = ipvs; +- tinfo->sock = sock; ++ tinfo->sock = NULL; + if (state == IP_VS_STATE_BACKUP) { + tinfo->buf = kmalloc(ipvs->bcfg.sync_maxlen, + GFP_KERNEL); + if (!tinfo->buf) +- goto outtinfo; ++ goto out; + } else { + tinfo->buf = NULL; + } + tinfo->id = id; ++ if (state == IP_VS_STATE_MASTER) ++ result = make_send_sock(ipvs, id, dev, &tinfo->sock); ++ else ++ result = make_receive_sock(ipvs, id, dev, &tinfo->sock); ++ if (result < 0) ++ goto out; + + task = kthread_run(threadfn, tinfo, name, ipvs->gen, id); + if (IS_ERR(task)) { + result = PTR_ERR(task); +- goto outtinfo; ++ goto out; + } + tinfo = NULL; + if (state == IP_VS_STATE_MASTER) +@@ -1910,20 +1905,20 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, + ipvs->sync_state |= state; + spin_unlock_bh(&ipvs->sync_buff_lock); + ++ mutex_unlock(&ipvs->sync_mutex); ++ rtnl_unlock(); ++ + /* increase the module use count */ + ip_vs_use_count_inc(); + + return 0; + +-outsocket: +- sock_release(sock); +- +-outtinfo: +- if (tinfo) { +- sock_release(tinfo->sock); +- kfree(tinfo->buf); +- kfree(tinfo); +- } ++out: ++ /* We do not need RTNL lock anymore, release it here so that ++ * sock_release below and in the kthreads can use rtnl_lock ++ * to leave the mcast group. ++ */ ++ rtnl_unlock(); + count = id; + while (count-- > 0) { + if (state == IP_VS_STATE_MASTER) +@@ -1931,13 +1926,23 @@ outtinfo: + else + kthread_stop(array[count]); + } +- kfree(array); +- +-out: + if (!(ipvs->sync_state & IP_VS_STATE_MASTER)) { + kfree(ipvs->ms); + ipvs->ms = NULL; + } ++ mutex_unlock(&ipvs->sync_mutex); ++ if (tinfo) { ++ if (tinfo->sock) ++ sock_release(tinfo->sock); ++ kfree(tinfo->buf); ++ kfree(tinfo); ++ } ++ kfree(array); ++ return result; ++ ++out_early: ++ mutex_unlock(&ipvs->sync_mutex); ++ rtnl_unlock(); + return result; + } + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 98fe9691337c..818400fddc9b 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -1795,6 +1795,8 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) + + if (msg->msg_namelen) { + err = -EINVAL; ++ if (msg->msg_namelen < sizeof(struct sockaddr_nl)) ++ goto out; + if (addr->nl_family != AF_NETLINK) + goto out; + dst_portid = addr->nl_pid; +diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c +index 93127220cb54..e6e249cc651c 100644 +--- a/net/rfkill/rfkill-gpio.c ++++ b/net/rfkill/rfkill-gpio.c +@@ -140,13 +140,18 @@ static int rfkill_gpio_probe(struct platform_device *pdev) + + ret = rfkill_register(rfkill->rfkill_dev); + if (ret < 0) +- return ret; ++ goto err_destroy; + + platform_set_drvdata(pdev, rfkill); + + dev_info(&pdev->dev, "%s device registered.\n", rfkill->name); + + return 0; ++ ++err_destroy: ++ rfkill_destroy(rfkill->rfkill_dev); ++ ++ return ret; + } + + static int rfkill_gpio_remove(struct platform_device *pdev) +diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c +index 5d9f25cb6426..90270d7110a3 100644 +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -2480,7 +2480,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + + #ifdef CONFIG_COMPAT + if (is_compat_task()) +- return -ENOTSUPP; ++ return -EOPNOTSUPP; + #endif + + type = nlh->nlmsg_type; +diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c +index 1f64ab0c2a95..7ae080bae15c 100644 +--- a/sound/core/pcm_compat.c ++++ b/sound/core/pcm_compat.c +@@ -426,6 +426,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, + return -ENOTTY; + if (substream->stream != dir) + return -EINVAL; ++ if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) ++ return -EBADFD; + + if ((ch = substream->runtime->channels) > 128) + return -EINVAL; +diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c +index 3b126af4a026..ef494ffc1369 100644 +--- a/sound/core/seq/seq_virmidi.c ++++ b/sound/core/seq/seq_virmidi.c +@@ -174,12 +174,12 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, + } + return; + } ++ spin_lock_irqsave(&substream->runtime->lock, flags); + if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { + if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) +- return; ++ goto out; + vmidi->event.type = SNDRV_SEQ_EVENT_NONE; + } +- spin_lock_irqsave(&substream->runtime->lock, flags); + while (1) { + count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf)); + if (count <= 0) +diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c +index dc91002d1e0d..847f70348d4d 100644 +--- a/sound/drivers/aloop.c ++++ b/sound/drivers/aloop.c +@@ -296,6 +296,8 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) + cable->pause |= stream; + loopback_timer_stop(dpcm); + spin_unlock(&cable->lock); ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ loopback_active_notify(dpcm); + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: +@@ -304,6 +306,8 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) + cable->pause &= ~stream; + loopback_timer_start(dpcm); + spin_unlock(&cable->lock); ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ loopback_active_notify(dpcm); + break; + default: + return -EINVAL; +@@ -828,9 +832,11 @@ static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol, + { + struct loopback *loopback = snd_kcontrol_chip(kcontrol); + ++ mutex_lock(&loopback->cable_lock); + ucontrol->value.integer.value[0] = + loopback->setup[kcontrol->id.subdevice] + [kcontrol->id.device].rate_shift; ++ mutex_unlock(&loopback->cable_lock); + return 0; + } + +@@ -862,9 +868,11 @@ static int loopback_notify_get(struct snd_kcontrol *kcontrol, + { + struct loopback *loopback = snd_kcontrol_chip(kcontrol); + ++ mutex_lock(&loopback->cable_lock); + ucontrol->value.integer.value[0] = + loopback->setup[kcontrol->id.subdevice] + [kcontrol->id.device].notify; ++ mutex_unlock(&loopback->cable_lock); + return 0; + } + +@@ -876,12 +884,14 @@ static int loopback_notify_put(struct snd_kcontrol *kcontrol, + int change = 0; + + val = ucontrol->value.integer.value[0] ? 1 : 0; ++ mutex_lock(&loopback->cable_lock); + if (val != loopback->setup[kcontrol->id.subdevice] + [kcontrol->id.device].notify) { + loopback->setup[kcontrol->id.subdevice] + [kcontrol->id.device].notify = val; + change = 1; + } ++ mutex_unlock(&loopback->cable_lock); + return change; + } + +@@ -889,13 +899,18 @@ static int loopback_active_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { + struct loopback *loopback = snd_kcontrol_chip(kcontrol); +- struct loopback_cable *cable = loopback->cables +- [kcontrol->id.subdevice][kcontrol->id.device ^ 1]; ++ struct loopback_cable *cable; ++ + unsigned int val = 0; + +- if (cable != NULL) +- val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? +- 1 : 0; ++ mutex_lock(&loopback->cable_lock); ++ cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1]; ++ if (cable != NULL) { ++ unsigned int running = cable->running ^ cable->pause; ++ ++ val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0; ++ } ++ mutex_unlock(&loopback->cable_lock); + ucontrol->value.integer.value[0] = val; + return 0; + } +@@ -938,9 +953,11 @@ static int loopback_rate_get(struct snd_kcontrol *kcontrol, + { + struct loopback *loopback = snd_kcontrol_chip(kcontrol); + ++ mutex_lock(&loopback->cable_lock); + ucontrol->value.integer.value[0] = + loopback->setup[kcontrol->id.subdevice] + [kcontrol->id.device].rate; ++ mutex_unlock(&loopback->cable_lock); + return 0; + } + +@@ -960,9 +977,11 @@ static int loopback_channels_get(struct snd_kcontrol *kcontrol, + { + struct loopback *loopback = snd_kcontrol_chip(kcontrol); + ++ mutex_lock(&loopback->cable_lock); + ucontrol->value.integer.value[0] = + loopback->setup[kcontrol->id.subdevice] + [kcontrol->id.device].channels; ++ mutex_unlock(&loopback->cable_lock); + return 0; + } + +diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh +index 61f9b1dbbd9b..63c310cdac09 100755 +--- a/tools/testing/selftests/firmware/fw_filesystem.sh ++++ b/tools/testing/selftests/firmware/fw_filesystem.sh +@@ -29,9 +29,11 @@ test_finish() + echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout + fi + if [ "$OLD_FWPATH" = "" ]; then +- OLD_FWPATH=" " ++ # A zero-length write won't work; write a null byte ++ printf '\000' >/sys/module/firmware_class/parameters/path ++ else ++ echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path + fi +- echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path + rm -f "$FW" + rmdir "$FWPATH" + } diff --git a/patch/kernel/rk3328-default/04-patch-4.4.133-134.patch b/patch/kernel/rk3328-default/04-patch-4.4.133-134.patch index 471dc559a..6e15b49da 100644 --- a/patch/kernel/rk3328-default/04-patch-4.4.133-134.patch +++ b/patch/kernel/rk3328-default/04-patch-4.4.133-134.patch @@ -4656,34 +4656,6 @@ index 32960b3ecd4f..97472088d65a 100644 if (IS_DIRSYNC(dir)) ext4_handle_sync(handle); -diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c -index 484df6850747..e5553cd8fe4e 100644 ---- a/fs/f2fs/namei.c -+++ b/fs/f2fs/namei.c -@@ -294,7 +294,6 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - - alloc_nid_done(sbi, ino); - -- unlock_new_inode(inode); - d_instantiate(dentry, inode); - - if (IS_DIRSYNC(dir)) -@@ -658,7 +657,6 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) - - alloc_nid_done(sbi, inode->i_ino); - -- unlock_new_inode(inode); - d_instantiate(dentry, inode); - - if (IS_DIRSYNC(dir)) -@@ -710,7 +708,6 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, - - alloc_nid_done(sbi, inode->i_ino); - -- unlock_new_inode(inode); - d_instantiate(dentry, inode); - - if (IS_DIRSYNC(dir)) diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 6b35fc4860a0..1de16a5a5c4e 100644 --- a/fs/fscache/page.c diff --git a/patch/kernel/rk3328-default/04-patch-4.4.137-138.patch b/patch/kernel/rk3328-default/04-patch-4.4.137-138.patch new file mode 100644 index 000000000..3fb702177 --- /dev/null +++ b/patch/kernel/rk3328-default/04-patch-4.4.137-138.patch @@ -0,0 +1,1561 @@ +diff --git a/Makefile b/Makefile +index 44efd1252ab8..1a8c0fc6b997 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 137 ++SUBLEVEL = 138 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/x86/crypto/chacha20_glue.c b/arch/x86/crypto/chacha20_glue.c +index 722bacea040e..8baaff5af0b5 100644 +--- a/arch/x86/crypto/chacha20_glue.c ++++ b/arch/x86/crypto/chacha20_glue.c +@@ -125,7 +125,7 @@ static struct crypto_alg alg = { + + static int __init chacha20_simd_mod_init(void) + { +- if (!cpu_has_ssse3) ++ if (!boot_cpu_has(X86_FEATURE_SSSE3)) + return -ENODEV; + + #ifdef CONFIG_AS_AVX2 +diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c +index 81a595d75cf5..15f5c7675d42 100644 +--- a/arch/x86/crypto/crc32c-intel_glue.c ++++ b/arch/x86/crypto/crc32c-intel_glue.c +@@ -58,16 +58,11 @@ + asmlinkage unsigned int crc_pcl(const u8 *buffer, int len, + unsigned int crc_init); + static int crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_EAGERFPU; +-#if defined(X86_FEATURE_EAGER_FPU) + #define set_pcl_breakeven_point() \ + do { \ + if (!use_eager_fpu()) \ + crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_NOEAGERFPU; \ + } while (0) +-#else +-#define set_pcl_breakeven_point() \ +- (crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_NOEAGERFPU) +-#endif + #endif /* CONFIG_X86_64 */ + + static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length) +@@ -257,7 +252,7 @@ static int __init crc32c_intel_mod_init(void) + if (!x86_match_cpu(crc32c_cpu_id)) + return -ENODEV; + #ifdef CONFIG_X86_64 +- if (cpu_has_pclmulqdq) { ++ if (boot_cpu_has(X86_FEATURE_PCLMULQDQ)) { + alg.update = crc32c_pcl_intel_update; + alg.finup = crc32c_pcl_intel_finup; + alg.digest = crc32c_pcl_intel_digest; +diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h +index f7e142926481..e4959d023af8 100644 +--- a/arch/x86/include/asm/cmpxchg_32.h ++++ b/arch/x86/include/asm/cmpxchg_32.h +@@ -109,6 +109,6 @@ static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new) + + #endif + +-#define system_has_cmpxchg_double() cpu_has_cx8 ++#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX8) + + #endif /* _ASM_X86_CMPXCHG_32_H */ +diff --git a/arch/x86/include/asm/cmpxchg_64.h b/arch/x86/include/asm/cmpxchg_64.h +index 1af94697aae5..caa23a34c963 100644 +--- a/arch/x86/include/asm/cmpxchg_64.h ++++ b/arch/x86/include/asm/cmpxchg_64.h +@@ -18,6 +18,6 @@ static inline void set_64bit(volatile u64 *ptr, u64 val) + cmpxchg_local((ptr), (o), (n)); \ + }) + +-#define system_has_cmpxchg_double() cpu_has_cx16 ++#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX16) + + #endif /* _ASM_X86_CMPXCHG_64_H */ +diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h +index 641f0f2c2982..232621c5e859 100644 +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -104,7 +104,7 @@ + #define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */ + #define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ + #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ +-#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */ ++/* free, was #define X86_FEATURE_EAGER_FPU ( 3*32+29) * "eagerfpu" Non lazy FPU restore */ + #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ + + /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ +@@ -368,58 +368,29 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; + #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit) + + #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) +-#define cpu_has_de boot_cpu_has(X86_FEATURE_DE) + #define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE) + #define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC) + #define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE) + #define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC) +-#define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP) +-#define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR) +-#define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX) + #define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR) + #define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) + #define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2) +-#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3) +-#define cpu_has_ssse3 boot_cpu_has(X86_FEATURE_SSSE3) + #define cpu_has_aes boot_cpu_has(X86_FEATURE_AES) + #define cpu_has_avx boot_cpu_has(X86_FEATURE_AVX) + #define cpu_has_avx2 boot_cpu_has(X86_FEATURE_AVX2) +-#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) +-#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) +-#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE) +-#define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN) +-#define cpu_has_xcrypt boot_cpu_has(X86_FEATURE_XCRYPT) +-#define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN) +-#define cpu_has_ace2 boot_cpu_has(X86_FEATURE_ACE2) +-#define cpu_has_ace2_enabled boot_cpu_has(X86_FEATURE_ACE2_EN) +-#define cpu_has_phe boot_cpu_has(X86_FEATURE_PHE) +-#define cpu_has_phe_enabled boot_cpu_has(X86_FEATURE_PHE_EN) +-#define cpu_has_pmm boot_cpu_has(X86_FEATURE_PMM) +-#define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN) +-#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) +-#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) + #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLUSH) +-#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) + #define cpu_has_gbpages boot_cpu_has(X86_FEATURE_GBPAGES) + #define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON) + #define cpu_has_pat boot_cpu_has(X86_FEATURE_PAT) +-#define cpu_has_xmm4_1 boot_cpu_has(X86_FEATURE_XMM4_1) +-#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2) + #define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC) + #define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE) +-#define cpu_has_xsaveopt boot_cpu_has(X86_FEATURE_XSAVEOPT) + #define cpu_has_xsaves boot_cpu_has(X86_FEATURE_XSAVES) + #define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE) + #define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) +-#define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ) +-#define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE) +-#define cpu_has_perfctr_nb boot_cpu_has(X86_FEATURE_PERFCTR_NB) +-#define cpu_has_perfctr_l2 boot_cpu_has(X86_FEATURE_PERFCTR_L2) +-#define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8) +-#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) +-#define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) +-#define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT) +-#define cpu_has_bpext boot_cpu_has(X86_FEATURE_BPEXT) ++/* ++ * Do not add any more of those clumsy macros - use static_cpu_has_safe() for ++ * fast paths and boot_cpu_has() otherwise! ++ */ + + #if __GNUC__ >= 4 + extern void warn_pre_alternatives(void); +diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h +index 3c3550c3a4a3..146d838e6ee7 100644 +--- a/arch/x86/include/asm/fpu/internal.h ++++ b/arch/x86/include/asm/fpu/internal.h +@@ -42,6 +42,7 @@ extern void fpu__init_cpu_xstate(void); + extern void fpu__init_system(struct cpuinfo_x86 *c); + extern void fpu__init_check_bugs(void); + extern void fpu__resume_cpu(void); ++extern u64 fpu__get_supported_xfeatures_mask(void); + + /* + * Debugging facility: +@@ -57,7 +58,7 @@ extern void fpu__resume_cpu(void); + */ + static __always_inline __pure bool use_eager_fpu(void) + { +- return static_cpu_has_safe(X86_FEATURE_EAGER_FPU); ++ return true; + } + + static __always_inline __pure bool use_xsaveopt(void) +@@ -595,7 +596,8 @@ switch_fpu_prepare(struct fpu *old_fpu, struct fpu *new_fpu, int cpu) + * If the task has used the math, pre-load the FPU on xsave processors + * or if the past 5 consecutive context-switches used math. + */ +- fpu.preload = new_fpu->fpstate_active && ++ fpu.preload = static_cpu_has(X86_FEATURE_FPU) && ++ new_fpu->fpstate_active && + (use_eager_fpu() || new_fpu->counter > 5); + + if (old_fpu->fpregs_active) { +diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h +index 3a6c89b70307..f23cd8c80b1c 100644 +--- a/arch/x86/include/asm/fpu/xstate.h ++++ b/arch/x86/include/asm/fpu/xstate.h +@@ -22,7 +22,7 @@ + #define XFEATURE_MASK_LAZY (XFEATURE_MASK_FP | \ + XFEATURE_MASK_SSE | \ + XFEATURE_MASK_YMM | \ +- XFEATURE_MASK_OPMASK | \ ++ XFEATURE_MASK_OPMASK | \ + XFEATURE_MASK_ZMM_Hi256 | \ + XFEATURE_MASK_Hi16_ZMM) + +diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h +index fc3c7e49c8e4..ae357d0afc91 100644 +--- a/arch/x86/include/asm/kvm_emulate.h ++++ b/arch/x86/include/asm/kvm_emulate.h +@@ -105,11 +105,12 @@ struct x86_emulate_ops { + * @addr: [IN ] Linear address from which to read. + * @val: [OUT] Value read from memory, zero-extended to 'u_long'. + * @bytes: [IN ] Number of bytes to read from memory. ++ * @system:[IN ] Whether the access is forced to be at CPL0. + */ + int (*read_std)(struct x86_emulate_ctxt *ctxt, + unsigned long addr, void *val, + unsigned int bytes, +- struct x86_exception *fault); ++ struct x86_exception *fault, bool system); + + /* + * read_phys: Read bytes of standard (non-emulated/special) memory. +@@ -127,10 +128,11 @@ struct x86_emulate_ops { + * @addr: [IN ] Linear address to which to write. + * @val: [OUT] Value write to memory, zero-extended to 'u_long'. + * @bytes: [IN ] Number of bytes to write to memory. ++ * @system:[IN ] Whether the access is forced to be at CPL0. + */ + int (*write_std)(struct x86_emulate_ctxt *ctxt, + unsigned long addr, void *val, unsigned int bytes, +- struct x86_exception *fault); ++ struct x86_exception *fault, bool system); + /* + * fetch: Read bytes of standard (non-emulated/special) memory. + * Used for instruction fetch. +diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h +index 222a6a3ca2b5..a438c5598a90 100644 +--- a/arch/x86/include/asm/smp.h ++++ b/arch/x86/include/asm/smp.h +@@ -21,15 +21,6 @@ + extern int smp_num_siblings; + extern unsigned int num_processors; + +-static inline bool cpu_has_ht_siblings(void) +-{ +- bool has_siblings = false; +-#ifdef CONFIG_SMP +- has_siblings = cpu_has_ht && smp_num_siblings > 1; +-#endif +- return has_siblings; +-} +- + DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); + DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map); + /* cpus sharing the last level cache: */ +diff --git a/arch/x86/include/asm/xor_32.h b/arch/x86/include/asm/xor_32.h +index 5a08bc8bff33..c54beb44c4c1 100644 +--- a/arch/x86/include/asm/xor_32.h ++++ b/arch/x86/include/asm/xor_32.h +@@ -553,7 +553,7 @@ do { \ + if (cpu_has_xmm) { \ + xor_speed(&xor_block_pIII_sse); \ + xor_speed(&xor_block_sse_pf64); \ +- } else if (cpu_has_mmx) { \ ++ } else if (boot_cpu_has(X86_FEATURE_MMX)) { \ + xor_speed(&xor_block_pII_mmx); \ + xor_speed(&xor_block_p5_mmx); \ + } else { \ +diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c +index 4bf9e77f3e05..f4fb8f5b0be4 100644 +--- a/arch/x86/kernel/cpu/amd.c ++++ b/arch/x86/kernel/cpu/amd.c +@@ -304,7 +304,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c) + int cpu = smp_processor_id(); + + /* get information required for multi-node processors */ +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + u32 eax, ebx, ecx, edx; + + cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); +@@ -954,7 +954,7 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) + + void set_dr_addr_mask(unsigned long mask, int dr) + { +- if (!cpu_has_bpext) ++ if (!boot_cpu_has(X86_FEATURE_BPEXT)) + return; + + switch (dr) { +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index 8eabbafff213..0498ad3702f5 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -1539,7 +1539,9 @@ void cpu_init(void) + + printk(KERN_INFO "Initializing CPU#%d\n", cpu); + +- if (cpu_feature_enabled(X86_FEATURE_VME) || cpu_has_tsc || cpu_has_de) ++ if (cpu_feature_enabled(X86_FEATURE_VME) || ++ cpu_has_tsc || ++ boot_cpu_has(X86_FEATURE_DE)) + cr4_clear_bits(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); + + load_current_idt(); +diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c +index 209ac1e7d1f0..565648bc1a0a 100644 +--- a/arch/x86/kernel/cpu/intel.c ++++ b/arch/x86/kernel/cpu/intel.c +@@ -445,7 +445,8 @@ static void init_intel(struct cpuinfo_x86 *c) + + if (cpu_has_xmm2) + set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); +- if (cpu_has_ds) { ++ ++ if (boot_cpu_has(X86_FEATURE_DS)) { + unsigned int l1; + rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); + if (!(l1 & (1<<11))) +diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c +index b4ca91cf55b0..3fa72317ad78 100644 +--- a/arch/x86/kernel/cpu/intel_cacheinfo.c ++++ b/arch/x86/kernel/cpu/intel_cacheinfo.c +@@ -591,7 +591,7 @@ cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf) + unsigned edx; + + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { +- if (cpu_has_topoext) ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) + cpuid_count(0x8000001d, index, &eax.full, + &ebx.full, &ecx.full, &edx); + else +@@ -637,7 +637,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c) + void init_amd_cacheinfo(struct cpuinfo_x86 *c) + { + +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + num_cache_leaves = find_num_cache_leaves(c); + } else if (c->extended_cpuid_level >= 0x80000006) { + if (cpuid_edx(0x80000006) & 0xf000) +@@ -809,7 +809,7 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index, + struct cacheinfo *this_leaf; + int i, sibling; + +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + unsigned int apicid, nshared, first, last; + + this_leaf = this_cpu_ci->info_list + index; +diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c +index b5624fafa44a..136ae86f4f5f 100644 +--- a/arch/x86/kernel/cpu/mtrr/generic.c ++++ b/arch/x86/kernel/cpu/mtrr/generic.c +@@ -349,7 +349,7 @@ static void get_fixed_ranges(mtrr_type *frs) + + void mtrr_save_fixed_ranges(void *info) + { +- if (cpu_has_mtrr) ++ if (boot_cpu_has(X86_FEATURE_MTRR)) + get_fixed_ranges(mtrr_state.fixed_ranges); + } + +diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c +index fa77ac8291f0..f924f41af89a 100644 +--- a/arch/x86/kernel/cpu/mtrr/main.c ++++ b/arch/x86/kernel/cpu/mtrr/main.c +@@ -682,7 +682,7 @@ void __init mtrr_bp_init(void) + + phys_addr = 32; + +- if (cpu_has_mtrr) { ++ if (boot_cpu_has(X86_FEATURE_MTRR)) { + mtrr_if = &generic_mtrr_ops; + size_or_mask = SIZE_OR_MASK_BITS(36); + size_and_mask = 0x00f00000; +diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c +index 1cee5d2d7ece..3ea177cb7366 100644 +--- a/arch/x86/kernel/cpu/perf_event_amd.c ++++ b/arch/x86/kernel/cpu/perf_event_amd.c +@@ -160,7 +160,7 @@ static inline int amd_pmu_addr_offset(int index, bool eventsel) + if (offset) + return offset; + +- if (!cpu_has_perfctr_core) ++ if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE)) + offset = index; + else + offset = index << 1; +@@ -652,7 +652,7 @@ static __initconst const struct x86_pmu amd_pmu = { + + static int __init amd_core_pmu_init(void) + { +- if (!cpu_has_perfctr_core) ++ if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE)) + return 0; + + switch (boot_cpu_data.x86) { +diff --git a/arch/x86/kernel/cpu/perf_event_amd_uncore.c b/arch/x86/kernel/cpu/perf_event_amd_uncore.c +index cc6cedb8f25d..49742746a6c9 100644 +--- a/arch/x86/kernel/cpu/perf_event_amd_uncore.c ++++ b/arch/x86/kernel/cpu/perf_event_amd_uncore.c +@@ -523,10 +523,10 @@ static int __init amd_uncore_init(void) + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) + goto fail_nodev; + +- if (!cpu_has_topoext) ++ if (!boot_cpu_has(X86_FEATURE_TOPOEXT)) + goto fail_nodev; + +- if (cpu_has_perfctr_nb) { ++ if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) { + amd_uncore_nb = alloc_percpu(struct amd_uncore *); + if (!amd_uncore_nb) { + ret = -ENOMEM; +@@ -540,7 +540,7 @@ static int __init amd_uncore_init(void) + ret = 0; + } + +- if (cpu_has_perfctr_l2) { ++ if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) { + amd_uncore_l2 = alloc_percpu(struct amd_uncore *); + if (!amd_uncore_l2) { + ret = -ENOMEM; +@@ -583,10 +583,11 @@ fail_online: + + /* amd_uncore_nb/l2 should have been freed by cleanup_cpu_online */ + amd_uncore_nb = amd_uncore_l2 = NULL; +- if (cpu_has_perfctr_l2) ++ ++ if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) + perf_pmu_unregister(&amd_l2_pmu); + fail_l2: +- if (cpu_has_perfctr_nb) ++ if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) + perf_pmu_unregister(&amd_nb_pmu); + if (amd_uncore_l2) + free_percpu(amd_uncore_l2); +diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c +index d25097c3fc1d..6aa0b519c851 100644 +--- a/arch/x86/kernel/fpu/core.c ++++ b/arch/x86/kernel/fpu/core.c +@@ -114,6 +114,10 @@ void __kernel_fpu_begin(void) + kernel_fpu_disable(); + + if (fpu->fpregs_active) { ++ /* ++ * Ignore return value -- we don't care if reg state ++ * is clobbered. ++ */ + copy_fpregs_to_fpstate(fpu); + } else { + this_cpu_write(fpu_fpregs_owner_ctx, NULL); +@@ -189,8 +193,12 @@ void fpu__save(struct fpu *fpu) + + preempt_disable(); + if (fpu->fpregs_active) { +- if (!copy_fpregs_to_fpstate(fpu)) +- fpregs_deactivate(fpu); ++ if (!copy_fpregs_to_fpstate(fpu)) { ++ if (use_eager_fpu()) ++ copy_kernel_to_fpregs(&fpu->state); ++ else ++ fpregs_deactivate(fpu); ++ } + } + preempt_enable(); + } +@@ -259,7 +267,11 @@ static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu) + preempt_disable(); + if (!copy_fpregs_to_fpstate(dst_fpu)) { + memcpy(&src_fpu->state, &dst_fpu->state, xstate_size); +- fpregs_deactivate(src_fpu); ++ ++ if (use_eager_fpu()) ++ copy_kernel_to_fpregs(&src_fpu->state); ++ else ++ fpregs_deactivate(src_fpu); + } + preempt_enable(); + } +@@ -409,8 +421,10 @@ static inline void copy_init_fpstate_to_fpregs(void) + { + if (use_xsave()) + copy_kernel_to_xregs(&init_fpstate.xsave, -1); +- else ++ else if (static_cpu_has(X86_FEATURE_FXSR)) + copy_kernel_to_fxregs(&init_fpstate.fxsave); ++ else ++ copy_kernel_to_fregs(&init_fpstate.fsave); + } + + /* +@@ -423,7 +437,7 @@ void fpu__clear(struct fpu *fpu) + { + WARN_ON_FPU(fpu != ¤t->thread.fpu); /* Almost certainly an anomaly */ + +- if (!use_eager_fpu()) { ++ if (!use_eager_fpu() || !static_cpu_has(X86_FEATURE_FPU)) { + /* FPU state will be reallocated lazily at the first use. */ + fpu__drop(fpu); + } else { +diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c +index 1011c05b1bd5..954517285fa2 100644 +--- a/arch/x86/kernel/fpu/init.c ++++ b/arch/x86/kernel/fpu/init.c +@@ -3,8 +3,11 @@ + */ + #include + #include ++#include ++#include + + #include ++#include + + /* + * Initialize the TS bit in CR0 according to the style of context-switches +@@ -12,10 +15,7 @@ + */ + static void fpu__init_cpu_ctx_switch(void) + { +- if (!cpu_has_eager_fpu) +- stts(); +- else +- clts(); ++ clts(); + } + + /* +@@ -75,13 +75,15 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) + cr0 &= ~(X86_CR0_TS | X86_CR0_EM); + write_cr0(cr0); + +- asm volatile("fninit ; fnstsw %0 ; fnstcw %1" +- : "+m" (fsw), "+m" (fcw)); ++ if (!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { ++ asm volatile("fninit ; fnstsw %0 ; fnstcw %1" ++ : "+m" (fsw), "+m" (fcw)); + +- if (fsw == 0 && (fcw & 0x103f) == 0x003f) +- set_cpu_cap(c, X86_FEATURE_FPU); +- else +- clear_cpu_cap(c, X86_FEATURE_FPU); ++ if (fsw == 0 && (fcw & 0x103f) == 0x003f) ++ set_cpu_cap(c, X86_FEATURE_FPU); ++ else ++ clear_cpu_cap(c, X86_FEATURE_FPU); ++ } + + #ifndef CONFIG_MATH_EMULATION + if (!cpu_has_fpu) { +@@ -130,7 +132,7 @@ static void __init fpu__init_system_generic(void) + * Set up the legacy init FPU context. (xstate init might overwrite this + * with a more modern format, if the CPU supports it.) + */ +- fpstate_init_fxstate(&init_fpstate.fxsave); ++ fpstate_init(&init_fpstate); + + fpu__init_system_mxcsr(); + } +@@ -230,53 +232,16 @@ static void __init fpu__init_system_xstate_size_legacy(void) + } + + /* +- * FPU context switching strategies: +- * +- * Against popular belief, we don't do lazy FPU saves, due to the +- * task migration complications it brings on SMP - we only do +- * lazy FPU restores. +- * +- * 'lazy' is the traditional strategy, which is based on setting +- * CR0::TS to 1 during context-switch (instead of doing a full +- * restore of the FPU state), which causes the first FPU instruction +- * after the context switch (whenever it is executed) to fault - at +- * which point we lazily restore the FPU state into FPU registers. +- * +- * Tasks are of course under no obligation to execute FPU instructions, +- * so it can easily happen that another context-switch occurs without +- * a single FPU instruction being executed. If we eventually switch +- * back to the original task (that still owns the FPU) then we have +- * not only saved the restores along the way, but we also have the +- * FPU ready to be used for the original task. +- * +- * 'eager' switching is used on modern CPUs, there we switch the FPU +- * state during every context switch, regardless of whether the task +- * has used FPU instructions in that time slice or not. This is done +- * because modern FPU context saving instructions are able to optimize +- * state saving and restoration in hardware: they can detect both +- * unused and untouched FPU state and optimize accordingly. +- * +- * [ Note that even in 'lazy' mode we might optimize context switches +- * to use 'eager' restores, if we detect that a task is using the FPU +- * frequently. See the fpu->counter logic in fpu/internal.h for that. ] ++ * Find supported xfeatures based on cpu features and command-line input. ++ * This must be called after fpu__init_parse_early_param() is called and ++ * xfeatures_mask is enumerated. + */ +-static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO; +- +-static int __init eager_fpu_setup(char *s) ++u64 __init fpu__get_supported_xfeatures_mask(void) + { +- if (!strcmp(s, "on")) +- eagerfpu = ENABLE; +- else if (!strcmp(s, "off")) +- eagerfpu = DISABLE; +- else if (!strcmp(s, "auto")) +- eagerfpu = AUTO; +- return 1; ++ return XCNTXT_MASK; + } +-__setup("eagerfpu=", eager_fpu_setup); + +-/* +- * Pick the FPU context switching strategy: +- */ ++/* Legacy code to initialize eager fpu mode. */ + static void __init fpu__init_system_ctx_switch(void) + { + static bool on_boot_cpu = 1; +@@ -286,25 +251,31 @@ static void __init fpu__init_system_ctx_switch(void) + + WARN_ON_FPU(current->thread.fpu.fpstate_active); + current_thread_info()->status = 0; ++} + +- /* Auto enable eagerfpu for xsaveopt */ +- if (cpu_has_xsaveopt && eagerfpu != DISABLE) +- eagerfpu = ENABLE; +- +- if (xfeatures_mask & XFEATURE_MASK_EAGER) { +- if (eagerfpu == DISABLE) { +- pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n", +- xfeatures_mask & XFEATURE_MASK_EAGER); +- xfeatures_mask &= ~XFEATURE_MASK_EAGER; +- } else { +- eagerfpu = ENABLE; +- } ++/* ++ * We parse fpu parameters early because fpu__init_system() is executed ++ * before parse_early_param(). ++ */ ++static void __init fpu__init_parse_early_param(void) ++{ ++ if (cmdline_find_option_bool(boot_command_line, "no387")) ++ setup_clear_cpu_cap(X86_FEATURE_FPU); ++ ++ if (cmdline_find_option_bool(boot_command_line, "nofxsr")) { ++ setup_clear_cpu_cap(X86_FEATURE_FXSR); ++ setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT); ++ setup_clear_cpu_cap(X86_FEATURE_XMM); + } + +- if (eagerfpu == ENABLE) +- setup_force_cpu_cap(X86_FEATURE_EAGER_FPU); ++ if (cmdline_find_option_bool(boot_command_line, "noxsave")) ++ fpu__xstate_clear_all_cpu_caps(); ++ ++ if (cmdline_find_option_bool(boot_command_line, "noxsaveopt")) ++ setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); + +- printk(KERN_INFO "x86/fpu: Using '%s' FPU context switches.\n", eagerfpu == ENABLE ? "eager" : "lazy"); ++ if (cmdline_find_option_bool(boot_command_line, "noxsaves")) ++ setup_clear_cpu_cap(X86_FEATURE_XSAVES); + } + + /* +@@ -313,6 +284,7 @@ static void __init fpu__init_system_ctx_switch(void) + */ + void __init fpu__init_system(struct cpuinfo_x86 *c) + { ++ fpu__init_parse_early_param(); + fpu__init_system_early_generic(c); + + /* +@@ -336,62 +308,3 @@ void __init fpu__init_system(struct cpuinfo_x86 *c) + + fpu__init_system_ctx_switch(); + } +- +-/* +- * Boot parameter to turn off FPU support and fall back to math-emu: +- */ +-static int __init no_387(char *s) +-{ +- setup_clear_cpu_cap(X86_FEATURE_FPU); +- return 1; +-} +-__setup("no387", no_387); +- +-/* +- * Disable all xstate CPU features: +- */ +-static int __init x86_noxsave_setup(char *s) +-{ +- if (strlen(s)) +- return 0; +- +- fpu__xstate_clear_all_cpu_caps(); +- +- return 1; +-} +-__setup("noxsave", x86_noxsave_setup); +- +-/* +- * Disable the XSAVEOPT instruction specifically: +- */ +-static int __init x86_noxsaveopt_setup(char *s) +-{ +- setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); +- +- return 1; +-} +-__setup("noxsaveopt", x86_noxsaveopt_setup); +- +-/* +- * Disable the XSAVES instruction: +- */ +-static int __init x86_noxsaves_setup(char *s) +-{ +- setup_clear_cpu_cap(X86_FEATURE_XSAVES); +- +- return 1; +-} +-__setup("noxsaves", x86_noxsaves_setup); +- +-/* +- * Disable FX save/restore and SSE support: +- */ +-static int __init x86_nofxsr_setup(char *s) +-{ +- setup_clear_cpu_cap(X86_FEATURE_FXSR); +- setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT); +- setup_clear_cpu_cap(X86_FEATURE_XMM); +- +- return 1; +-} +-__setup("nofxsr", x86_nofxsr_setup); +diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c +index 70fc312221fc..3fa200ecca62 100644 +--- a/arch/x86/kernel/fpu/xstate.c ++++ b/arch/x86/kernel/fpu/xstate.c +@@ -632,8 +632,7 @@ void __init fpu__init_system_xstate(void) + BUG(); + } + +- /* Support only the state known to the OS: */ +- xfeatures_mask = xfeatures_mask & XCNTXT_MASK; ++ xfeatures_mask &= fpu__get_supported_xfeatures_mask(); + + /* Enable xstate instructions to be able to continue with initialization: */ + fpu__init_cpu_xstate(); +diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c +index 50a3fad5b89f..2bcfb5f2bc44 100644 +--- a/arch/x86/kernel/hw_breakpoint.c ++++ b/arch/x86/kernel/hw_breakpoint.c +@@ -300,6 +300,10 @@ static int arch_build_bp_info(struct perf_event *bp) + return -EINVAL; + if (bp->attr.bp_addr & (bp->attr.bp_len - 1)) + return -EINVAL; ++ ++ if (!boot_cpu_has(X86_FEATURE_BPEXT)) ++ return -EOPNOTSUPP; ++ + /* + * It's impossible to use a range breakpoint to fake out + * user vs kernel detection because bp_len - 1 can't +@@ -307,8 +311,6 @@ static int arch_build_bp_info(struct perf_event *bp) + * breakpoints, then we'll have to check for kprobe-blacklisted + * addresses anywhere in the range. + */ +- if (!cpu_has_bpext) +- return -EOPNOTSUPP; + info->mask = bp->attr.bp_len - 1; + info->len = X86_BREAKPOINT_LEN_1; + } +diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c +index 48ca93242bfd..1f7aefc7b0b4 100644 +--- a/arch/x86/kernel/smpboot.c ++++ b/arch/x86/kernel/smpboot.c +@@ -295,7 +295,7 @@ do { \ + + static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) + { +- if (cpu_has_topoext) { ++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + int cpu1 = c->cpu_index, cpu2 = o->cpu_index; + + if (c->phys_proc_id == o->phys_proc_id && +diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c +index 1fbd2631be60..8c73bf1492b8 100644 +--- a/arch/x86/kernel/traps.c ++++ b/arch/x86/kernel/traps.c +@@ -751,7 +751,6 @@ dotraplinkage void + do_device_not_available(struct pt_regs *regs, long error_code) + { + RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); +- BUG_ON(use_eager_fpu()); + + #ifdef CONFIG_MATH_EMULATION + if (read_cr0() & X86_CR0_EM) { +diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c +index af57736a0309..d6d64a519559 100644 +--- a/arch/x86/kernel/vm86_32.c ++++ b/arch/x86/kernel/vm86_32.c +@@ -357,8 +357,10 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) + tss = &per_cpu(cpu_tss, get_cpu()); + /* make room for real-mode segments */ + tsk->thread.sp0 += 16; +- if (cpu_has_sep) ++ ++ if (static_cpu_has_safe(X86_FEATURE_SEP)) + tsk->thread.sysenter_cs = 0; ++ + load_sp0(tss, &tsk->thread); + put_cpu(); + +diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c +index 8864fec63a20..f1507626ed36 100644 +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -790,6 +790,19 @@ static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) + return assign_eip_near(ctxt, ctxt->_eip + rel); + } + ++static int linear_read_system(struct x86_emulate_ctxt *ctxt, ulong linear, ++ void *data, unsigned size) ++{ ++ return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, true); ++} ++ ++static int linear_write_system(struct x86_emulate_ctxt *ctxt, ++ ulong linear, void *data, ++ unsigned int size) ++{ ++ return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, true); ++} ++ + static int segmented_read_std(struct x86_emulate_ctxt *ctxt, + struct segmented_address addr, + void *data, +@@ -801,7 +814,7 @@ static int segmented_read_std(struct x86_emulate_ctxt *ctxt, + rc = linearize(ctxt, addr, size, false, &linear); + if (rc != X86EMUL_CONTINUE) + return rc; +- return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception); ++ return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, false); + } + + static int segmented_write_std(struct x86_emulate_ctxt *ctxt, +@@ -815,7 +828,7 @@ static int segmented_write_std(struct x86_emulate_ctxt *ctxt, + rc = linearize(ctxt, addr, size, true, &linear); + if (rc != X86EMUL_CONTINUE) + return rc; +- return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception); ++ return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, false); + } + + /* +@@ -1488,8 +1501,7 @@ static int read_interrupt_descriptor(struct x86_emulate_ctxt *ctxt, + return emulate_gp(ctxt, index << 3 | 0x2); + + addr = dt.address + index * 8; +- return ctxt->ops->read_std(ctxt, addr, desc, sizeof *desc, +- &ctxt->exception); ++ return linear_read_system(ctxt, addr, desc, sizeof *desc); + } + + static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt, +@@ -1552,8 +1564,7 @@ static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt, + if (rc != X86EMUL_CONTINUE) + return rc; + +- return ctxt->ops->read_std(ctxt, *desc_addr_p, desc, sizeof(*desc), +- &ctxt->exception); ++ return linear_read_system(ctxt, *desc_addr_p, desc, sizeof(*desc)); + } + + /* allowed just for 8 bytes segments */ +@@ -1567,8 +1578,7 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt, + if (rc != X86EMUL_CONTINUE) + return rc; + +- return ctxt->ops->write_std(ctxt, addr, desc, sizeof *desc, +- &ctxt->exception); ++ return linear_write_system(ctxt, addr, desc, sizeof *desc); + } + + static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, +@@ -1729,8 +1739,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, + return ret; + } + } else if (ctxt->mode == X86EMUL_MODE_PROT64) { +- ret = ctxt->ops->read_std(ctxt, desc_addr+8, &base3, +- sizeof(base3), &ctxt->exception); ++ ret = linear_read_system(ctxt, desc_addr+8, &base3, sizeof(base3)); + if (ret != X86EMUL_CONTINUE) + return ret; + if (is_noncanonical_address(get_desc_base(&seg_desc) | +@@ -2043,11 +2052,11 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq) + eip_addr = dt.address + (irq << 2); + cs_addr = dt.address + (irq << 2) + 2; + +- rc = ops->read_std(ctxt, cs_addr, &cs, 2, &ctxt->exception); ++ rc = linear_read_system(ctxt, cs_addr, &cs, 2); + if (rc != X86EMUL_CONTINUE) + return rc; + +- rc = ops->read_std(ctxt, eip_addr, &eip, 2, &ctxt->exception); ++ rc = linear_read_system(ctxt, eip_addr, &eip, 2); + if (rc != X86EMUL_CONTINUE) + return rc; + +@@ -2891,12 +2900,12 @@ static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, + #ifdef CONFIG_X86_64 + base |= ((u64)base3) << 32; + #endif +- r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL); ++ r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL, true); + if (r != X86EMUL_CONTINUE) + return false; + if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg)) + return false; +- r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL); ++ r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL, true); + if (r != X86EMUL_CONTINUE) + return false; + if ((perm >> bit_idx) & mask) +@@ -3025,35 +3034,30 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, + u16 tss_selector, u16 old_tss_sel, + ulong old_tss_base, struct desc_struct *new_desc) + { +- const struct x86_emulate_ops *ops = ctxt->ops; + struct tss_segment_16 tss_seg; + int ret; + u32 new_tss_base = get_desc_base(new_desc); + +- ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + + save_state_to_tss16(ctxt, &tss_seg); + +- ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_write_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + +- ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + + if (old_tss_sel != 0xffff) { + tss_seg.prev_task_link = old_tss_sel; + +- ret = ops->write_std(ctxt, new_tss_base, +- &tss_seg.prev_task_link, +- sizeof tss_seg.prev_task_link, +- &ctxt->exception); ++ ret = linear_write_system(ctxt, new_tss_base, ++ &tss_seg.prev_task_link, ++ sizeof tss_seg.prev_task_link); + if (ret != X86EMUL_CONTINUE) + return ret; + } +@@ -3169,38 +3173,34 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt, + u16 tss_selector, u16 old_tss_sel, + ulong old_tss_base, struct desc_struct *new_desc) + { +- const struct x86_emulate_ops *ops = ctxt->ops; + struct tss_segment_32 tss_seg; + int ret; + u32 new_tss_base = get_desc_base(new_desc); + u32 eip_offset = offsetof(struct tss_segment_32, eip); + u32 ldt_sel_offset = offsetof(struct tss_segment_32, ldt_selector); + +- ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + + save_state_to_tss32(ctxt, &tss_seg); + + /* Only GP registers and segment selectors are saved */ +- ret = ops->write_std(ctxt, old_tss_base + eip_offset, &tss_seg.eip, +- ldt_sel_offset - eip_offset, &ctxt->exception); ++ ret = linear_write_system(ctxt, old_tss_base + eip_offset, &tss_seg.eip, ++ ldt_sel_offset - eip_offset); + if (ret != X86EMUL_CONTINUE) + return ret; + +- ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, +- &ctxt->exception); ++ ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); + if (ret != X86EMUL_CONTINUE) + return ret; + + if (old_tss_sel != 0xffff) { + tss_seg.prev_task_link = old_tss_sel; + +- ret = ops->write_std(ctxt, new_tss_base, +- &tss_seg.prev_task_link, +- sizeof tss_seg.prev_task_link, +- &ctxt->exception); ++ ret = linear_write_system(ctxt, new_tss_base, ++ &tss_seg.prev_task_link, ++ sizeof tss_seg.prev_task_link); + if (ret != X86EMUL_CONTINUE) + return ret; + } +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index a750fc7c7458..63c44a9bf6bb 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -6692,8 +6692,7 @@ static int nested_vmx_check_vmptr(struct kvm_vcpu *vcpu, int exit_reason, + vmcs_read32(VMX_INSTRUCTION_INFO), false, &gva)) + return 1; + +- if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vmptr, +- sizeof(vmptr), &e)) { ++ if (kvm_read_guest_virt(vcpu, gva, &vmptr, sizeof(vmptr), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +@@ -7211,8 +7210,8 @@ static int handle_vmread(struct kvm_vcpu *vcpu) + vmx_instruction_info, true, &gva)) + return 1; + /* _system ok, as nested_vmx_check_permission verified cpl=0 */ +- kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, gva, +- &field_value, (is_long_mode(vcpu) ? 8 : 4), NULL); ++ kvm_write_guest_virt_system(vcpu, gva, &field_value, ++ (is_long_mode(vcpu) ? 8 : 4), NULL); + } + + nested_vmx_succeed(vcpu); +@@ -7247,8 +7246,8 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) + if (get_vmx_mem_address(vcpu, exit_qualification, + vmx_instruction_info, false, &gva)) + return 1; +- if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, +- &field_value, (is_64_bit_mode(vcpu) ? 8 : 4), &e)) { ++ if (kvm_read_guest_virt(vcpu, gva, &field_value, ++ (is_64_bit_mode(vcpu) ? 8 : 4), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +@@ -7338,9 +7337,9 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu) + vmx_instruction_info, true, &vmcs_gva)) + return 1; + /* ok to use *_system, as nested_vmx_check_permission verified cpl=0 */ +- if (kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, vmcs_gva, +- (void *)&to_vmx(vcpu)->nested.current_vmptr, +- sizeof(u64), &e)) { ++ if (kvm_write_guest_virt_system(vcpu, vmcs_gva, ++ (void *)&to_vmx(vcpu)->nested.current_vmptr, ++ sizeof(u64), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +@@ -7394,8 +7393,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) + if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), + vmx_instruction_info, false, &gva)) + return 1; +- if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &operand, +- sizeof(operand), &e)) { ++ if (kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +@@ -7454,8 +7452,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) + if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), + vmx_instruction_info, false, &gva)) + return 1; +- if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vpid, +- sizeof(u32), &e)) { ++ if (kvm_read_guest_virt(vcpu, gva, &vpid, sizeof(u32), &e)) { + kvm_inject_page_fault(vcpu, &e); + return 1; + } +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 9cea09597d66..53d43d22a84b 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -4245,11 +4245,10 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt, + return X86EMUL_CONTINUE; + } + +-int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, ++int kvm_read_guest_virt(struct kvm_vcpu *vcpu, + gva_t addr, void *val, unsigned int bytes, + struct x86_exception *exception) + { +- struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); + u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; + + return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, +@@ -4257,12 +4256,17 @@ int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, + } + EXPORT_SYMBOL_GPL(kvm_read_guest_virt); + +-static int kvm_read_guest_virt_system(struct x86_emulate_ctxt *ctxt, +- gva_t addr, void *val, unsigned int bytes, +- struct x86_exception *exception) ++static int emulator_read_std(struct x86_emulate_ctxt *ctxt, ++ gva_t addr, void *val, unsigned int bytes, ++ struct x86_exception *exception, bool system) + { + struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); +- return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception); ++ u32 access = 0; ++ ++ if (!system && kvm_x86_ops->get_cpl(vcpu) == 3) ++ access |= PFERR_USER_MASK; ++ ++ return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, exception); + } + + static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt, +@@ -4274,18 +4278,16 @@ static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt, + return r < 0 ? X86EMUL_IO_NEEDED : X86EMUL_CONTINUE; + } + +-int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, +- gva_t addr, void *val, +- unsigned int bytes, +- struct x86_exception *exception) ++static int kvm_write_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, ++ struct kvm_vcpu *vcpu, u32 access, ++ struct x86_exception *exception) + { +- struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); + void *data = val; + int r = X86EMUL_CONTINUE; + + while (bytes) { + gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, +- PFERR_WRITE_MASK, ++ access, + exception); + unsigned offset = addr & (PAGE_SIZE-1); + unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); +@@ -4306,6 +4308,27 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, + out: + return r; + } ++ ++static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *val, ++ unsigned int bytes, struct x86_exception *exception, ++ bool system) ++{ ++ struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); ++ u32 access = PFERR_WRITE_MASK; ++ ++ if (!system && kvm_x86_ops->get_cpl(vcpu) == 3) ++ access |= PFERR_USER_MASK; ++ ++ return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, ++ access, exception); ++} ++ ++int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val, ++ unsigned int bytes, struct x86_exception *exception) ++{ ++ return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, ++ PFERR_WRITE_MASK, exception); ++} + EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system); + + static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, +@@ -5025,8 +5048,8 @@ static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_fla + static const struct x86_emulate_ops emulate_ops = { + .read_gpr = emulator_read_gpr, + .write_gpr = emulator_write_gpr, +- .read_std = kvm_read_guest_virt_system, +- .write_std = kvm_write_guest_virt_system, ++ .read_std = emulator_read_std, ++ .write_std = emulator_write_std, + .read_phys = kvm_read_guest_phys_system, + .fetch = kvm_fetch_guest_virt, + .read_emulated = emulator_read_emulated, +diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h +index f2afa5fe48a6..53a750a10598 100644 +--- a/arch/x86/kvm/x86.h ++++ b/arch/x86/kvm/x86.h +@@ -164,11 +164,11 @@ int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); + + void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr); + +-int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, ++int kvm_read_guest_virt(struct kvm_vcpu *vcpu, + gva_t addr, void *val, unsigned int bytes, + struct x86_exception *exception); + +-int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, ++int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, + gva_t addr, void *val, unsigned int bytes, + struct x86_exception *exception); + +diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c +index 90555bf60aa4..92e2eacb3321 100644 +--- a/arch/x86/mm/setup_nx.c ++++ b/arch/x86/mm/setup_nx.c +@@ -31,7 +31,7 @@ early_param("noexec", noexec_setup); + + void x86_configure_nx(void) + { +- if (cpu_has_nx && !disable_nx) ++ if (boot_cpu_has(X86_FEATURE_NX) && !disable_nx) + __supported_pte_mask |= _PAGE_NX; + else + __supported_pte_mask &= ~_PAGE_NX; +@@ -39,7 +39,7 @@ void x86_configure_nx(void) + + void __init x86_report_nx(void) + { +- if (!cpu_has_nx) { ++ if (!boot_cpu_has(X86_FEATURE_NX)) { + printk(KERN_NOTICE "Notice: NX (Execute Disable) protection " + "missing in CPU!\n"); + } else { +diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c +index 0c98a9d51a24..44ce80606944 100644 +--- a/drivers/char/hw_random/via-rng.c ++++ b/drivers/char/hw_random/via-rng.c +@@ -140,7 +140,7 @@ static int via_rng_init(struct hwrng *rng) + * RNG configuration like it used to be the case in this + * register */ + if ((c->x86 == 6) && (c->x86_model >= 0x0f)) { +- if (!cpu_has_xstore_enabled) { ++ if (!boot_cpu_has(X86_FEATURE_XSTORE_EN)) { + pr_err(PFX "can't enable hardware RNG " + "if XSTORE is not enabled\n"); + return -ENODEV; +@@ -200,8 +200,9 @@ static int __init mod_init(void) + { + int err; + +- if (!cpu_has_xstore) ++ if (!boot_cpu_has(X86_FEATURE_XSTORE)) + return -ENODEV; ++ + pr_info("VIA RNG detected\n"); + err = hwrng_register(&via_rng); + if (err) { +diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c +index da2d6777bd09..97a364694bfc 100644 +--- a/drivers/crypto/padlock-aes.c ++++ b/drivers/crypto/padlock-aes.c +@@ -515,7 +515,7 @@ static int __init padlock_init(void) + if (!x86_match_cpu(padlock_cpu_id)) + return -ENODEV; + +- if (!cpu_has_xcrypt_enabled) { ++ if (!boot_cpu_has(X86_FEATURE_XCRYPT_EN)) { + printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); + return -ENODEV; + } +diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c +index 4e154c9b9206..8c5f90647b7a 100644 +--- a/drivers/crypto/padlock-sha.c ++++ b/drivers/crypto/padlock-sha.c +@@ -540,7 +540,7 @@ static int __init padlock_init(void) + struct shash_alg *sha1; + struct shash_alg *sha256; + +- if (!x86_match_cpu(padlock_sha_ids) || !cpu_has_phe_enabled) ++ if (!x86_match_cpu(padlock_sha_ids) || !boot_cpu_has(X86_FEATURE_PHE_EN)) + return -ENODEV; + + /* Register the newly added algorithm module if on * +diff --git a/drivers/crypto/vmx/aes.c b/drivers/crypto/vmx/aes.c +index 263af709e536..b907e4b1bbe2 100644 +--- a/drivers/crypto/vmx/aes.c ++++ b/drivers/crypto/vmx/aes.c +@@ -53,8 +53,6 @@ static int p8_aes_init(struct crypto_tfm *tfm) + alg, PTR_ERR(fallback)); + return PTR_ERR(fallback); + } +- printk(KERN_INFO "Using '%s' as fallback implementation.\n", +- crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback)); + + crypto_cipher_set_flags(fallback, + crypto_cipher_get_flags((struct +diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c +index 3f8bb9a40df1..9506e8693c81 100644 +--- a/drivers/crypto/vmx/aes_cbc.c ++++ b/drivers/crypto/vmx/aes_cbc.c +@@ -55,8 +55,6 @@ static int p8_aes_cbc_init(struct crypto_tfm *tfm) + alg, PTR_ERR(fallback)); + return PTR_ERR(fallback); + } +- printk(KERN_INFO "Using '%s' as fallback implementation.\n", +- crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback)); + + crypto_blkcipher_set_flags( + fallback, +diff --git a/drivers/crypto/vmx/aes_ctr.c b/drivers/crypto/vmx/aes_ctr.c +index d83ab4bac8b1..7d070201b3d3 100644 +--- a/drivers/crypto/vmx/aes_ctr.c ++++ b/drivers/crypto/vmx/aes_ctr.c +@@ -53,8 +53,6 @@ static int p8_aes_ctr_init(struct crypto_tfm *tfm) + alg, PTR_ERR(fallback)); + return PTR_ERR(fallback); + } +- printk(KERN_INFO "Using '%s' as fallback implementation.\n", +- crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback)); + + crypto_blkcipher_set_flags( + fallback, +diff --git a/drivers/crypto/vmx/ghash.c b/drivers/crypto/vmx/ghash.c +index 9cb3a0b715e2..84b9389bf1ed 100644 +--- a/drivers/crypto/vmx/ghash.c ++++ b/drivers/crypto/vmx/ghash.c +@@ -64,8 +64,6 @@ static int p8_ghash_init_tfm(struct crypto_tfm *tfm) + alg, PTR_ERR(fallback)); + return PTR_ERR(fallback); + } +- printk(KERN_INFO "Using '%s' as fallback implementation.\n", +- crypto_tfm_alg_driver_name(crypto_shash_tfm(fallback))); + + crypto_shash_set_flags(fallback, + crypto_shash_get_flags((struct crypto_shash +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 759a39906a52..fe89fd56eabf 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -2117,6 +2117,8 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, + struct gpio_desc *desc = NULL; + int status; + enum gpio_lookup_flags lookupflags = 0; ++ /* Maybe we have a device name, maybe not */ ++ const char *devname = dev ? dev_name(dev) : "?"; + + dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id); + +@@ -2145,8 +2147,11 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, + return desc; + } + +- /* If a connection label was passed use that, else use the device name as label */ +- status = gpiod_request(desc, con_id ? con_id : dev_name(dev)); ++ /* ++ * If a connection label was passed use that, else attempt to use ++ * the device name as label ++ */ ++ status = gpiod_request(desc, con_id ? con_id : devname); + if (status < 0) + return ERR_PTR(status); + +diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c +index 3851d5715772..aeb8250ab079 100644 +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -1249,6 +1249,7 @@ static const struct acpi_device_id elan_acpi_id[] = { + { "ELAN060B", 0 }, + { "ELAN060C", 0 }, + { "ELAN0611", 0 }, ++ { "ELAN0612", 0 }, + { "ELAN1000", 0 }, + { } + }; +diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c +index 4d113c9e4b77..7bf2597ce44c 100644 +--- a/drivers/input/touchscreen/goodix.c ++++ b/drivers/input/touchscreen/goodix.c +@@ -425,6 +425,7 @@ MODULE_DEVICE_TABLE(i2c, goodix_ts_id); + #ifdef CONFIG_ACPI + static const struct acpi_device_id goodix_acpi_match[] = { + { "GDIX1001", 0 }, ++ { "GDIX1002", 0 }, + { } + }; + MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); +diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c +index e9b241b1c9dd..ac596928f6b4 100644 +--- a/drivers/iommu/intel_irq_remapping.c ++++ b/drivers/iommu/intel_irq_remapping.c +@@ -753,7 +753,7 @@ static inline void set_irq_posting_cap(void) + * should have X86_FEATURE_CX16 support, this has been confirmed + * with Intel hardware guys. + */ +- if ( cpu_has_cx16 ) ++ if (boot_cpu_has(X86_FEATURE_CX16)) + intel_irq_remap_ops.capability |= 1 << IRQ_POSTING_CAP; + + for_each_iommu(iommu, drhd) +diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c +index 1e688bfec567..fe90b7e04427 100644 +--- a/drivers/misc/vmw_balloon.c ++++ b/drivers/misc/vmw_balloon.c +@@ -576,15 +576,9 @@ static void vmballoon_pop(struct vmballoon *b) + } + } + +- if (b->batch_page) { +- vunmap(b->batch_page); +- b->batch_page = NULL; +- } +- +- if (b->page) { +- __free_page(b->page); +- b->page = NULL; +- } ++ /* Clearing the batch_page unconditionally has no adverse effect */ ++ free_page((unsigned long)b->batch_page); ++ b->batch_page = NULL; + } + + /* +@@ -991,16 +985,13 @@ static const struct vmballoon_ops vmballoon_batched_ops = { + + static bool vmballoon_init_batching(struct vmballoon *b) + { +- b->page = alloc_page(VMW_PAGE_ALLOC_NOSLEEP); +- if (!b->page) +- return false; ++ struct page *page; + +- b->batch_page = vmap(&b->page, 1, VM_MAP, PAGE_KERNEL); +- if (!b->batch_page) { +- __free_page(b->page); ++ page = alloc_page(GFP_KERNEL | __GFP_ZERO); ++ if (!page) + return false; +- } + ++ b->batch_page = page_address(page); + return true; + } + +diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c +index 312343beb249..4d532a085db9 100644 +--- a/drivers/tty/serial/samsung.c ++++ b/drivers/tty/serial/samsung.c +@@ -860,15 +860,12 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) + dma->rx_conf.direction = DMA_DEV_TO_MEM; + dma->rx_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + dma->rx_conf.src_addr = p->port.mapbase + S3C2410_URXH; +- dma->rx_conf.src_maxburst = 16; ++ dma->rx_conf.src_maxburst = 1; + + dma->tx_conf.direction = DMA_MEM_TO_DEV; + dma->tx_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + dma->tx_conf.dst_addr = p->port.mapbase + S3C2410_UTXH; +- if (dma_get_cache_alignment() >= 16) +- dma->tx_conf.dst_maxburst = 16; +- else +- dma->tx_conf.dst_maxburst = 1; ++ dma->tx_conf.dst_maxburst = 1; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 208b3f5ffb3f..7efd70bfeaf7 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -923,7 +923,7 @@ static int check_async_write(struct inode *inode, unsigned long bio_flags) + if (bio_flags & EXTENT_BIO_TREE_LOG) + return 0; + #ifdef CONFIG_X86 +- if (cpu_has_xmm4_2) ++ if (static_cpu_has_safe(X86_FEATURE_XMM4_2)) + return 0; + #endif + return 1; +diff --git a/include/linux/fs.h b/include/linux/fs.h +index da79e9d66e5b..240cbaee819f 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -926,9 +926,9 @@ static inline struct file *get_file(struct file *f) + /* Page cache limit. The filesystems should put that into their s_maxbytes + limits, otherwise bad things can happen in VM. */ + #if BITS_PER_LONG==32 +-#define MAX_LFS_FILESIZE (((loff_t)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) ++#define MAX_LFS_FILESIZE ((loff_t)ULONG_MAX << PAGE_SHIFT) + #elif BITS_PER_LONG==64 +-#define MAX_LFS_FILESIZE ((loff_t)0x7fffffffffffffffLL) ++#define MAX_LFS_FILESIZE ((loff_t)LLONG_MAX) + #endif + + #define FL_POSIX 1 +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 15150b412930..3ba903ff2bb0 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -437,6 +437,24 @@ static int verify_address_len(const void *p) + return 0; + } + ++static inline int sadb_key_len(const struct sadb_key *key) ++{ ++ int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8); ++ ++ return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes, ++ sizeof(uint64_t)); ++} ++ ++static int verify_key_len(const void *p) ++{ ++ const struct sadb_key *key = p; ++ ++ if (sadb_key_len(key) > key->sadb_key_len) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx) + { + return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) + +@@ -533,16 +551,25 @@ static int parse_exthdrs(struct sk_buff *skb, const struct sadb_msg *hdr, void * + return -EINVAL; + if (ext_hdrs[ext_type-1] != NULL) + return -EINVAL; +- if (ext_type == SADB_EXT_ADDRESS_SRC || +- ext_type == SADB_EXT_ADDRESS_DST || +- ext_type == SADB_EXT_ADDRESS_PROXY || +- ext_type == SADB_X_EXT_NAT_T_OA) { ++ switch (ext_type) { ++ case SADB_EXT_ADDRESS_SRC: ++ case SADB_EXT_ADDRESS_DST: ++ case SADB_EXT_ADDRESS_PROXY: ++ case SADB_X_EXT_NAT_T_OA: + if (verify_address_len(p)) + return -EINVAL; +- } +- if (ext_type == SADB_X_EXT_SEC_CTX) { ++ break; ++ case SADB_X_EXT_SEC_CTX: + if (verify_sec_ctx_len(p)) + return -EINVAL; ++ break; ++ case SADB_EXT_KEY_AUTH: ++ case SADB_EXT_KEY_ENCRYPT: ++ if (verify_key_len(p)) ++ return -EINVAL; ++ break; ++ default: ++ break; + } + ext_hdrs[ext_type-1] = (void *) p; + } +@@ -1111,14 +1138,12 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net, + key = ext_hdrs[SADB_EXT_KEY_AUTH - 1]; + if (key != NULL && + sa->sadb_sa_auth != SADB_X_AALG_NULL && +- ((key->sadb_key_bits+7) / 8 == 0 || +- (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) ++ key->sadb_key_bits == 0) + return ERR_PTR(-EINVAL); + key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; + if (key != NULL && + sa->sadb_sa_encrypt != SADB_EALG_NULL && +- ((key->sadb_key_bits+7) / 8 == 0 || +- (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t))) ++ key->sadb_key_bits == 0) + return ERR_PTR(-EINVAL); + + x = xfrm_state_alloc(net); diff --git a/patch/kernel/rk3328-default/rock64-DT-add-ethernet-aliases.patch b/patch/kernel/rk3328-default/rock64-DT-add-ethernet-aliases.patch index 9285ca6de..1fb7ca5d2 100644 --- a/patch/kernel/rk3328-default/rock64-DT-add-ethernet-aliases.patch +++ b/patch/kernel/rk3328-default/rock64-DT-add-ethernet-aliases.patch @@ -1,5 +1,5 @@ diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts -index 113b82cd..d0612eb1 100755 +index 113b82cd..d0612eb1 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -47,6 +47,10 @@ diff --git a/patch/kernel/rk3328-default/wifi-0001-realtek-881xAU-605ecfa.patch b/patch/kernel/rk3328-default/wifi-0001-realtek-881xAU-605ecfa.patch index b38578723..c01672ae3 100644 --- a/patch/kernel/rk3328-default/wifi-0001-realtek-881xAU-605ecfa.patch +++ b/patch/kernel/rk3328-default/wifi-0001-realtek-881xAU-605ecfa.patch @@ -361,7 +361,7 @@ index 0000000..d159169 +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/drivers/net/wireless/rtl8812au/Makefile b/drivers/net/wireless/rtl8812au/Makefile -new file mode 100755 +new file mode 100644 index 0000000..ef959e7 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/Makefile @@ -110647,7 +110647,7 @@ index 0000000..cf167a5 + +#endif diff --git a/drivers/net/wireless/rtl8812au/hal/btc/HalBtc8703b2Ant.c b/drivers/net/wireless/rtl8812au/hal/btc/HalBtc8703b2Ant.c -new file mode 100755 +new file mode 100644 index 0000000..d5c5c47 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/btc/HalBtc8703b2Ant.c @@ -115517,7 +115517,7 @@ index 0000000..d5c5c47 +#endif + diff --git a/drivers/net/wireless/rtl8812au/hal/btc/HalBtc8703b2Ant.h b/drivers/net/wireless/rtl8812au/hal/btc/HalBtc8703b2Ant.h -new file mode 100755 +new file mode 100644 index 0000000..361c443 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/btc/HalBtc8703b2Ant.h @@ -267231,7 +267231,7 @@ index 0000000..ec8c6fa +#endif + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/phydm_rxhp.c b/drivers/net/wireless/rtl8812au/hal/phydm/phydm_rxhp.c -new file mode 100755 +new file mode 100644 index 0000000..8a4a273 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/phydm_rxhp.c @@ -268929,7 +268929,7 @@ index 0000000..8a4a273 + + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/phydm_rxhp.h b/drivers/net/wireless/rtl8812au/hal/phydm/phydm_rxhp.h -new file mode 100755 +new file mode 100644 index 0000000..a1fe97f --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/phydm_rxhp.h @@ -320394,7 +320394,7 @@ index 0000000..e9c28bf +#define COMMIT_BY_8814A "BB_LUKE" +#define RELEASE_VERSION_8814A 81 diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_bb.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_bb.c -new file mode 100755 +new file mode 100644 index 0000000..09f3fbf --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_bb.c @@ -321205,7 +321205,7 @@ index 0000000..09f3fbf +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_bb.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_bb.h -new file mode 100755 +new file mode 100644 index 0000000..a5429f1 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_bb.h @@ -321280,7 +321280,7 @@ index 0000000..a5429f1 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_fw.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_fw.c -new file mode 100755 +new file mode 100644 index 0000000..dc91392 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_fw.c @@ -327923,7 +327923,7 @@ index 0000000..dc91392 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_fw.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_fw.h -new file mode 100755 +new file mode 100644 index 0000000..945819a --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_fw.h @@ -328002,7 +328002,7 @@ index 0000000..945819a +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_mac.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_mac.c -new file mode 100755 +new file mode 100644 index 0000000..ed73444 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_mac.c @@ -328294,7 +328294,7 @@ index 0000000..ed73444 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_mac.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_mac.h -new file mode 100755 +new file mode 100644 index 0000000..73158b4 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_mac.h @@ -328339,7 +328339,7 @@ index 0000000..73158b4 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_rf.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_rf.c -new file mode 100755 +new file mode 100644 index 0000000..29df963 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_rf.c @@ -333809,7 +333809,7 @@ index 0000000..29df963 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_rf.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_rf.h -new file mode 100755 +new file mode 100644 index 0000000..c4dd473 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halhwimg8821a_rf.h @@ -333964,7 +333964,7 @@ index 0000000..c4dd473 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_ce.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_ce.c -new file mode 100755 +new file mode 100644 index 0000000..01da5a1 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_ce.c @@ -334295,7 +334295,7 @@ index 0000000..01da5a1 + + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_ce.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_ce.h -new file mode 100755 +new file mode 100644 index 0000000..688a95e --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_ce.h @@ -334353,7 +334353,7 @@ index 0000000..688a95e +#endif // #ifndef __HAL_PHY_RF_8821A_H__ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_win.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_win.c -new file mode 100755 +new file mode 100644 index 0000000..40d6b52 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_win.c @@ -335507,7 +335507,7 @@ index 0000000..40d6b52 + + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_win.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_win.h -new file mode 100755 +new file mode 100644 index 0000000..5d239ad --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/halphyrf_8821a_win.h @@ -335585,7 +335585,7 @@ index 0000000..5d239ad +#endif // #ifndef __HAL_PHY_RF_8821A_H__ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.c -new file mode 100755 +new file mode 100644 index 0000000..382025b --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.c @@ -336466,7 +336466,7 @@ index 0000000..382025b +#endif + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.h -new file mode 100755 +new file mode 100644 index 0000000..8c74fec --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.h @@ -336520,7 +336520,7 @@ index 0000000..8c74fec +#endif // #ifndef __PHYDM_IQK_8821A_H__ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.c -new file mode 100755 +new file mode 100644 index 0000000..28905fd --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.c @@ -337402,7 +337402,7 @@ index 0000000..28905fd +#endif + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.h -new file mode 100755 +new file mode 100644 index 0000000..f44f445 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.h @@ -337456,7 +337456,7 @@ index 0000000..f44f445 +#endif // #ifndef __PHYDM_IQK_8821A_H__ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.c -new file mode 100755 +new file mode 100644 index 0000000..aeb4979 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.c @@ -338337,7 +338337,7 @@ index 0000000..aeb4979 +#endif + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.h -new file mode 100755 +new file mode 100644 index 0000000..8c74fec --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.h @@ -338391,7 +338391,7 @@ index 0000000..8c74fec +#endif // #ifndef __PHYDM_IQK_8821A_H__ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_regconfig8821a.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_regconfig8821a.c -new file mode 100755 +new file mode 100644 index 0000000..c09db08 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_regconfig8821a.c @@ -338617,7 +338617,7 @@ index 0000000..c09db08 +#endif /* #if (RTL8821A_SUPPORT == 1)*/ + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_regconfig8821a.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_regconfig8821a.h -new file mode 100755 +new file mode 100644 index 0000000..a07fd74 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_regconfig8821a.h @@ -338719,7 +338719,7 @@ index 0000000..a07fd74 +#endif // end of SUPPORT + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.c b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.c -new file mode 100755 +new file mode 100644 index 0000000..27bccb3 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.c @@ -338795,7 +338795,7 @@ index 0000000..27bccb3 +#endif //#if (RTL8821A_SUPPORT == 1) + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.h -new file mode 100755 +new file mode 100644 index 0000000..0b5edf5 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/phydm_rtl8821a.h @@ -338830,7 +338830,7 @@ index 0000000..0b5edf5 +#endif + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/version_rtl8821a.h b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/version_rtl8821a.h -new file mode 100755 +new file mode 100644 index 0000000..5e10b15 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/rtl8821a/version_rtl8821a.h @@ -340785,7 +340785,7 @@ index 0000000..7efdc02 +#endif + diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/txbf/haltxbf8821b.c b/drivers/net/wireless/rtl8812au/hal/phydm/txbf/haltxbf8821b.c -new file mode 100755 +new file mode 100644 index 0000000..eff8e98 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/txbf/haltxbf8821b.c @@ -341191,7 +341191,7 @@ index 0000000..eff8e98 + +#endif diff --git a/drivers/net/wireless/rtl8812au/hal/phydm/txbf/haltxbf8821b.h b/drivers/net/wireless/rtl8812au/hal/phydm/txbf/haltxbf8821b.h -new file mode 100755 +new file mode 100644 index 0000000..c92d79a --- /dev/null +++ b/drivers/net/wireless/rtl8812au/hal/phydm/txbf/haltxbf8821b.h @@ -412866,7 +412866,7 @@ index 0000000..4ab4feb + +#endif /* __HAL_COMMON_H__ */ diff --git a/drivers/net/wireless/rtl8812au/include/hal_data.h b/drivers/net/wireless/rtl8812au/include/hal_data.h -new file mode 100755 +new file mode 100644 index 0000000..a9dd586 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/hal_data.h @@ -413649,7 +413649,7 @@ index 0000000..a9dd586 + +#endif /* __HAL_DATA_H__ */ diff --git a/drivers/net/wireless/rtl8812au/include/hal_data.h.edited b/drivers/net/wireless/rtl8812au/include/hal_data.h.edited -new file mode 100755 +new file mode 100644 index 0000000..ec59ebb --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/hal_data.h.edited @@ -428588,7 +428588,7 @@ index 0000000..a3bb7df + +#endif diff --git a/drivers/net/wireless/rtl8812au/include/rtl8723b_hal.h b/drivers/net/wireless/rtl8812au/include/rtl8723b_hal.h -new file mode 100755 +new file mode 100644 index 0000000..e6391a4 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8723b_hal.h @@ -428892,7 +428892,7 @@ index 0000000..e6391a4 + +#endif diff --git a/drivers/net/wireless/rtl8812au/include/rtl8723b_led.h b/drivers/net/wireless/rtl8812au/include/rtl8723b_led.h -new file mode 100755 +new file mode 100644 index 0000000..0a7b2c9 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8723b_led.h @@ -428946,7 +428946,7 @@ index 0000000..0a7b2c9 + +#endif diff --git a/drivers/net/wireless/rtl8812au/include/rtl8723b_recv.h b/drivers/net/wireless/rtl8812au/include/rtl8723b_recv.h -new file mode 100755 +new file mode 100644 index 0000000..fd9faef --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8723b_recv.h @@ -429079,7 +429079,7 @@ index 0000000..bf56dde + +#endif diff --git a/drivers/net/wireless/rtl8812au/include/rtl8723b_spec.h b/drivers/net/wireless/rtl8812au/include/rtl8723b_spec.h -new file mode 100755 +new file mode 100644 index 0000000..85b9d1e --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8723b_spec.h @@ -429416,7 +429416,7 @@ index 0000000..8067359 +#endif +#endif diff --git a/drivers/net/wireless/rtl8812au/include/rtl8723b_xmit.h b/drivers/net/wireless/rtl8812au/include/rtl8723b_xmit.h -new file mode 100755 +new file mode 100644 index 0000000..7cc33e1 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8723b_xmit.h @@ -433210,7 +433210,7 @@ index 0000000..9fe4dfb +#include "rtl8821a_xmit.h" +#endif /* CONFIG_RTL8821A */ diff --git a/drivers/net/wireless/rtl8812au/include/rtl8814a_cmd.h b/drivers/net/wireless/rtl8812au/include/rtl8814a_cmd.h -new file mode 100755 +new file mode 100644 index 0000000..e2e0236 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8814a_cmd.h @@ -433408,7 +433408,7 @@ index 0000000..bb925e4 + +#endif diff --git a/drivers/net/wireless/rtl8812au/include/rtl8814a_hal.h b/drivers/net/wireless/rtl8812au/include/rtl8814a_hal.h -new file mode 100755 +new file mode 100644 index 0000000..a2846bb --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8814a_hal.h @@ -433785,7 +433785,7 @@ index 0000000..1137a9b + +#endif /* __RTL8814A_LED_H__ */ diff --git a/drivers/net/wireless/rtl8812au/include/rtl8814a_recv.h b/drivers/net/wireless/rtl8812au/include/rtl8814a_recv.h -new file mode 100755 +new file mode 100644 index 0000000..e9626f3 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8814a_recv.h @@ -434021,7 +434021,7 @@ index 0000000..7b11d99 + +#endif/* __RTL8188E_RF_H__ */ diff --git a/drivers/net/wireless/rtl8812au/include/rtl8814a_spec.h b/drivers/net/wireless/rtl8812au/include/rtl8814a_spec.h -new file mode 100755 +new file mode 100644 index 0000000..43a6381 --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8814a_spec.h @@ -434713,7 +434713,7 @@ index 0000000..5d95e1f +#endif +#endif diff --git a/drivers/net/wireless/rtl8812au/include/rtl8814a_xmit.h b/drivers/net/wireless/rtl8812au/include/rtl8814a_xmit.h -new file mode 100755 +new file mode 100644 index 0000000..099760d --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8814a_xmit.h @@ -435914,7 +435914,7 @@ index 0000000..089f97d + +#endif /* _RTL8822B_HAL_H_ */ diff --git a/drivers/net/wireless/rtl8812au/include/rtl8822be_hal.h b/drivers/net/wireless/rtl8812au/include/rtl8822be_hal.h -new file mode 100755 +new file mode 100644 index 0000000..8379fab --- /dev/null +++ b/drivers/net/wireless/rtl8812au/include/rtl8822be_hal.h @@ -496518,7 +496518,7 @@ index 0000000..d159169 +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/drivers/net/wireless/rtl8814au/Makefile b/drivers/net/wireless/rtl8814au/Makefile -new file mode 100755 +new file mode 100644 index 0000000..ef959e7 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/Makefile @@ -606804,7 +606804,7 @@ index 0000000..cf167a5 + +#endif diff --git a/drivers/net/wireless/rtl8814au/hal/btc/HalBtc8703b2Ant.c b/drivers/net/wireless/rtl8814au/hal/btc/HalBtc8703b2Ant.c -new file mode 100755 +new file mode 100644 index 0000000..d5c5c47 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/btc/HalBtc8703b2Ant.c @@ -611674,7 +611674,7 @@ index 0000000..d5c5c47 +#endif + diff --git a/drivers/net/wireless/rtl8814au/hal/btc/HalBtc8703b2Ant.h b/drivers/net/wireless/rtl8814au/hal/btc/HalBtc8703b2Ant.h -new file mode 100755 +new file mode 100644 index 0000000..361c443 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/btc/HalBtc8703b2Ant.h @@ -763388,7 +763388,7 @@ index 0000000..ec8c6fa +#endif + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/phydm_rxhp.c b/drivers/net/wireless/rtl8814au/hal/phydm/phydm_rxhp.c -new file mode 100755 +new file mode 100644 index 0000000..8a4a273 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/phydm_rxhp.c @@ -765086,7 +765086,7 @@ index 0000000..8a4a273 + + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/phydm_rxhp.h b/drivers/net/wireless/rtl8814au/hal/phydm/phydm_rxhp.h -new file mode 100755 +new file mode 100644 index 0000000..a1fe97f --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/phydm_rxhp.h @@ -816551,7 +816551,7 @@ index 0000000..e9c28bf +#define COMMIT_BY_8814A "BB_LUKE" +#define RELEASE_VERSION_8814A 81 diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_bb.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_bb.c -new file mode 100755 +new file mode 100644 index 0000000..09f3fbf --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_bb.c @@ -817362,7 +817362,7 @@ index 0000000..09f3fbf +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_bb.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_bb.h -new file mode 100755 +new file mode 100644 index 0000000..a5429f1 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_bb.h @@ -817437,7 +817437,7 @@ index 0000000..a5429f1 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_fw.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_fw.c -new file mode 100755 +new file mode 100644 index 0000000..dc91392 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_fw.c @@ -824080,7 +824080,7 @@ index 0000000..dc91392 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_fw.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_fw.h -new file mode 100755 +new file mode 100644 index 0000000..945819a --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_fw.h @@ -824159,7 +824159,7 @@ index 0000000..945819a +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_mac.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_mac.c -new file mode 100755 +new file mode 100644 index 0000000..ed73444 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_mac.c @@ -824451,7 +824451,7 @@ index 0000000..ed73444 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_mac.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_mac.h -new file mode 100755 +new file mode 100644 index 0000000..73158b4 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_mac.h @@ -824496,7 +824496,7 @@ index 0000000..73158b4 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_rf.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_rf.c -new file mode 100755 +new file mode 100644 index 0000000..29df963 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_rf.c @@ -829966,7 +829966,7 @@ index 0000000..29df963 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_rf.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_rf.h -new file mode 100755 +new file mode 100644 index 0000000..c4dd473 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halhwimg8821a_rf.h @@ -830121,7 +830121,7 @@ index 0000000..c4dd473 +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_ce.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_ce.c -new file mode 100755 +new file mode 100644 index 0000000..01da5a1 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_ce.c @@ -830452,7 +830452,7 @@ index 0000000..01da5a1 + + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_ce.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_ce.h -new file mode 100755 +new file mode 100644 index 0000000..688a95e --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_ce.h @@ -830510,7 +830510,7 @@ index 0000000..688a95e +#endif // #ifndef __HAL_PHY_RF_8821A_H__ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_win.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_win.c -new file mode 100755 +new file mode 100644 index 0000000..40d6b52 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_win.c @@ -831664,7 +831664,7 @@ index 0000000..40d6b52 + + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_win.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_win.h -new file mode 100755 +new file mode 100644 index 0000000..5d239ad --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/halphyrf_8821a_win.h @@ -831742,7 +831742,7 @@ index 0000000..5d239ad +#endif // #ifndef __HAL_PHY_RF_8821A_H__ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.c -new file mode 100755 +new file mode 100644 index 0000000..382025b --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.c @@ -832623,7 +832623,7 @@ index 0000000..382025b +#endif + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.h -new file mode 100755 +new file mode 100644 index 0000000..8c74fec --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ap.h @@ -832677,7 +832677,7 @@ index 0000000..8c74fec +#endif // #ifndef __PHYDM_IQK_8821A_H__ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.c -new file mode 100755 +new file mode 100644 index 0000000..28905fd --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.c @@ -833559,7 +833559,7 @@ index 0000000..28905fd +#endif + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.h -new file mode 100755 +new file mode 100644 index 0000000..f44f445 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.h @@ -833613,7 +833613,7 @@ index 0000000..f44f445 +#endif // #ifndef __PHYDM_IQK_8821A_H__ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.c -new file mode 100755 +new file mode 100644 index 0000000..aeb4979 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.c @@ -834494,7 +834494,7 @@ index 0000000..aeb4979 +#endif + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.h -new file mode 100755 +new file mode 100644 index 0000000..8c74fec --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_iqk_8821a_win.h @@ -834548,7 +834548,7 @@ index 0000000..8c74fec +#endif // #ifndef __PHYDM_IQK_8821A_H__ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_regconfig8821a.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_regconfig8821a.c -new file mode 100755 +new file mode 100644 index 0000000..c09db08 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_regconfig8821a.c @@ -834774,7 +834774,7 @@ index 0000000..c09db08 +#endif /* #if (RTL8821A_SUPPORT == 1)*/ + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_regconfig8821a.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_regconfig8821a.h -new file mode 100755 +new file mode 100644 index 0000000..a07fd74 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_regconfig8821a.h @@ -834876,7 +834876,7 @@ index 0000000..a07fd74 +#endif // end of SUPPORT + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_rtl8821a.c b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_rtl8821a.c -new file mode 100755 +new file mode 100644 index 0000000..27bccb3 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_rtl8821a.c @@ -834952,7 +834952,7 @@ index 0000000..27bccb3 +#endif //#if (RTL8821A_SUPPORT == 1) + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_rtl8821a.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_rtl8821a.h -new file mode 100755 +new file mode 100644 index 0000000..0b5edf5 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/phydm_rtl8821a.h @@ -834987,7 +834987,7 @@ index 0000000..0b5edf5 +#endif + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/version_rtl8821a.h b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/version_rtl8821a.h -new file mode 100755 +new file mode 100644 index 0000000..5e10b15 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/rtl8821a/version_rtl8821a.h @@ -836942,7 +836942,7 @@ index 0000000..7efdc02 +#endif + diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/txbf/haltxbf8821b.c b/drivers/net/wireless/rtl8814au/hal/phydm/txbf/haltxbf8821b.c -new file mode 100755 +new file mode 100644 index 0000000..eff8e98 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/txbf/haltxbf8821b.c @@ -837348,7 +837348,7 @@ index 0000000..eff8e98 + +#endif diff --git a/drivers/net/wireless/rtl8814au/hal/phydm/txbf/haltxbf8821b.h b/drivers/net/wireless/rtl8814au/hal/phydm/txbf/haltxbf8821b.h -new file mode 100755 +new file mode 100644 index 0000000..c92d79a --- /dev/null +++ b/drivers/net/wireless/rtl8814au/hal/phydm/txbf/haltxbf8821b.h @@ -909023,7 +909023,7 @@ index 0000000..4ab4feb + +#endif /* __HAL_COMMON_H__ */ diff --git a/drivers/net/wireless/rtl8814au/include/hal_data.h b/drivers/net/wireless/rtl8814au/include/hal_data.h -new file mode 100755 +new file mode 100644 index 0000000..a9dd586 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/hal_data.h @@ -909806,7 +909806,7 @@ index 0000000..a9dd586 + +#endif /* __HAL_DATA_H__ */ diff --git a/drivers/net/wireless/rtl8814au/include/hal_data.h.edited b/drivers/net/wireless/rtl8814au/include/hal_data.h.edited -new file mode 100755 +new file mode 100644 index 0000000..ec59ebb --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/hal_data.h.edited @@ -924745,7 +924745,7 @@ index 0000000..a3bb7df + +#endif diff --git a/drivers/net/wireless/rtl8814au/include/rtl8723b_hal.h b/drivers/net/wireless/rtl8814au/include/rtl8723b_hal.h -new file mode 100755 +new file mode 100644 index 0000000..e6391a4 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8723b_hal.h @@ -925049,7 +925049,7 @@ index 0000000..e6391a4 + +#endif diff --git a/drivers/net/wireless/rtl8814au/include/rtl8723b_led.h b/drivers/net/wireless/rtl8814au/include/rtl8723b_led.h -new file mode 100755 +new file mode 100644 index 0000000..0a7b2c9 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8723b_led.h @@ -925103,7 +925103,7 @@ index 0000000..0a7b2c9 + +#endif diff --git a/drivers/net/wireless/rtl8814au/include/rtl8723b_recv.h b/drivers/net/wireless/rtl8814au/include/rtl8723b_recv.h -new file mode 100755 +new file mode 100644 index 0000000..fd9faef --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8723b_recv.h @@ -925236,7 +925236,7 @@ index 0000000..bf56dde + +#endif diff --git a/drivers/net/wireless/rtl8814au/include/rtl8723b_spec.h b/drivers/net/wireless/rtl8814au/include/rtl8723b_spec.h -new file mode 100755 +new file mode 100644 index 0000000..85b9d1e --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8723b_spec.h @@ -925573,7 +925573,7 @@ index 0000000..8067359 +#endif +#endif diff --git a/drivers/net/wireless/rtl8814au/include/rtl8723b_xmit.h b/drivers/net/wireless/rtl8814au/include/rtl8723b_xmit.h -new file mode 100755 +new file mode 100644 index 0000000..7cc33e1 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8723b_xmit.h @@ -929367,7 +929367,7 @@ index 0000000..9fe4dfb +#include "rtl8821a_xmit.h" +#endif /* CONFIG_RTL8821A */ diff --git a/drivers/net/wireless/rtl8814au/include/rtl8814a_cmd.h b/drivers/net/wireless/rtl8814au/include/rtl8814a_cmd.h -new file mode 100755 +new file mode 100644 index 0000000..e2e0236 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8814a_cmd.h @@ -929565,7 +929565,7 @@ index 0000000..bb925e4 + +#endif diff --git a/drivers/net/wireless/rtl8814au/include/rtl8814a_hal.h b/drivers/net/wireless/rtl8814au/include/rtl8814a_hal.h -new file mode 100755 +new file mode 100644 index 0000000..a2846bb --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8814a_hal.h @@ -929942,7 +929942,7 @@ index 0000000..1137a9b + +#endif /* __RTL8814A_LED_H__ */ diff --git a/drivers/net/wireless/rtl8814au/include/rtl8814a_recv.h b/drivers/net/wireless/rtl8814au/include/rtl8814a_recv.h -new file mode 100755 +new file mode 100644 index 0000000..e9626f3 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8814a_recv.h @@ -930178,7 +930178,7 @@ index 0000000..7b11d99 + +#endif/* __RTL8188E_RF_H__ */ diff --git a/drivers/net/wireless/rtl8814au/include/rtl8814a_spec.h b/drivers/net/wireless/rtl8814au/include/rtl8814a_spec.h -new file mode 100755 +new file mode 100644 index 0000000..43a6381 --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8814a_spec.h @@ -930870,7 +930870,7 @@ index 0000000..5d95e1f +#endif +#endif diff --git a/drivers/net/wireless/rtl8814au/include/rtl8814a_xmit.h b/drivers/net/wireless/rtl8814au/include/rtl8814a_xmit.h -new file mode 100755 +new file mode 100644 index 0000000..099760d --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8814a_xmit.h @@ -932071,7 +932071,7 @@ index 0000000..089f97d + +#endif /* _RTL8822B_HAL_H_ */ diff --git a/drivers/net/wireless/rtl8814au/include/rtl8822be_hal.h b/drivers/net/wireless/rtl8814au/include/rtl8822be_hal.h -new file mode 100755 +new file mode 100644 index 0000000..8379fab --- /dev/null +++ b/drivers/net/wireless/rtl8814au/include/rtl8822be_hal.h