diff --git a/config/kernel/linux-rockchip-default.config b/config/kernel/linux-rockchip-default.config index 6c2e0747e5..b7fb90a939 100644 --- a/config/kernel/linux-rockchip-default.config +++ b/config/kernel/linux-rockchip-default.config @@ -678,7 +678,10 @@ CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_PNP is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE_DEMUX is not set CONFIG_NET_IP_TUNNEL=y @@ -1056,7 +1059,7 @@ CONFIG_NET_CLS_CGROUP=y # CONFIG_NET_CLS_IND is not set CONFIG_NET_SCH_FIFO=y # CONFIG_DCB is not set -# CONFIG_DNS_RESOLVER is not set +CONFIG_DNS_RESOLVER=y # CONFIG_BATMAN_ADV is not set # CONFIG_OPENVSWITCH is not set # CONFIG_VSOCKETS is not set @@ -4085,7 +4088,7 @@ CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_FANOTIFY is not set CONFIG_QUOTA=y @@ -4201,20 +4204,21 @@ CONFIG_AUFS_BR_HFSPLUS=y CONFIG_AUFS_BDEV_LOOP=y # CONFIG_AUFS_DEBUG is not set CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=m +CONFIG_NFS_FS=y CONFIG_NFS_V2=m -CONFIG_NFS_V3=m +CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=m +CONFIG_NFS_V4=y CONFIG_NFS_SWAP=y CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y -CONFIG_PNFS_FILE_LAYOUT=m -CONFIG_PNFS_BLOCK=m +CONFIG_PNFS_FILE_LAYOUT=y +CONFIG_PNFS_BLOCK=y CONFIG_PNFS_FLEXFILE_LAYOUT=m CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" CONFIG_NFS_V4_1_MIGRATION=y CONFIG_NFS_V4_SECURITY_LABEL=y +CONFIG_ROOT_NFS=y CONFIG_NFS_USE_LEGACY_DNS=y CONFIG_NFS_DEBUG=y CONFIG_NFSD=m @@ -4225,13 +4229,13 @@ CONFIG_NFSD_V4=y CONFIG_NFSD_PNFS=y CONFIG_NFSD_V4_SECURITY_LABEL=y CONFIG_NFSD_FAULT_INJECTION=y -CONFIG_GRACE_PERIOD=m -CONFIG_LOCKD=m +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_ACL_SUPPORT=y CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y CONFIG_SUNRPC_BACKCHANNEL=y CONFIG_SUNRPC_SWAP=y CONFIG_SUNRPC_DEBUG=y diff --git a/patch/kernel/rockchip-default/03-patch-4.4.61-62.patch b/patch/kernel/rockchip-default/03-patch-4.4.61-62.patch new file mode 100644 index 0000000000..d86996d4d0 --- /dev/null +++ b/patch/kernel/rockchip-default/03-patch-4.4.61-62.patch @@ -0,0 +1,840 @@ +diff --git a/Makefile b/Makefile +index ef5045b8201d..0309acc34472 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 61 ++SUBLEVEL = 62 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index 75bfca69e418..d5cfa937d622 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -9,6 +9,7 @@ config MIPS + select HAVE_CONTEXT_TRACKING + select HAVE_GENERIC_DMA_COHERENT + select HAVE_IDE ++ select HAVE_IRQ_EXIT_ON_IRQ_STACK + select HAVE_OPROFILE + select HAVE_PERF_EVENTS + select PERF_USE_VMALLOC +diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h +index 15e0fecbc300..ebb9efb02502 100644 +--- a/arch/mips/include/asm/irq.h ++++ b/arch/mips/include/asm/irq.h +@@ -17,6 +17,18 @@ + + #include + ++#define IRQ_STACK_SIZE THREAD_SIZE ++ ++extern void *irq_stack[NR_CPUS]; ++ ++static inline bool on_irq_stack(int cpu, unsigned long sp) ++{ ++ unsigned long low = (unsigned long)irq_stack[cpu]; ++ unsigned long high = low + IRQ_STACK_SIZE; ++ ++ return (low <= sp && sp <= high); ++} ++ + #ifdef CONFIG_I8259 + static inline int irq_canonicalize(int irq) + { +diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h +index a71da576883c..5347f130f536 100644 +--- a/arch/mips/include/asm/stackframe.h ++++ b/arch/mips/include/asm/stackframe.h +@@ -216,12 +216,19 @@ + LONG_S $25, PT_R25(sp) + LONG_S $28, PT_R28(sp) + LONG_S $31, PT_R31(sp) ++ ++ /* Set thread_info if we're coming from user mode */ ++ mfc0 k0, CP0_STATUS ++ sll k0, 3 /* extract cu0 bit */ ++ bltz k0, 9f ++ + ori $28, sp, _THREAD_MASK + xori $28, _THREAD_MASK + #ifdef CONFIG_CPU_CAVIUM_OCTEON + .set mips64 + pref 0, 0($28) /* Prefetch the current pointer */ + #endif ++9: + .set pop + .endm + +diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c +index 154e2039ea5e..ec053ce7bb38 100644 +--- a/arch/mips/kernel/asm-offsets.c ++++ b/arch/mips/kernel/asm-offsets.c +@@ -101,6 +101,7 @@ void output_thread_info_defines(void) + OFFSET(TI_REGS, thread_info, regs); + DEFINE(_THREAD_SIZE, THREAD_SIZE); + DEFINE(_THREAD_MASK, THREAD_MASK); ++ DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE); + BLANK(); + } + +diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S +index baa7b6fc0a60..619e30e2c4f0 100644 +--- a/arch/mips/kernel/genex.S ++++ b/arch/mips/kernel/genex.S +@@ -188,9 +188,44 @@ NESTED(handle_int, PT_SIZE, sp) + + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) +- PTR_LA ra, ret_from_irq +- PTR_LA v0, plat_irq_dispatch +- jr v0 ++ ++ /* ++ * SAVE_ALL ensures we are using a valid kernel stack for the thread. ++ * Check if we are already using the IRQ stack. ++ */ ++ move s1, sp # Preserve the sp ++ ++ /* Get IRQ stack for this CPU */ ++ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG ++#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) ++ lui k1, %hi(irq_stack) ++#else ++ lui k1, %highest(irq_stack) ++ daddiu k1, %higher(irq_stack) ++ dsll k1, 16 ++ daddiu k1, %hi(irq_stack) ++ dsll k1, 16 ++#endif ++ LONG_SRL k0, SMP_CPUID_PTRSHIFT ++ LONG_ADDU k1, k0 ++ LONG_L t0, %lo(irq_stack)(k1) ++ ++ # Check if already on IRQ stack ++ PTR_LI t1, ~(_THREAD_SIZE-1) ++ and t1, t1, sp ++ beq t0, t1, 2f ++ ++ /* Switch to IRQ stack */ ++ li t1, _IRQ_STACK_SIZE ++ PTR_ADD sp, t0, t1 ++ ++2: ++ jal plat_irq_dispatch ++ ++ /* Restore sp */ ++ move sp, s1 ++ ++ j ret_from_irq + #ifdef CONFIG_CPU_MICROMIPS + nop + #endif +@@ -263,8 +298,44 @@ NESTED(except_vec_vi_handler, 0, sp) + + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) +- PTR_LA ra, ret_from_irq +- jr v0 ++ ++ /* ++ * SAVE_ALL ensures we are using a valid kernel stack for the thread. ++ * Check if we are already using the IRQ stack. ++ */ ++ move s1, sp # Preserve the sp ++ ++ /* Get IRQ stack for this CPU */ ++ ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG ++#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) ++ lui k1, %hi(irq_stack) ++#else ++ lui k1, %highest(irq_stack) ++ daddiu k1, %higher(irq_stack) ++ dsll k1, 16 ++ daddiu k1, %hi(irq_stack) ++ dsll k1, 16 ++#endif ++ LONG_SRL k0, SMP_CPUID_PTRSHIFT ++ LONG_ADDU k1, k0 ++ LONG_L t0, %lo(irq_stack)(k1) ++ ++ # Check if already on IRQ stack ++ PTR_LI t1, ~(_THREAD_SIZE-1) ++ and t1, t1, sp ++ beq t0, t1, 2f ++ ++ /* Switch to IRQ stack */ ++ li t1, _IRQ_STACK_SIZE ++ PTR_ADD sp, t0, t1 ++ ++2: ++ jalr v0 ++ ++ /* Restore sp */ ++ move sp, s1 ++ ++ j ret_from_irq + END(except_vec_vi_handler) + + /* +diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c +index 8eb5af805964..dc1180a8bfa1 100644 +--- a/arch/mips/kernel/irq.c ++++ b/arch/mips/kernel/irq.c +@@ -25,6 +25,8 @@ + #include + #include + ++void *irq_stack[NR_CPUS]; ++ + /* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themselves. +@@ -55,6 +57,15 @@ void __init init_IRQ(void) + irq_set_noprobe(i); + + arch_init_irq(); ++ ++ for_each_possible_cpu(i) { ++ int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE; ++ void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages); ++ ++ irq_stack[i] = s; ++ pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, ++ irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE); ++ } + } + + #ifdef CONFIG_DEBUG_STACKOVERFLOW +diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c +index fc537d1b649d..8c26ecac930d 100644 +--- a/arch/mips/kernel/process.c ++++ b/arch/mips/kernel/process.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -552,7 +553,19 @@ EXPORT_SYMBOL(unwind_stack_by_address); + unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, + unsigned long pc, unsigned long *ra) + { +- unsigned long stack_page = (unsigned long)task_stack_page(task); ++ unsigned long stack_page = 0; ++ int cpu; ++ ++ for_each_possible_cpu(cpu) { ++ if (on_irq_stack(cpu, *sp)) { ++ stack_page = (unsigned long)irq_stack[cpu]; ++ break; ++ } ++ } ++ ++ if (!stack_page) ++ stack_page = (unsigned long)task_stack_page(task); ++ + return unwind_stack_by_address(stack_page, sp, pc, ra); + } + #endif +diff --git a/block/blk-mq.c b/block/blk-mq.c +index d8d63c38bf29..0d1af3e44efb 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -1470,7 +1470,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, + INIT_LIST_HEAD(&tags->page_list); + + tags->rqs = kzalloc_node(set->queue_depth * sizeof(struct request *), +- GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY, ++ GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, + set->numa_node); + if (!tags->rqs) { + blk_mq_free_tags(tags); +@@ -1496,7 +1496,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, + + do { + page = alloc_pages_node(set->numa_node, +- GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO, ++ GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO, + this_order); + if (page) + break; +@@ -1517,7 +1517,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, + * Allow kmemleak to scan these pages as they contain pointers + * to additional allocations like via ops->init_request(). + */ +- kmemleak_alloc(p, order_to_size(this_order), 1, GFP_KERNEL); ++ kmemleak_alloc(p, order_to_size(this_order), 1, GFP_NOIO); + entries_per_page = order_to_size(this_order) / rq_size; + to_do = min(entries_per_page, set->queue_depth - i); + left -= to_do * rq_size; +diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c +index 69d4a1326fee..53e61459c69f 100644 +--- a/drivers/crypto/caam/ctrl.c ++++ b/drivers/crypto/caam/ctrl.c +@@ -278,7 +278,8 @@ static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask) + /* Try to run it through DECO0 */ + ret = run_descriptor_deco0(ctrldev, desc, &status); + +- if (ret || status) { ++ if (ret || ++ (status && status != JRSTA_SSRC_JUMP_HALT_CC)) { + dev_err(ctrldev, + "Failed to deinstantiate RNG4 SH%d\n", + sh_idx); +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index fb9f647bb5cd..5044f2257e89 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -1159,7 +1159,7 @@ struct intel_gen6_power_mgmt { + struct intel_rps_client semaphores, mmioflips; + + /* manual wa residency calculations */ +- struct intel_rps_ei up_ei, down_ei; ++ struct intel_rps_ei ei; + + /* + * Protects RPS/RC6 register access and PCU communication. +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 0f42a2782afc..b7b0a38acd67 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -994,68 +994,51 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv, + ei->media_c0 = I915_READ(VLV_MEDIA_C0_COUNT); + } + +-static bool vlv_c0_above(struct drm_i915_private *dev_priv, +- const struct intel_rps_ei *old, +- const struct intel_rps_ei *now, +- int threshold) +-{ +- u64 time, c0; +- unsigned int mul = 100; +- +- if (old->cz_clock == 0) +- return false; +- +- if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) +- mul <<= 8; +- +- time = now->cz_clock - old->cz_clock; +- time *= threshold * dev_priv->czclk_freq; +- +- /* Workload can be split between render + media, e.g. SwapBuffers +- * being blitted in X after being rendered in mesa. To account for +- * this we need to combine both engines into our activity counter. +- */ +- c0 = now->render_c0 - old->render_c0; +- c0 += now->media_c0 - old->media_c0; +- c0 *= mul * VLV_CZ_CLOCK_TO_MILLI_SEC; +- +- return c0 >= time; +-} +- + void gen6_rps_reset_ei(struct drm_i915_private *dev_priv) + { +- vlv_c0_read(dev_priv, &dev_priv->rps.down_ei); +- dev_priv->rps.up_ei = dev_priv->rps.down_ei; ++ memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei)); + } + + static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) + { ++ const struct intel_rps_ei *prev = &dev_priv->rps.ei; + struct intel_rps_ei now; + u32 events = 0; + +- if ((pm_iir & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) == 0) ++ if ((pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) == 0) + return 0; + + vlv_c0_read(dev_priv, &now); + if (now.cz_clock == 0) + return 0; + +- if (pm_iir & GEN6_PM_RP_DOWN_EI_EXPIRED) { +- if (!vlv_c0_above(dev_priv, +- &dev_priv->rps.down_ei, &now, +- dev_priv->rps.down_threshold)) +- events |= GEN6_PM_RP_DOWN_THRESHOLD; +- dev_priv->rps.down_ei = now; +- } ++ if (prev->cz_clock) { ++ u64 time, c0; ++ unsigned int mul; + +- if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) { +- if (vlv_c0_above(dev_priv, +- &dev_priv->rps.up_ei, &now, +- dev_priv->rps.up_threshold)) +- events |= GEN6_PM_RP_UP_THRESHOLD; +- dev_priv->rps.up_ei = now; ++ mul = VLV_CZ_CLOCK_TO_MILLI_SEC * 100; /* scale to threshold% */ ++ if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) ++ mul <<= 8; ++ ++ time = now.cz_clock - prev->cz_clock; ++ time *= dev_priv->czclk_freq; ++ ++ /* Workload can be split between render + media, ++ * e.g. SwapBuffers being blitted in X after being rendered in ++ * mesa. To account for this we need to combine both engines ++ * into our activity counter. ++ */ ++ c0 = now.render_c0 - prev->render_c0; ++ c0 += now.media_c0 - prev->media_c0; ++ c0 *= mul; ++ ++ if (c0 > time * dev_priv->rps.up_threshold) ++ events = GEN6_PM_RP_UP_THRESHOLD; ++ else if (c0 < time * dev_priv->rps.down_threshold) ++ events = GEN6_PM_RP_DOWN_THRESHOLD; + } + ++ dev_priv->rps.ei = now; + return events; + } + +@@ -4390,7 +4373,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) + /* Let's track the enabled rps events */ + if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) + /* WaGsvRC0ResidencyMethod:vlv */ +- dev_priv->pm_rps_events = GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED; ++ dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; + else + dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index e7c18519274a..fd4690ed93c0 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -4376,6 +4376,12 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) + break; + } + ++ /* When byt can survive without system hang with dynamic ++ * sw freq adjustments, this restriction can be lifted. ++ */ ++ if (IS_VALLEYVIEW(dev_priv)) ++ goto skip_hw_write; ++ + I915_WRITE(GEN6_RP_UP_EI, + GT_INTERVAL_FROM_US(dev_priv, ei_up)); + I915_WRITE(GEN6_RP_UP_THRESHOLD, +@@ -4394,6 +4400,7 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) + GEN6_RP_UP_BUSY_AVG | + GEN6_RP_DOWN_IDLE_AVG); + ++skip_hw_write: + dev_priv->rps.power = new_power; + dev_priv->rps.up_threshold = threshold_up; + dev_priv->rps.down_threshold = threshold_down; +@@ -4404,8 +4411,9 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) + { + u32 mask = 0; + ++ /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */ + if (val > dev_priv->rps.min_freq_softlimit) +- mask |= GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; ++ mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; + if (val < dev_priv->rps.max_freq_softlimit) + mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD; + +@@ -4509,7 +4517,7 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) + { + mutex_lock(&dev_priv->rps.hw_lock); + if (dev_priv->rps.enabled) { +- if (dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED)) ++ if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED) + gen6_rps_reset_ei(dev_priv); + I915_WRITE(GEN6_PMINTRMSK, + gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); +diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c +index c0720c1ee4c9..5abab8800891 100644 +--- a/drivers/mtd/bcm47xxpart.c ++++ b/drivers/mtd/bcm47xxpart.c +@@ -225,12 +225,10 @@ static int bcm47xxpart_parse(struct mtd_info *master, + + last_trx_part = curr_part - 1; + +- /* +- * We have whole TRX scanned, skip to the next part. Use +- * roundown (not roundup), as the loop will increase +- * offset in next step. +- */ +- offset = rounddown(offset + trx->length, blocksize); ++ /* Jump to the end of TRX */ ++ offset = roundup(offset + trx->length, blocksize); ++ /* Next loop iteration will increase the offset */ ++ offset -= blocksize; + continue; + } + +diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c +index 7af870a3c549..855c43d8f7e0 100644 +--- a/drivers/net/ethernet/ibm/ibmveth.c ++++ b/drivers/net/ethernet/ibm/ibmveth.c +@@ -58,7 +58,7 @@ static struct kobj_type ktype_veth_pool; + + static const char ibmveth_driver_name[] = "ibmveth"; + static const char ibmveth_driver_string[] = "IBM Power Virtual Ethernet Driver"; +-#define ibmveth_driver_version "1.05" ++#define ibmveth_driver_version "1.06" + + MODULE_AUTHOR("Santiago Leon "); + MODULE_DESCRIPTION("IBM Power Virtual Ethernet Driver"); +@@ -137,6 +137,11 @@ static inline int ibmveth_rxq_frame_offset(struct ibmveth_adapter *adapter) + return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK; + } + ++static inline int ibmveth_rxq_large_packet(struct ibmveth_adapter *adapter) ++{ ++ return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_LRG_PKT; ++} ++ + static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter) + { + return be32_to_cpu(adapter->rx_queue.queue_addr[adapter->rx_queue.index].length); +@@ -1172,6 +1177,45 @@ map_failed: + goto retry_bounce; + } + ++static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt) ++{ ++ int offset = 0; ++ ++ /* only TCP packets will be aggregated */ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ struct iphdr *iph = (struct iphdr *)skb->data; ++ ++ if (iph->protocol == IPPROTO_TCP) { ++ offset = iph->ihl * 4; ++ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; ++ } else { ++ return; ++ } ++ } else if (skb->protocol == htons(ETH_P_IPV6)) { ++ struct ipv6hdr *iph6 = (struct ipv6hdr *)skb->data; ++ ++ if (iph6->nexthdr == IPPROTO_TCP) { ++ offset = sizeof(struct ipv6hdr); ++ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; ++ } else { ++ return; ++ } ++ } else { ++ return; ++ } ++ /* if mss is not set through Large Packet bit/mss in rx buffer, ++ * expect that the mss will be written to the tcp header checksum. ++ */ ++ if (lrg_pkt) { ++ skb_shinfo(skb)->gso_size = mss; ++ } else if (offset) { ++ struct tcphdr *tcph = (struct tcphdr *)(skb->data + offset); ++ ++ skb_shinfo(skb)->gso_size = ntohs(tcph->check); ++ tcph->check = 0; ++ } ++} ++ + static int ibmveth_poll(struct napi_struct *napi, int budget) + { + struct ibmveth_adapter *adapter = +@@ -1180,6 +1224,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) + int frames_processed = 0; + unsigned long lpar_rc; + struct iphdr *iph; ++ u16 mss = 0; + + restart_poll: + while (frames_processed < budget) { +@@ -1197,9 +1242,21 @@ restart_poll: + int length = ibmveth_rxq_frame_length(adapter); + int offset = ibmveth_rxq_frame_offset(adapter); + int csum_good = ibmveth_rxq_csum_good(adapter); ++ int lrg_pkt = ibmveth_rxq_large_packet(adapter); + + skb = ibmveth_rxq_get_buffer(adapter); + ++ /* if the large packet bit is set in the rx queue ++ * descriptor, the mss will be written by PHYP eight ++ * bytes from the start of the rx buffer, which is ++ * skb->data at this stage ++ */ ++ if (lrg_pkt) { ++ __be64 *rxmss = (__be64 *)(skb->data + 8); ++ ++ mss = (u16)be64_to_cpu(*rxmss); ++ } ++ + new_skb = NULL; + if (length < rx_copybreak) + new_skb = netdev_alloc_skb(netdev, length); +@@ -1233,11 +1290,15 @@ restart_poll: + if (iph->check == 0xffff) { + iph->check = 0; + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); +- adapter->rx_large_packets++; + } + } + } + ++ if (length > netdev->mtu + ETH_HLEN) { ++ ibmveth_rx_mss_helper(skb, mss, lrg_pkt); ++ adapter->rx_large_packets++; ++ } ++ + napi_gro_receive(napi, skb); /* send it up */ + + netdev->stats.rx_packets++; +diff --git a/drivers/net/ethernet/ibm/ibmveth.h b/drivers/net/ethernet/ibm/ibmveth.h +index 4eade67fe30c..7acda04d034e 100644 +--- a/drivers/net/ethernet/ibm/ibmveth.h ++++ b/drivers/net/ethernet/ibm/ibmveth.h +@@ -209,6 +209,7 @@ struct ibmveth_rx_q_entry { + #define IBMVETH_RXQ_TOGGLE 0x80000000 + #define IBMVETH_RXQ_TOGGLE_SHIFT 31 + #define IBMVETH_RXQ_VALID 0x40000000 ++#define IBMVETH_RXQ_LRG_PKT 0x04000000 + #define IBMVETH_RXQ_NO_CSUM 0x02000000 + #define IBMVETH_RXQ_CSUM_GOOD 0x01000000 + #define IBMVETH_RXQ_OFF_MASK 0x0000FFFF +diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c +index 3348e646db70..6eba58044456 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/cq.c ++++ b/drivers/net/ethernet/mellanox/mlx4/cq.c +@@ -101,13 +101,19 @@ void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn) + { + struct mlx4_cq *cq; + ++ rcu_read_lock(); + cq = radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree, + cqn & (dev->caps.num_cqs - 1)); ++ rcu_read_unlock(); ++ + if (!cq) { + mlx4_dbg(dev, "Completion event for bogus CQ %08x\n", cqn); + return; + } + ++ /* Acessing the CQ outside of rcu_read_lock is safe, because ++ * the CQ is freed only after interrupt handling is completed. ++ */ + ++cq->arm_sn; + + cq->comp(cq); +@@ -118,23 +124,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type) + struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table; + struct mlx4_cq *cq; + +- spin_lock(&cq_table->lock); +- ++ rcu_read_lock(); + cq = radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1)); +- if (cq) +- atomic_inc(&cq->refcount); +- +- spin_unlock(&cq_table->lock); ++ rcu_read_unlock(); + + if (!cq) { +- mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn); ++ mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn); + return; + } + ++ /* Acessing the CQ outside of rcu_read_lock is safe, because ++ * the CQ is freed only after interrupt handling is completed. ++ */ + cq->event(cq, event_type); +- +- if (atomic_dec_and_test(&cq->refcount)) +- complete(&cq->free); + } + + static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, +@@ -301,9 +303,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, + if (err) + return err; + +- spin_lock_irq(&cq_table->lock); ++ spin_lock(&cq_table->lock); + err = radix_tree_insert(&cq_table->tree, cq->cqn, cq); +- spin_unlock_irq(&cq_table->lock); ++ spin_unlock(&cq_table->lock); + if (err) + goto err_icm; + +@@ -347,9 +349,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, + return 0; + + err_radix: +- spin_lock_irq(&cq_table->lock); ++ spin_lock(&cq_table->lock); + radix_tree_delete(&cq_table->tree, cq->cqn); +- spin_unlock_irq(&cq_table->lock); ++ spin_unlock(&cq_table->lock); + + err_icm: + mlx4_cq_free_icm(dev, cq->cqn); +@@ -368,15 +370,15 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq) + if (err) + mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn); + ++ spin_lock(&cq_table->lock); ++ radix_tree_delete(&cq_table->tree, cq->cqn); ++ spin_unlock(&cq_table->lock); ++ + synchronize_irq(priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq); + if (priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(cq->vector)].irq != + priv->eq_table.eq[MLX4_EQ_ASYNC].irq) + synchronize_irq(priv->eq_table.eq[MLX4_EQ_ASYNC].irq); + +- spin_lock_irq(&cq_table->lock); +- radix_tree_delete(&cq_table->tree, cq->cqn); +- spin_unlock_irq(&cq_table->lock); +- + if (atomic_dec_and_test(&cq->refcount)) + complete(&cq->free); + wait_for_completion(&cq->free); +diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c +index 28a4b34310b2..82bf1b539d87 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c ++++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c +@@ -439,8 +439,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) + ring->cqn = priv->rx_cq[ring_ind]->mcq.cqn; + + ring->stride = stride; +- if (ring->stride <= TXBB_SIZE) ++ if (ring->stride <= TXBB_SIZE) { ++ /* Stamp first unused send wqe */ ++ __be32 *ptr = (__be32 *)ring->buf; ++ __be32 stamp = cpu_to_be32(1 << STAMP_SHIFT); ++ *ptr = stamp; ++ /* Move pointer to start of rx section */ + ring->buf += TXBB_SIZE; ++ } + + ring->log_stride = ffs(ring->stride) - 1; + ring->buf_size = ring->size * ring->stride; +diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +index d314d96dcb1c..d1fc7fa87b05 100644 +--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c ++++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +@@ -2955,6 +2955,9 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave, + put_res(dev, slave, srqn, RES_SRQ); + qp->srq = srq; + } ++ ++ /* Save param3 for dynamic changes from VST back to VGT */ ++ qp->param3 = qpc->param3; + put_res(dev, slave, rcqn, RES_CQ); + put_res(dev, slave, mtt_base, RES_MTT); + res_end_move(dev, slave, RES_QP, qpn); +@@ -3747,7 +3750,6 @@ int mlx4_INIT2RTR_QP_wrapper(struct mlx4_dev *dev, int slave, + int qpn = vhcr->in_modifier & 0x7fffff; + struct res_qp *qp; + u8 orig_sched_queue; +- __be32 orig_param3 = qpc->param3; + u8 orig_vlan_control = qpc->pri_path.vlan_control; + u8 orig_fvl_rx = qpc->pri_path.fvl_rx; + u8 orig_pri_path_fl = qpc->pri_path.fl; +@@ -3789,7 +3791,6 @@ out: + */ + if (!err) { + qp->sched_queue = orig_sched_queue; +- qp->param3 = orig_param3; + qp->vlan_control = orig_vlan_control; + qp->fvl_rx = orig_fvl_rx; + qp->pri_path_fl = orig_pri_path_fl; +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 9e62c93af96e..7c2d87befb51 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -2602,8 +2602,15 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, + if (ret < 0) + return ret; + +- /* The port state is unknown until the reset completes. */ +- if (!(portstatus & USB_PORT_STAT_RESET)) ++ /* ++ * The port state is unknown until the reset completes. ++ * ++ * On top of that, some chips may require additional time ++ * to re-establish a connection after the reset is complete, ++ * so also wait for the connection to be re-established. ++ */ ++ if (!(portstatus & USB_PORT_STAT_RESET) && ++ (portstatus & USB_PORT_STAT_CONNECTION)) + break; + + /* switch to the long delay after two short delay failures */ +diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c +index 210ff64857e1..ec7a50f98f57 100644 +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -235,6 +235,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + int status) + { + struct dwc3 *dwc = dep->dwc; ++ unsigned int unmap_after_complete = false; + int i; + + if (req->queued) { +@@ -259,11 +260,19 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + if (req->request.status == -EINPROGRESS) + req->request.status = status; + +- if (dwc->ep0_bounced && dep->number <= 1) ++ /* ++ * NOTICE we don't want to unmap before calling ->complete() if we're ++ * dealing with a bounced ep0 request. If we unmap it here, we would end ++ * up overwritting the contents of req->buf and this could confuse the ++ * gadget driver. ++ */ ++ if (dwc->ep0_bounced && dep->number <= 1) { + dwc->ep0_bounced = false; +- +- usb_gadget_unmap_request(&dwc->gadget, &req->request, +- req->direction); ++ unmap_after_complete = true; ++ } else { ++ usb_gadget_unmap_request(&dwc->gadget, ++ &req->request, req->direction); ++ } + + dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", + req, dep->name, req->request.actual, +@@ -210,8 +210,9 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, + usb_gadget_giveback_request(&dep->endpoint, &req->request); + spin_lock(&dwc->lock); + +- if (dep->number > 1) +- pm_runtime_put(dwc->dev); ++ if (unmap_after_complete) ++ usb_gadget_unmap_request(&dwc->gadget, ++ &req->request, req->direction); + } + + int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param) +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 3975ac809934..d76800108ddb 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -4138,8 +4138,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + if (unlikely(!PAGE_ALIGNED(req->tp_block_size))) + goto out; + if (po->tp_version >= TPACKET_V3 && +- (int)(req->tp_block_size - +- BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0) ++ req->tp_block_size <= ++ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv)) + goto out; + if (unlikely(req->tp_frame_size < po->tp_hdrlen + + po->tp_reserve)) diff --git a/patch/kernel/rockchip-default/03-patch-4.4.62-63.patch b/patch/kernel/rockchip-default/03-patch-4.4.62-63.patch new file mode 100644 index 0000000000..74a615c79b --- /dev/null +++ b/patch/kernel/rockchip-default/03-patch-4.4.62-63.patch @@ -0,0 +1,1801 @@ +diff --git a/Makefile b/Makefile +index 0309acc34472..ec52973043f6 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 62 ++SUBLEVEL = 63 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig +index d5cfa937d622..8b0424abc84c 100644 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -1413,7 +1413,7 @@ config CPU_MIPS32_R6 + select CPU_SUPPORTS_MSA + select GENERIC_CSUM + select HAVE_KVM +- select MIPS_O32_FP64_SUPPORT if 32BIT ++ select MIPS_O32_FP64_SUPPORT + help + Choose this option to build a kernel for release 6 or later of the + MIPS32 architecture. New MIPS processors, starting with the Warrior +@@ -1464,7 +1464,7 @@ config CPU_MIPS64_R6 + select CPU_SUPPORTS_HIGHMEM + select CPU_SUPPORTS_MSA + select GENERIC_CSUM +- select MIPS_O32_FP64_SUPPORT if MIPS32_O32 ++ select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32 + help + Choose this option to build a kernel for release 6 or later of the + MIPS64 architecture. New MIPS processors, starting with the Warrior +diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c +index 51cdc46a87e2..2e7f60c9fc5d 100644 +--- a/arch/mips/lantiq/irq.c ++++ b/arch/mips/lantiq/irq.c +@@ -269,11 +269,6 @@ static void ltq_hw5_irqdispatch(void) + DEFINE_HWx_IRQDISPATCH(5) + #endif + +-static void ltq_hw_irq_handler(struct irq_desc *desc) +-{ +- ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2); +-} +- + #ifdef CONFIG_MIPS_MT_SMP + void __init arch_init_ipiirq(int irq, struct irqaction *action) + { +@@ -318,19 +313,23 @@ static struct irqaction irq_call = { + asmlinkage void plat_irq_dispatch(void) + { + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; +- int irq; +- +- if (!pending) { +- spurious_interrupt(); +- return; ++ unsigned int i; ++ ++ if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) { ++ do_IRQ(MIPS_CPU_TIMER_IRQ); ++ goto out; ++ } else { ++ for (i = 0; i < MAX_IM; i++) { ++ if (pending & (CAUSEF_IP2 << i)) { ++ ltq_hw_irqdispatch(i); ++ goto out; ++ } ++ } + } ++ pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status()); + +- pending >>= CAUSEB_IP; +- while (pending) { +- irq = fls(pending) - 1; +- do_IRQ(MIPS_CPU_IRQ_BASE + irq); +- pending &= ~BIT(irq); +- } ++out: ++ return; + } + + static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) +@@ -355,6 +354,11 @@ static const struct irq_domain_ops irq_domain_ops = { + .map = icu_map, + }; + ++static struct irqaction cascade = { ++ .handler = no_action, ++ .name = "cascade", ++}; ++ + int __init icu_of_init(struct device_node *node, struct device_node *parent) + { + struct device_node *eiu_node; +@@ -386,7 +390,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) + mips_cpu_irq_init(); + + for (i = 0; i < MAX_IM; i++) +- irq_set_chained_handler(i + 2, ltq_hw_irq_handler); ++ setup_irq(i + 2, &cascade); + + if (cpu_has_vint) { + pr_info("Setting up vectored interrupts\n"); +diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c +index 5c03a6a9b054..a20823210ac0 100644 +--- a/arch/powerpc/kernel/setup_64.c ++++ b/arch/powerpc/kernel/setup_64.c +@@ -220,6 +220,15 @@ static void cpu_ready_for_interrupts(void) + unsigned long lpcr = mfspr(SPRN_LPCR); + mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); + } ++ ++ /* ++ * Fixup HFSCR:TM based on CPU features. The bit is set by our ++ * early asm init because at that point we haven't updated our ++ * CPU features from firmware and device-tree. Here we have, ++ * so let's do it. ++ */ ++ if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP)) ++ mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM); + } + + /* +diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c +index 08a317a9ae4b..a7508d7e20b7 100644 +--- a/arch/x86/entry/vdso/vdso32-setup.c ++++ b/arch/x86/entry/vdso/vdso32-setup.c +@@ -31,8 +31,10 @@ static int __init vdso32_setup(char *s) + { + vdso32_enabled = simple_strtoul(s, NULL, 0); + +- if (vdso32_enabled > 1) ++ if (vdso32_enabled > 1) { + pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n"); ++ vdso32_enabled = 0; ++ } + + return 1; + } +@@ -63,13 +65,18 @@ subsys_initcall(sysenter_setup); + /* Register vsyscall32 into the ABI table */ + #include + ++static const int zero; ++static const int one = 1; ++ + static struct ctl_table abi_table2[] = { + { + .procname = "vsyscall32", + .data = &vdso32_enabled, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec ++ .proc_handler = proc_dointvec_minmax, ++ .extra1 = (int *)&zero, ++ .extra2 = (int *)&one, + }, + {} + }; +diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h +index 1514753fd435..d262f985bbc8 100644 +--- a/arch/x86/include/asm/elf.h ++++ b/arch/x86/include/asm/elf.h +@@ -278,7 +278,7 @@ struct task_struct; + + #define ARCH_DLINFO_IA32 \ + do { \ +- if (vdso32_enabled) { \ ++ if (VDSO_CURRENT_BASE) { \ + NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ + } \ +diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c +index 659f01e165d5..8900400230c6 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c ++++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c +@@ -410,6 +410,9 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) + cpuc->lbr_entries[i].to = msr_lastbranch.to; + cpuc->lbr_entries[i].mispred = 0; + cpuc->lbr_entries[i].predicted = 0; ++ cpuc->lbr_entries[i].in_tx = 0; ++ cpuc->lbr_entries[i].abort = 0; ++ cpuc->lbr_entries[i].cycles = 0; + cpuc->lbr_entries[i].reserved = 0; + } + cpuc->lbr_stack.nr = i; +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 3a7ae80dc49d..0a472e9865c5 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -6678,14 +6678,20 @@ static int nested_vmx_check_vmptr(struct kvm_vcpu *vcpu, int exit_reason, + } + + page = nested_get_page(vcpu, vmptr); +- if (page == NULL || +- *(u32 *)kmap(page) != VMCS12_REVISION) { ++ if (page == NULL) { + nested_vmx_failInvalid(vcpu); ++ skip_emulated_instruction(vcpu); ++ return 1; ++ } ++ if (*(u32 *)kmap(page) != VMCS12_REVISION) { + kunmap(page); ++ nested_release_page_clean(page); ++ nested_vmx_failInvalid(vcpu); + skip_emulated_instruction(vcpu); + return 1; + } + kunmap(page); ++ nested_release_page_clean(page); + vmx->nested.vmxon_ptr = vmptr; + break; + case EXIT_REASON_VMCLEAR: +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index 493f54172b4a..3aebbd6c6f5f 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -628,21 +628,40 @@ void __init init_mem_mapping(void) + * devmem_is_allowed() checks to see if /dev/mem access to a certain address + * is valid. The argument is a physical page number. + * +- * +- * On x86, access has to be given to the first megabyte of ram because that area +- * contains BIOS code and data regions used by X and dosemu and similar apps. +- * Access has to be given to non-kernel-ram areas as well, these contain the PCI +- * mmio resources as well as potential bios/acpi data regions. ++ * On x86, access has to be given to the first megabyte of RAM because that ++ * area traditionally contains BIOS code and data regions used by X, dosemu, ++ * and similar apps. Since they map the entire memory range, the whole range ++ * must be allowed (for mapping), but any areas that would otherwise be ++ * disallowed are flagged as being "zero filled" instead of rejected. ++ * Access has to be given to non-kernel-ram areas as well, these contain the ++ * PCI mmio resources as well as potential bios/acpi data regions. + */ + int devmem_is_allowed(unsigned long pagenr) + { +- if (pagenr < 256) +- return 1; +- if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) ++ if (page_is_ram(pagenr)) { ++ /* ++ * For disallowed memory regions in the low 1MB range, ++ * request that the page be shown as all zeros. ++ */ ++ if (pagenr < 256) ++ return 2; ++ ++ return 0; ++ } ++ ++ /* ++ * This must follow RAM test, since System RAM is considered a ++ * restricted resource under CONFIG_STRICT_IOMEM. ++ */ ++ if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) { ++ /* Low 1MB bypasses iomem restrictions. */ ++ if (pagenr < 256) ++ return 1; ++ + return 0; +- if (!page_is_ram(pagenr)) +- return 1; +- return 0; ++ } ++ ++ return 1; + } + + void free_init_pages(char *what, unsigned long begin, unsigned long end) +diff --git a/crypto/ahash.c b/crypto/ahash.c +index dac1c24e9c3e..f9caf0f74199 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -31,6 +31,7 @@ struct ahash_request_priv { + crypto_completion_t complete; + void *data; + u8 *result; ++ u32 flags; + void *ubuf[] CRYPTO_MINALIGN_ATTR; + }; + +@@ -270,6 +271,8 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) + priv->result = req->result; + priv->complete = req->base.complete; + priv->data = req->base.data; ++ priv->flags = req->base.flags; ++ + /* + * WARNING: We do not backup req->priv here! The req->priv + * is for internal use of the Crypto API and the +@@ -284,38 +287,44 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt) + return 0; + } + +-static void ahash_restore_req(struct ahash_request *req) ++static void ahash_restore_req(struct ahash_request *req, int err) + { + struct ahash_request_priv *priv = req->priv; + ++ if (!err) ++ memcpy(priv->result, req->result, ++ crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); ++ + /* Restore the original crypto request. */ + req->result = priv->result; +- req->base.complete = priv->complete; +- req->base.data = priv->data; ++ ++ ahash_request_set_callback(req, priv->flags, ++ priv->complete, priv->data); + req->priv = NULL; + + /* Free the req->priv.priv from the ADJUSTED request. */ + kzfree(priv); + } + +-static void ahash_op_unaligned_finish(struct ahash_request *req, int err) ++static void ahash_notify_einprogress(struct ahash_request *req) + { + struct ahash_request_priv *priv = req->priv; ++ struct crypto_async_request oreq; + +- if (err == -EINPROGRESS) +- return; +- +- if (!err) +- memcpy(priv->result, req->result, +- crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); ++ oreq.data = priv->data; + +- ahash_restore_req(req); ++ priv->complete(&oreq, -EINPROGRESS); + } + + static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) + { + struct ahash_request *areq = req->data; + ++ if (err == -EINPROGRESS) { ++ ahash_notify_einprogress(areq); ++ return; ++ } ++ + /* + * Restore the original request, see ahash_op_unaligned() for what + * goes where. +@@ -326,7 +335,7 @@ static void ahash_op_unaligned_done(struct crypto_async_request *req, int err) + */ + + /* First copy req->result into req->priv.result */ +- ahash_op_unaligned_finish(areq, err); ++ ahash_restore_req(areq, err); + + /* Complete the ORIGINAL request. */ + areq->base.complete(&areq->base, err); +@@ -342,7 +351,12 @@ static int ahash_op_unaligned(struct ahash_request *req, + return err; + + err = op(req); +- ahash_op_unaligned_finish(req, err); ++ if (err == -EINPROGRESS || ++ (err == -EBUSY && (ahash_request_flags(req) & ++ CRYPTO_TFM_REQ_MAY_BACKLOG))) ++ return err; ++ ++ ahash_restore_req(req, err); + + return err; + } +@@ -377,25 +391,14 @@ int crypto_ahash_digest(struct ahash_request *req) + } + EXPORT_SYMBOL_GPL(crypto_ahash_digest); + +-static void ahash_def_finup_finish2(struct ahash_request *req, int err) ++static void ahash_def_finup_done2(struct crypto_async_request *req, int err) + { +- struct ahash_request_priv *priv = req->priv; ++ struct ahash_request *areq = req->data; + + if (err == -EINPROGRESS) + return; + +- if (!err) +- memcpy(priv->result, req->result, +- crypto_ahash_digestsize(crypto_ahash_reqtfm(req))); +- +- ahash_restore_req(req); +-} +- +-static void ahash_def_finup_done2(struct crypto_async_request *req, int err) +-{ +- struct ahash_request *areq = req->data; +- +- ahash_def_finup_finish2(areq, err); ++ ahash_restore_req(areq, err); + + areq->base.complete(&areq->base, err); + } +@@ -406,11 +409,15 @@ static int ahash_def_finup_finish1(struct ahash_request *req, int err) + goto out; + + req->base.complete = ahash_def_finup_done2; +- req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; ++ + err = crypto_ahash_reqtfm(req)->final(req); ++ if (err == -EINPROGRESS || ++ (err == -EBUSY && (ahash_request_flags(req) & ++ CRYPTO_TFM_REQ_MAY_BACKLOG))) ++ return err; + + out: +- ahash_def_finup_finish2(req, err); ++ ahash_restore_req(req, err); + return err; + } + +@@ -418,7 +425,16 @@ static void ahash_def_finup_done1(struct crypto_async_request *req, int err) + { + struct ahash_request *areq = req->data; + ++ if (err == -EINPROGRESS) { ++ ahash_notify_einprogress(areq); ++ return; ++ } ++ ++ areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; ++ + err = ahash_def_finup_finish1(areq, err); ++ if (areq->priv) ++ return; + + areq->base.complete(&areq->base, err); + } +@@ -433,6 +449,11 @@ static int ahash_def_finup(struct ahash_request *req) + return err; + + err = tfm->update(req); ++ if (err == -EINPROGRESS || ++ (err == -EBUSY && (ahash_request_flags(req) & ++ CRYPTO_TFM_REQ_MAY_BACKLOG))) ++ return err; ++ + return ahash_def_finup_finish1(req, err); + } + +diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c +index 14c2a07c9f3f..67d7489ced01 100644 +--- a/drivers/acpi/nfit.c ++++ b/drivers/acpi/nfit.c +@@ -979,7 +979,11 @@ static int cmp_map(const void *m0, const void *m1) + const struct nfit_set_info_map *map0 = m0; + const struct nfit_set_info_map *map1 = m1; + +- return map0->region_offset - map1->region_offset; ++ if (map0->region_offset < map1->region_offset) ++ return -1; ++ else if (map0->region_offset > map1->region_offset) ++ return 1; ++ return 0; + } + + /* Retrieve the nth entry referencing this spa */ +diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c +index 1648de80e230..62a93b685c54 100644 +--- a/drivers/block/zram/zram_drv.c ++++ b/drivers/block/zram/zram_drv.c +@@ -574,13 +574,13 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index) + + if (!handle || zram_test_flag(meta, index, ZRAM_ZERO)) { + bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); +- clear_page(mem); ++ memset(mem, 0, PAGE_SIZE); + return 0; + } + + cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO); + if (size == PAGE_SIZE) +- copy_page(mem, cmem); ++ memcpy(mem, cmem, PAGE_SIZE); + else + ret = zcomp_decompress(zram->comp, cmem, size, mem); + zs_unmap_object(meta->mem_pool, handle); +@@ -738,7 +738,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, + + if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) { + src = kmap_atomic(page); +- copy_page(cmem, src); ++ memcpy(cmem, src, PAGE_SIZE); + kunmap_atomic(src); + } else { + memcpy(cmem, src, clen); +diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig +index a043107da2af..3143db57ce44 100644 +--- a/drivers/char/Kconfig ++++ b/drivers/char/Kconfig +@@ -583,10 +583,12 @@ config TELCLOCK + controlling the behavior of this hardware. + + config DEVPORT +- bool +- depends on !M68K ++ bool "/dev/port character device" + depends on ISA || PCI + default y ++ help ++ Say Y here if you want to support the /dev/port device. The /dev/port ++ device is similar to /dev/mem, but for I/O ports. + + source "drivers/s390/char/Kconfig" + +diff --git a/drivers/char/mem.c b/drivers/char/mem.c +index 6b1721f978c2..e901463d4972 100644 +--- a/drivers/char/mem.c ++++ b/drivers/char/mem.c +@@ -59,6 +59,10 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) + #endif + + #ifdef CONFIG_STRICT_DEVMEM ++static inline int page_is_allowed(unsigned long pfn) ++{ ++ return devmem_is_allowed(pfn); ++} + static inline int range_is_allowed(unsigned long pfn, unsigned long size) + { + u64 from = ((u64)pfn) << PAGE_SHIFT; +@@ -78,6 +82,10 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) + return 1; + } + #else ++static inline int page_is_allowed(unsigned long pfn) ++{ ++ return 1; ++} + static inline int range_is_allowed(unsigned long pfn, unsigned long size) + { + return 1; +@@ -125,23 +133,31 @@ static ssize_t read_mem(struct file *file, char __user *buf, + + while (count > 0) { + unsigned long remaining; ++ int allowed; + + sz = size_inside_page(p, count); + +- if (!range_is_allowed(p >> PAGE_SHIFT, count)) ++ allowed = page_is_allowed(p >> PAGE_SHIFT); ++ if (!allowed) + return -EPERM; ++ if (allowed == 2) { ++ /* Show zeros for restricted memory. */ ++ remaining = clear_user(buf, sz); ++ } else { ++ /* ++ * On ia64 if a page has been mapped somewhere as ++ * uncached, then it must also be accessed uncached ++ * by the kernel or data corruption may occur. ++ */ ++ ptr = xlate_dev_mem_ptr(p); ++ if (!ptr) ++ return -EFAULT; + +- /* +- * On ia64 if a page has been mapped somewhere as uncached, then +- * it must also be accessed uncached by the kernel or data +- * corruption may occur. +- */ +- ptr = xlate_dev_mem_ptr(p); +- if (!ptr) +- return -EFAULT; ++ remaining = copy_to_user(buf, ptr, sz); ++ ++ unxlate_dev_mem_ptr(p, ptr); ++ } + +- remaining = copy_to_user(buf, ptr, sz); +- unxlate_dev_mem_ptr(p, ptr); + if (remaining) + return -EFAULT; + +@@ -184,30 +200,36 @@ static ssize_t write_mem(struct file *file, const char __user *buf, + #endif + + while (count > 0) { ++ int allowed; ++ + sz = size_inside_page(p, count); + +- if (!range_is_allowed(p >> PAGE_SHIFT, sz)) ++ allowed = page_is_allowed(p >> PAGE_SHIFT); ++ if (!allowed) + return -EPERM; + +- /* +- * On ia64 if a page has been mapped somewhere as uncached, then +- * it must also be accessed uncached by the kernel or data +- * corruption may occur. +- */ +- ptr = xlate_dev_mem_ptr(p); +- if (!ptr) { +- if (written) +- break; +- return -EFAULT; +- } ++ /* Skip actual writing when a page is marked as restricted. */ ++ if (allowed == 1) { ++ /* ++ * On ia64 if a page has been mapped somewhere as ++ * uncached, then it must also be accessed uncached ++ * by the kernel or data corruption may occur. ++ */ ++ ptr = xlate_dev_mem_ptr(p); ++ if (!ptr) { ++ if (written) ++ break; ++ return -EFAULT; ++ } + +- copied = copy_from_user(ptr, buf, sz); +- unxlate_dev_mem_ptr(p, ptr); +- if (copied) { +- written += sz - copied; +- if (written) +- break; +- return -EFAULT; ++ copied = copy_from_user(ptr, buf, sz); ++ unxlate_dev_mem_ptr(p, ptr); ++ if (copied) { ++ written += sz - copied; ++ if (written) ++ break; ++ return -EFAULT; ++ } + } + + buf += sz; +diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c +index 090183f812be..31e8ae916ba0 100644 +--- a/drivers/char/virtio_console.c ++++ b/drivers/char/virtio_console.c +@@ -1130,6 +1130,8 @@ static int put_chars(u32 vtermno, const char *buf, int count) + { + struct port *port; + struct scatterlist sg[1]; ++ void *data; ++ int ret; + + if (unlikely(early_put_chars)) + return early_put_chars(vtermno, buf, count); +@@ -1138,8 +1140,14 @@ static int put_chars(u32 vtermno, const char *buf, int count) + if (!port) + return -EPIPE; + +- sg_init_one(sg, buf, count); +- return __send_to_port(port, sg, 1, count, (void *)buf, false); ++ data = kmemdup(buf, count, GFP_ATOMIC); ++ if (!data) ++ return -ENOMEM; ++ ++ sg_init_one(sg, data, count); ++ ret = __send_to_port(port, sg, 1, count, data, false); ++ kfree(data); ++ return ret; + } + + /* +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +index ece9f4102c0e..7f8acb3ebfcd 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +@@ -714,7 +714,7 @@ nv4a_chipset = { + .i2c = nv04_i2c_new, + .imem = nv40_instmem_new, + .mc = nv44_mc_new, +- .mmu = nv44_mmu_new, ++ .mmu = nv04_mmu_new, + .pci = nv40_pci_new, + .therm = nv40_therm_new, + .timer = nv41_timer_new, +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c +index d4d8942b1347..e55f8302d08a 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c +@@ -198,7 +198,7 @@ nv31_mpeg_intr(struct nvkm_engine *engine) + } + + if (type == 0x00000010) { +- if (!nv31_mpeg_mthd(mpeg, mthd, data)) ++ if (nv31_mpeg_mthd(mpeg, mthd, data)) + show &= ~0x01000000; + } + } +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c +index d433cfa4a8ab..36af0a8927fc 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c +@@ -172,7 +172,7 @@ nv44_mpeg_intr(struct nvkm_engine *engine) + } + + if (type == 0x00000010) { +- if (!nv44_mpeg_mthd(subdev->device, mthd, data)) ++ if (nv44_mpeg_mthd(subdev->device, mthd, data)) + show &= ~0x01000000; + } + } +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 16f000a76de5..3258baf3282e 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -189,6 +189,7 @@ static const struct xpad_device { + { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, + { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, + { 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 }, ++ { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE }, + { 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 }, + { 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, + { 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 }, +@@ -310,6 +311,7 @@ static struct usb_device_id xpad_table[] = { + XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ + XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */ + XPAD_XBOX360_VENDOR(0x1532), /* Razer Sabertooth */ ++ XPAD_XBOXONE_VENDOR(0x1532), /* Razer Wildcat */ + XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */ + XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */ + { } +diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c +index 15af9a9753e5..2d203b422129 100644 +--- a/drivers/irqchip/irq-imx-gpcv2.c ++++ b/drivers/irqchip/irq-imx-gpcv2.c +@@ -230,6 +230,8 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, + return -ENOMEM; + } + ++ raw_spin_lock_init(&cd->rlock); ++ + cd->gpc_base = of_iomap(node, 0); + if (!cd->gpc_base) { + pr_err("fsl-gpcv2: unable to map gpc registers\n"); +diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +index f5df9eaba04f..9757f35cd5f5 100644 +--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c ++++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +@@ -1010,8 +1010,8 @@ EXPORT_SYMBOL(dvb_usbv2_probe); + void dvb_usbv2_disconnect(struct usb_interface *intf) + { + struct dvb_usb_device *d = usb_get_intfdata(intf); +- const char *name = d->name; +- struct device dev = d->udev->dev; ++ const char *devname = kstrdup(dev_name(&d->udev->dev), GFP_KERNEL); ++ const char *drvname = d->name; + + dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__, + intf->cur_altsetting->desc.bInterfaceNumber); +@@ -1021,8 +1021,9 @@ void dvb_usbv2_disconnect(struct usb_interface *intf) + + dvb_usbv2_exit(d); + +- dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n", +- KBUILD_MODNAME, name); ++ pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n", ++ KBUILD_MODNAME, drvname, devname); ++ kfree(devname); + } + EXPORT_SYMBOL(dvb_usbv2_disconnect); + +diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +index 733a7ff7b207..caad3b5c01ad 100644 +--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c ++++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +@@ -35,42 +35,51 @@ static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 le + + int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type) + { +- struct hexline hx; +- u8 reset; +- int ret,pos=0; ++ struct hexline *hx; ++ u8 *buf; ++ int ret, pos = 0; ++ u16 cpu_cs_register = cypress[type].cpu_cs_register; ++ ++ buf = kmalloc(sizeof(*hx), GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ hx = (struct hexline *)buf; + + /* stop the CPU */ +- reset = 1; +- if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) ++ buf[0] = 1; ++ if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) + err("could not stop the USB controller CPU."); + +- while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) { +- deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk); +- ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len); ++ while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) { ++ deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n", hx->addr, hx->len, hx->chk); ++ ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len); + +- if (ret != hx.len) { ++ if (ret != hx->len) { + err("error while transferring firmware " + "(transferred size: %d, block size: %d)", +- ret,hx.len); ++ ret, hx->len); + ret = -EINVAL; + break; + } + } + if (ret < 0) { + err("firmware download failed at %d with %d",pos,ret); ++ kfree(buf); + return ret; + } + + if (ret == 0) { + /* restart the CPU */ +- reset = 0; +- if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { ++ buf[0] = 0; ++ if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) { + err("could not restart the USB controller CPU."); + ret = -EINVAL; + } + } else + ret = -EIO; + ++ kfree(buf); ++ + return ret; + } + EXPORT_SYMBOL(usb_cypress_load_firmware); +diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c +index 855c43d8f7e0..f9e4988ea30e 100644 +--- a/drivers/net/ethernet/ibm/ibmveth.c ++++ b/drivers/net/ethernet/ibm/ibmveth.c +@@ -1179,7 +1179,9 @@ map_failed: + + static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt) + { ++ struct tcphdr *tcph; + int offset = 0; ++ int hdr_len; + + /* only TCP packets will be aggregated */ + if (skb->protocol == htons(ETH_P_IP)) { +@@ -1206,14 +1208,20 @@ static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt) + /* if mss is not set through Large Packet bit/mss in rx buffer, + * expect that the mss will be written to the tcp header checksum. + */ ++ tcph = (struct tcphdr *)(skb->data + offset); + if (lrg_pkt) { + skb_shinfo(skb)->gso_size = mss; + } else if (offset) { +- struct tcphdr *tcph = (struct tcphdr *)(skb->data + offset); +- + skb_shinfo(skb)->gso_size = ntohs(tcph->check); + tcph->check = 0; + } ++ ++ if (skb_shinfo(skb)->gso_size) { ++ hdr_len = offset + tcph->doff * 4; ++ skb_shinfo(skb)->gso_segs = ++ DIV_ROUND_UP(skb->len - hdr_len, ++ skb_shinfo(skb)->gso_size); ++ } + } + + static int ibmveth_poll(struct napi_struct *napi, int budget) +diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c +index 4e2b26a88b15..2aa1a1d29cb4 100644 +--- a/drivers/net/usb/catc.c ++++ b/drivers/net/usb/catc.c +@@ -777,7 +777,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + struct net_device *netdev; + struct catc *catc; + u8 broadcast[ETH_ALEN]; +- int i, pktsz; ++ int pktsz, ret; + + if (usb_set_interface(usbdev, + intf->altsetting->desc.bInterfaceNumber, 1)) { +@@ -812,12 +812,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + if ((!catc->ctrl_urb) || (!catc->tx_urb) || + (!catc->rx_urb) || (!catc->irq_urb)) { + dev_err(&intf->dev, "No free urbs available.\n"); +- usb_free_urb(catc->ctrl_urb); +- usb_free_urb(catc->tx_urb); +- usb_free_urb(catc->rx_urb); +- usb_free_urb(catc->irq_urb); +- free_netdev(netdev); +- return -ENOMEM; ++ ret = -ENOMEM; ++ goto fail_free; + } + + /* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */ +@@ -845,15 +841,24 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + catc->irq_buf, 2, catc_irq_done, catc, 1); + + if (!catc->is_f5u011) { ++ u32 *buf; ++ int i; ++ + dev_dbg(dev, "Checking memory size\n"); + +- i = 0x12345678; +- catc_write_mem(catc, 0x7a80, &i, 4); +- i = 0x87654321; +- catc_write_mem(catc, 0xfa80, &i, 4); +- catc_read_mem(catc, 0x7a80, &i, 4); ++ buf = kmalloc(4, GFP_KERNEL); ++ if (!buf) { ++ ret = -ENOMEM; ++ goto fail_free; ++ } ++ ++ *buf = 0x12345678; ++ catc_write_mem(catc, 0x7a80, buf, 4); ++ *buf = 0x87654321; ++ catc_write_mem(catc, 0xfa80, buf, 4); ++ catc_read_mem(catc, 0x7a80, buf, 4); + +- switch (i) { ++ switch (*buf) { + case 0x12345678: + catc_set_reg(catc, TxBufCount, 8); + catc_set_reg(catc, RxBufCount, 32); +@@ -868,6 +873,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + dev_dbg(dev, "32k Memory\n"); + break; + } ++ ++ kfree(buf); + + dev_dbg(dev, "Getting MAC from SEEROM.\n"); + +@@ -914,16 +921,21 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id + usb_set_intfdata(intf, catc); + + SET_NETDEV_DEV(netdev, &intf->dev); +- if (register_netdev(netdev) != 0) { +- usb_set_intfdata(intf, NULL); +- usb_free_urb(catc->ctrl_urb); +- usb_free_urb(catc->tx_urb); +- usb_free_urb(catc->rx_urb); +- usb_free_urb(catc->irq_urb); +- free_netdev(netdev); +- return -EIO; +- } ++ ret = register_netdev(netdev); ++ if (ret) ++ goto fail_clear_intfdata; ++ + return 0; ++ ++fail_clear_intfdata: ++ usb_set_intfdata(intf, NULL); ++fail_free: ++ usb_free_urb(catc->ctrl_urb); ++ usb_free_urb(catc->tx_urb); ++ usb_free_urb(catc->rx_urb); ++ usb_free_urb(catc->irq_urb); ++ free_netdev(netdev); ++ return ret; + } + + static void catc_disconnect(struct usb_interface *intf) +diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c +index f84080215915..17fac0121e56 100644 +--- a/drivers/net/usb/pegasus.c ++++ b/drivers/net/usb/pegasus.c +@@ -126,40 +126,61 @@ static void async_ctrl_callback(struct urb *urb) + + static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) + { ++ u8 *buf; + int ret; + ++ buf = kmalloc(size, GFP_NOIO); ++ if (!buf) ++ return -ENOMEM; ++ + ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0), + PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0, +- indx, data, size, 1000); ++ indx, buf, size, 1000); + if (ret < 0) + netif_dbg(pegasus, drv, pegasus->net, + "%s returned %d\n", __func__, ret); ++ else if (ret <= size) ++ memcpy(data, buf, ret); ++ kfree(buf); + return ret; + } + +-static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) ++static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, ++ const void *data) + { ++ u8 *buf; + int ret; + ++ buf = kmemdup(data, size, GFP_NOIO); ++ if (!buf) ++ return -ENOMEM; ++ + ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), + PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0, +- indx, data, size, 100); ++ indx, buf, size, 100); + if (ret < 0) + netif_dbg(pegasus, drv, pegasus->net, + "%s returned %d\n", __func__, ret); ++ kfree(buf); + return ret; + } + + static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data) + { ++ u8 *buf; + int ret; + ++ buf = kmemdup(&data, 1, GFP_NOIO); ++ if (!buf) ++ return -ENOMEM; ++ + ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), + PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data, +- indx, &data, 1, 1000); ++ indx, buf, 1, 1000); + if (ret < 0) + netif_dbg(pegasus, drv, pegasus->net, + "%s returned %d\n", __func__, ret); ++ kfree(buf); + return ret; + } + +diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c +index d37b7dce2d40..39672984dde1 100644 +--- a/drivers/net/usb/rtl8150.c ++++ b/drivers/net/usb/rtl8150.c +@@ -155,16 +155,36 @@ static const char driver_name [] = "rtl8150"; + */ + static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) + { +- return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), +- RTL8150_REQ_GET_REGS, RTL8150_REQT_READ, +- indx, 0, data, size, 500); ++ void *buf; ++ int ret; ++ ++ buf = kmalloc(size, GFP_NOIO); ++ if (!buf) ++ return -ENOMEM; ++ ++ ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), ++ RTL8150_REQ_GET_REGS, RTL8150_REQT_READ, ++ indx, 0, buf, size, 500); ++ if (ret > 0 && ret <= size) ++ memcpy(data, buf, ret); ++ kfree(buf); ++ return ret; + } + +-static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) ++static int set_registers(rtl8150_t * dev, u16 indx, u16 size, const void *data) + { +- return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), +- RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE, +- indx, 0, data, size, 500); ++ void *buf; ++ int ret; ++ ++ buf = kmemdup(data, size, GFP_NOIO); ++ if (!buf) ++ return -ENOMEM; ++ ++ ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), ++ RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE, ++ indx, 0, buf, size, 500); ++ kfree(buf); ++ return ret; + } + + static void async_set_reg_cb(struct urb *urb) +diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c +index a8762711ad74..03945731eb65 100644 +--- a/drivers/net/wireless/ath/ath9k/common-spectral.c ++++ b/drivers/net/wireless/ath/ath9k/common-spectral.c +@@ -528,6 +528,9 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h + if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK)) + return 0; + ++ if (!spec_priv->rfs_chan_spec_scan) ++ return 1; ++ + /* Output buffers are full, no need to process anything + * since there is no space to put the result anyway + */ +@@ -1072,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = { + + void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv) + { +- if (config_enabled(CONFIG_ATH9K_DEBUGFS)) { ++ if (config_enabled(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) { + relay_close(spec_priv->rfs_chan_spec_scan); + spec_priv->rfs_chan_spec_scan = NULL; + } +@@ -1086,6 +1089,9 @@ void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, + debugfs_phy, + 1024, 256, &rfs_spec_scan_cb, + NULL); ++ if (!spec_priv->rfs_chan_spec_scan) ++ return; ++ + debugfs_create_file("spectral_scan_ctl", + S_IRUSR | S_IWUSR, + debugfs_phy, spec_priv, +diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c +index 5f47356d6942..254b0ee37039 100644 +--- a/drivers/nvdimm/bus.c ++++ b/drivers/nvdimm/bus.c +@@ -590,8 +590,14 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm, + rc = nd_desc->ndctl(nd_desc, nvdimm, cmd, buf, buf_len); + if (rc < 0) + goto out_unlock; ++ nvdimm_bus_unlock(&nvdimm_bus->dev); ++ + if (copy_to_user(p, buf, buf_len)) + rc = -EFAULT; ++ ++ vfree(buf); ++ return rc; ++ + out_unlock: + nvdimm_bus_unlock(&nvdimm_bus->dev); + out: +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index 1062fa42ff26..b2cdc1a1ad4f 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -1816,11 +1816,24 @@ static int __init acer_wmi_enable_lm(void) + return status; + } + ++#define ACER_WMID_ACCEL_HID "BST0001" ++ + static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level, + void *ctx, void **retval) + { ++ struct acpi_device *dev; ++ ++ if (!strcmp(ctx, "SENR")) { ++ if (acpi_bus_get_device(ah, &dev)) ++ return AE_OK; ++ if (!strcmp(ACER_WMID_ACCEL_HID, acpi_device_hid(dev))) ++ return AE_OK; ++ } else ++ return AE_OK; ++ + *(acpi_handle *)retval = ah; +- return AE_OK; ++ ++ return AE_CTRL_TERMINATE; + } + + static int __init acer_wmi_get_handle(const char *name, const char *prop, +@@ -1847,7 +1860,7 @@ static int __init acer_wmi_accel_setup(void) + { + int err; + +- err = acer_wmi_get_handle("SENR", "BST0001", &gsensor_handle); ++ err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle); + if (err) + return err; + +@@ -2185,10 +2198,11 @@ static int __init acer_wmi_init(void) + err = acer_wmi_input_setup(); + if (err) + return err; ++ err = acer_wmi_accel_setup(); ++ if (err) ++ return err; + } + +- acer_wmi_accel_setup(); +- + err = platform_driver_register(&acer_platform_driver); + if (err) { + pr_err("Unable to register platform driver\n"); +diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c +index 60232bd366ef..71216aa68905 100644 +--- a/drivers/rtc/rtc-tegra.c ++++ b/drivers/rtc/rtc-tegra.c +@@ -18,6 +18,7 @@ + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #include ++#include + #include + #include + #include +@@ -59,6 +60,7 @@ struct tegra_rtc_info { + struct platform_device *pdev; + struct rtc_device *rtc_dev; + void __iomem *rtc_base; /* NULL if not initialized. */ ++ struct clk *clk; + int tegra_rtc_irq; /* alarm and periodic irq */ + spinlock_t tegra_rtc_lock; + }; +@@ -332,6 +334,14 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) + if (info->tegra_rtc_irq <= 0) + return -EBUSY; + ++ info->clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(info->clk)) ++ return PTR_ERR(info->clk); ++ ++ ret = clk_prepare_enable(info->clk); ++ if (ret < 0) ++ return ret; ++ + /* set context info. */ + info->pdev = pdev; + spin_lock_init(&info->tegra_rtc_lock); +@@ -352,7 +362,7 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) + ret = PTR_ERR(info->rtc_dev); + dev_err(&pdev->dev, "Unable to register device (err=%d).\n", + ret); +- return ret; ++ goto disable_clk; + } + + ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq, +@@ -362,12 +372,25 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) + dev_err(&pdev->dev, + "Unable to request interrupt for device (err=%d).\n", + ret); +- return ret; ++ goto disable_clk; + } + + dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n"); + + return 0; ++ ++disable_clk: ++ clk_disable_unprepare(info->clk); ++ return ret; ++} ++ ++static int tegra_rtc_remove(struct platform_device *pdev) ++{ ++ struct tegra_rtc_info *info = platform_get_drvdata(pdev); ++ ++ clk_disable_unprepare(info->clk); ++ ++ return 0; + } + + #ifdef CONFIG_PM_SLEEP +@@ -419,6 +442,7 @@ static void tegra_rtc_shutdown(struct platform_device *pdev) + + MODULE_ALIAS("platform:tegra_rtc"); + static struct platform_driver tegra_rtc_driver = { ++ .remove = tegra_rtc_remove, + .shutdown = tegra_rtc_shutdown, + .driver = { + .name = "tegra_rtc", +diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c +index 78430ef28ea4..4d5207dff960 100644 +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -2051,6 +2051,22 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, + + #define READ_CAPACITY_RETRIES_ON_RESET 10 + ++/* ++ * Ensure that we don't overflow sector_t when CONFIG_LBDAF is not set ++ * and the reported logical block size is bigger than 512 bytes. Note ++ * that last_sector is a u64 and therefore logical_to_sectors() is not ++ * applicable. ++ */ ++static bool sd_addressable_capacity(u64 lba, unsigned int sector_size) ++{ ++ u64 last_sector = (lba + 1ULL) << (ilog2(sector_size) - 9); ++ ++ if (sizeof(sector_t) == 4 && last_sector > U32_MAX) ++ return false; ++ ++ return true; ++} ++ + static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, + unsigned char *buffer) + { +@@ -2116,7 +2132,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, + return -ENODEV; + } + +- if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) { ++ if (!sd_addressable_capacity(lba, sector_size)) { + sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " + "kernel compiled with support for large block " + "devices.\n"); +@@ -2202,7 +2218,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, + return sector_size; + } + +- if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) { ++ if (!sd_addressable_capacity(lba, sector_size)) { + sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " + "kernel compiled with support for large block " + "devices.\n"); +@@ -2888,7 +2904,8 @@ static int sd_revalidate_disk(struct gendisk *disk) + q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks); + rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks); + } else +- rw_max = BLK_DEF_MAX_SECTORS; ++ rw_max = min_not_zero(logical_to_sectors(sdp, dev_max), ++ (sector_t)BLK_DEF_MAX_SECTORS); + + /* Combine with controller limits */ + q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q)); +diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c +index 64c867405ad4..804586aeaffe 100644 +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -834,6 +834,7 @@ static void get_capabilities(struct scsi_cd *cd) + unsigned char *buffer; + struct scsi_mode_data data; + struct scsi_sense_hdr sshdr; ++ unsigned int ms_len = 128; + int rc, n; + + static const char *loadmech[] = +@@ -860,10 +861,11 @@ static void get_capabilities(struct scsi_cd *cd) + scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); + + /* ask for mode page 0x2a */ +- rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, ++ rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len, + SR_TIMEOUT, 3, &data, NULL); + +- if (!scsi_status_is_good(rc)) { ++ if (!scsi_status_is_good(rc) || data.length > ms_len || ++ data.header_length + data.block_descriptor_length > data.length) { + /* failed, drive doesn't have capabilities mode page */ + cd->cdi.speed = 1; + cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | +diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c +index 2cbea2af7cd0..6d1b0acbc5b3 100644 +--- a/drivers/target/iscsi/iscsi_target_parameters.c ++++ b/drivers/target/iscsi/iscsi_target_parameters.c +@@ -781,22 +781,6 @@ static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param) + if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) + SET_PSTATE_REPLY_OPTIONAL(param); + /* +- * The GlobalSAN iSCSI Initiator for MacOSX does +- * not respond to MaxBurstLength, FirstBurstLength, +- * DefaultTime2Wait or DefaultTime2Retain parameter keys. +- * So, we set them to 'reply optional' here, and assume the +- * the defaults from iscsi_parameters.h if the initiator +- * is not RFC compliant and the keys are not negotiated. +- */ +- if (!strcmp(param->name, MAXBURSTLENGTH)) +- SET_PSTATE_REPLY_OPTIONAL(param); +- if (!strcmp(param->name, FIRSTBURSTLENGTH)) +- SET_PSTATE_REPLY_OPTIONAL(param); +- if (!strcmp(param->name, DEFAULTTIME2WAIT)) +- SET_PSTATE_REPLY_OPTIONAL(param); +- if (!strcmp(param->name, DEFAULTTIME2RETAIN)) +- SET_PSTATE_REPLY_OPTIONAL(param); +- /* + * Required for gPXE iSCSI boot client + */ + if (!strcmp(param->name, MAXCONNECTIONS)) +diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c +index 428b0d9e3dba..93590521ae33 100644 +--- a/drivers/target/iscsi/iscsi_target_util.c ++++ b/drivers/target/iscsi/iscsi_target_util.c +@@ -731,21 +731,23 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown) + { + struct se_cmd *se_cmd = NULL; + int rc; ++ bool op_scsi = false; + /* + * Determine if a struct se_cmd is associated with + * this struct iscsi_cmd. + */ + switch (cmd->iscsi_opcode) { + case ISCSI_OP_SCSI_CMD: +- se_cmd = &cmd->se_cmd; +- __iscsit_free_cmd(cmd, true, shutdown); ++ op_scsi = true; + /* + * Fallthrough + */ + case ISCSI_OP_SCSI_TMFUNC: +- rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown); +- if (!rc && shutdown && se_cmd && se_cmd->se_sess) { +- __iscsit_free_cmd(cmd, true, shutdown); ++ se_cmd = &cmd->se_cmd; ++ __iscsit_free_cmd(cmd, op_scsi, shutdown); ++ rc = transport_generic_free_cmd(se_cmd, shutdown); ++ if (!rc && shutdown && se_cmd->se_sess) { ++ __iscsit_free_cmd(cmd, op_scsi, shutdown); + target_put_sess_cmd(se_cmd); + } + break; +diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c +index a15070a7fcd6..53e4d5056db7 100644 +--- a/drivers/tty/serial/atmel_serial.c ++++ b/drivers/tty/serial/atmel_serial.c +@@ -810,6 +810,11 @@ static void atmel_complete_tx_dma(void *arg) + */ + if (!uart_circ_empty(xmit)) + tasklet_schedule(&atmel_port->tasklet); ++ else if ((port->rs485.flags & SER_RS485_ENABLED) && ++ !(port->rs485.flags & SER_RS485_RX_DURING_TX)) { ++ /* DMA done, stop TX, start RX for RS485 */ ++ atmel_start_rx(port); ++ } + + spin_unlock_irqrestore(&port->lock, flags); + } +@@ -912,12 +917,6 @@ static void atmel_tx_dma(struct uart_port *port) + desc->callback = atmel_complete_tx_dma; + desc->callback_param = atmel_port; + atmel_port->cookie_tx = dmaengine_submit(desc); +- +- } else { +- if (port->rs485.flags & SER_RS485_ENABLED) { +- /* DMA done, stop TX, start RX for RS485 */ +- atmel_start_rx(port); +- } + } + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) +diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c +index 0567d517eed3..ea2f19f5fbde 100644 +--- a/drivers/video/fbdev/xen-fbfront.c ++++ b/drivers/video/fbdev/xen-fbfront.c +@@ -644,7 +644,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev, + break; + + case XenbusStateInitWait: +-InitWait: + xenbus_switch_state(dev, XenbusStateConnected); + break; + +@@ -655,7 +654,8 @@ InitWait: + * get Connected twice here. + */ + if (dev->state != XenbusStateConnected) +- goto InitWait; /* no InitWait seen yet, fudge it */ ++ /* no InitWait seen yet, fudge it */ ++ xenbus_switch_state(dev, XenbusStateConnected); + + if (xenbus_scanf(XBT_NIL, info->xbdev->otherend, + "request-update", "%d", &val) < 0) +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index 72f270d4bd17..a0c0a49b6620 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -2545,7 +2545,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, + wdata->credits = credits; + + if (!wdata->cfile->invalidHandle || +- !cifs_reopen_file(wdata->cfile, false)) ++ !(rc = cifs_reopen_file(wdata->cfile, false))) + rc = server->ops->async_writev(wdata, + cifs_uncached_writedata_release); + if (rc) { +@@ -2958,7 +2958,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, + rdata->credits = credits; + + if (!rdata->cfile->invalidHandle || +- !cifs_reopen_file(rdata->cfile, true)) ++ !(rc = cifs_reopen_file(rdata->cfile, true))) + rc = server->ops->async_readv(rdata); + error: + if (rc) { +@@ -3544,7 +3544,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, + } + + if (!rdata->cfile->invalidHandle || +- !cifs_reopen_file(rdata->cfile, true)) ++ !(rc = cifs_reopen_file(rdata->cfile, true))) + rc = server->ops->async_readv(rdata); + if (rc) { + add_credits_and_wake_if(server, rdata->credits, 0); +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 7dcc97eadb12..817a937de733 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -71,10 +71,9 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw, + csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, + csum_size); + offset += csum_size; +- csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, +- EXT4_INODE_SIZE(inode->i_sb) - +- offset); + } ++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, ++ EXT4_INODE_SIZE(inode->i_sb) - offset); + } + + return csum; +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index d598b9c809c1..db1a1427c27a 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -803,7 +803,14 @@ static inline void clear_soft_dirty(struct vm_area_struct *vma, + static inline void clear_soft_dirty_pmd(struct vm_area_struct *vma, + unsigned long addr, pmd_t *pmdp) + { +- pmd_t pmd = pmdp_huge_get_and_clear(vma->vm_mm, addr, pmdp); ++ pmd_t pmd = *pmdp; ++ ++ /* See comment in change_huge_pmd() */ ++ pmdp_invalidate(vma, addr, pmdp); ++ if (pmd_dirty(*pmdp)) ++ pmd = pmd_mkdirty(pmd); ++ if (pmd_young(*pmdp)) ++ pmd = pmd_mkyoung(pmd); + + pmd = pmd_wrprotect(pmd); + pmd = pmd_clear_soft_dirty(pmd); +diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h +index 3b4af1d7c7e9..a25414ce2898 100644 +--- a/include/crypto/internal/hash.h ++++ b/include/crypto/internal/hash.h +@@ -173,6 +173,16 @@ static inline struct ahash_instance *ahash_alloc_instance( + return crypto_alloc_instance2(name, alg, ahash_instance_headroom()); + } + ++static inline void ahash_request_complete(struct ahash_request *req, int err) ++{ ++ req->base.complete(&req->base, err); ++} ++ ++static inline u32 ahash_request_flags(struct ahash_request *req) ++{ ++ return req->base.flags; ++} ++ + static inline struct crypto_ahash *crypto_spawn_ahash( + struct crypto_ahash_spawn *spawn) + { +diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h +index cb91b44f5f78..ad2bcf647b9a 100644 +--- a/include/linux/cgroup.h ++++ b/include/linux/cgroup.h +@@ -528,6 +528,25 @@ static inline void pr_cont_cgroup_path(struct cgroup *cgrp) + pr_cont_kernfs_path(cgrp->kn); + } + ++static inline void cgroup_init_kthreadd(void) ++{ ++ /* ++ * kthreadd is inherited by all kthreads, keep it in the root so ++ * that the new kthreads are guaranteed to stay in the root until ++ * initialization is finished. ++ */ ++ current->no_cgroup_migration = 1; ++} ++ ++static inline void cgroup_kthread_ready(void) ++{ ++ /* ++ * This kthread finished initialization. The creator should have ++ * set PF_NO_SETAFFINITY if this kthread should stay in the root. ++ */ ++ current->no_cgroup_migration = 0; ++} ++ + #else /* !CONFIG_CGROUPS */ + + struct cgroup_subsys_state; +@@ -551,6 +570,8 @@ static inline void cgroup_free(struct task_struct *p) {} + + static inline int cgroup_init_early(void) { return 0; } + static inline int cgroup_init(void) { return 0; } ++static inline void cgroup_init_kthreadd(void) {} ++static inline void cgroup_kthread_ready(void) {} + + #endif /* !CONFIG_CGROUPS */ + +diff --git a/include/linux/sched.h b/include/linux/sched.h +index ce0f61dcd887..352213b360d7 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1475,6 +1475,10 @@ struct task_struct { + #ifdef CONFIG_COMPAT_BRK + unsigned brk_randomized:1; + #endif ++#ifdef CONFIG_CGROUPS ++ /* disallow userland-initiated cgroup migration */ ++ unsigned no_cgroup_migration:1; ++#endif + + unsigned long atomic_flags; /* Flags needing atomic access. */ + +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index 127c63e02d52..4cb94b678e9f 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -2752,11 +2752,12 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, + tsk = tsk->group_leader; + + /* +- * Workqueue threads may acquire PF_NO_SETAFFINITY and become +- * trapped in a cpuset, or RT worker may be born in a cgroup +- * with no rt_runtime allocated. Just say no. ++ * kthreads may acquire PF_NO_SETAFFINITY during initialization. ++ * If userland migrates such a kthread to a non-root cgroup, it can ++ * become trapped in a cpuset, or RT kthread may be born in a ++ * cgroup with no rt_runtime allocated. Just say no. + */ +- if (tsk == kthreadd_task || (tsk->flags & PF_NO_SETAFFINITY)) { ++ if (tsk->no_cgroup_migration || (tsk->flags & PF_NO_SETAFFINITY)) { + ret = -EINVAL; + goto out_unlock_rcu; + } +diff --git a/kernel/kthread.c b/kernel/kthread.c +index 9ff173dca1ae..850b255649a2 100644 +--- a/kernel/kthread.c ++++ b/kernel/kthread.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + + static DEFINE_SPINLOCK(kthread_create_lock); +@@ -205,6 +206,7 @@ static int kthread(void *_create) + ret = -EINTR; + + if (!test_bit(KTHREAD_SHOULD_STOP, &self.flags)) { ++ cgroup_kthread_ready(); + __kthread_parkme(&self); + ret = threadfn(data); + } +@@ -510,6 +512,7 @@ int kthreadd(void *unused) + set_mems_allowed(node_states[N_MEMORY]); + + current->flags |= PF_NOFREEZE; ++ cgroup_init_kthreadd(); + + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 3f743b147247..34b2a0d5cf1a 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -3677,23 +3677,24 @@ static void __enable_ftrace_function_probe(struct ftrace_ops_hash *old_hash) + ftrace_probe_registered = 1; + } + +-static void __disable_ftrace_function_probe(void) ++static bool __disable_ftrace_function_probe(void) + { + int i; + + if (!ftrace_probe_registered) +- return; ++ return false; + + for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) { + struct hlist_head *hhd = &ftrace_func_hash[i]; + if (hhd->first) +- return; ++ return false; + } + + /* no more funcs left */ + ftrace_shutdown(&trace_probe_ops, 0); + + ftrace_probe_registered = 0; ++ return true; + } + + +@@ -3820,6 +3821,7 @@ static void + __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + void *data, int flags) + { ++ struct ftrace_ops_hash old_hash_ops; + struct ftrace_func_entry *rec_entry; + struct ftrace_func_probe *entry; + struct ftrace_func_probe *p; +@@ -3831,6 +3833,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + struct hlist_node *tmp; + char str[KSYM_SYMBOL_LEN]; + int i, ret; ++ bool disabled; + + if (glob && (strcmp(glob, "*") == 0 || !strlen(glob))) + func_g.search = NULL; +@@ -3849,6 +3852,10 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + + mutex_lock(&trace_probe_ops.func_hash->regex_lock); + ++ old_hash_ops.filter_hash = old_hash; ++ /* Probes only have filters */ ++ old_hash_ops.notrace_hash = NULL; ++ + hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); + if (!hash) + /* Hmm, should report this somehow */ +@@ -3886,12 +3893,17 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, + } + } + mutex_lock(&ftrace_lock); +- __disable_ftrace_function_probe(); ++ disabled = __disable_ftrace_function_probe(); + /* + * Remove after the disable is called. Otherwise, if the last + * probe is removed, a null hash means *all enabled*. + */ + ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); ++ ++ /* still need to update the function call sites */ ++ if (ftrace_enabled && !disabled) ++ ftrace_run_modify_code(&trace_probe_ops, FTRACE_UPDATE_CALLS, ++ &old_hash_ops); + synchronize_sched(); + if (!ret) + free_ftrace_hash_rcu(old_hash); +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 36bf4c3fe4f5..9f0aa255e288 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -2084,6 +2084,8 @@ static int ip6_route_del(struct fib6_config *cfg) + continue; + if (cfg->fc_metric && cfg->fc_metric != rt->rt6i_metric) + continue; ++ if (cfg->fc_protocol && cfg->fc_protocol != rt->rt6i_protocol) ++ continue; + dst_hold(&rt->dst); + read_unlock_bh(&table->tb6_lock); + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 138f2d667212..5758818435f3 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -4422,6 +4422,12 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) + if (!asoc) + return -EINVAL; + ++ /* If there is a thread waiting on more sndbuf space for ++ * sending on this asoc, it cannot be peeled. ++ */ ++ if (waitqueue_active(&asoc->wait)) ++ return -EBUSY; ++ + /* An association cannot be branched off from an already peeled-off + * socket, nor is this supported for tcp style sockets. + */ +@@ -6960,8 +6966,6 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, + */ + release_sock(sk); + current_timeo = schedule_timeout(current_timeo); +- if (sk != asoc->base.sk) +- goto do_error; + lock_sock(sk); + + *timeo_p = current_timeo; +diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c +index 06095cc8815e..1f0687d8e3d7 100644 +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -541,9 +541,13 @@ gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred) + return gss_new; + gss_msg = gss_add_msg(gss_new); + if (gss_msg == gss_new) { +- int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg); ++ int res; ++ atomic_inc(&gss_msg->count); ++ res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg); + if (res) { + gss_unhash_msg(gss_new); ++ atomic_dec(&gss_msg->count); ++ gss_release_msg(gss_new); + gss_msg = ERR_PTR(res); + } + } else +@@ -836,6 +840,7 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg) + warn_gssd(); + gss_release_msg(gss_msg); + } ++ gss_release_msg(gss_msg); + } + + static void gss_pipe_dentry_destroy(struct dentry *dir, diff --git a/patch/kernel/rockchip-default/rtl8723bs-v4.4.0.patch b/patch/kernel/rockchip-default/xrtl8723bs-v4.4.0.patch similarity index 100% rename from patch/kernel/rockchip-default/rtl8723bs-v4.4.0.patch rename to patch/kernel/rockchip-default/xrtl8723bs-v4.4.0.patch